net.sf.jasperreports.engine

## Interface JRSubreport

- All Superinterfaces:
    java.lang.Cloneable, JRChild, JRCloneable, JRCommonElement, JRElement, JRIdentifiable, JRPropertiesHolder, JRStyleContainer, JRVisitable
  All Known Implementing Classes:
    FillTableSubreport, JRBaseSubreport, JRDesignSubreport, JRFillSubreport, TableSubreport

      public interface JRSubreport
      extends JRElement

  An abstract representation of a subreport.

  ### Subreport Overview

  Subreports are an important feature of a report-generating tool. They enable you to create more complex reports and simplify the design work. Subreports are very useful when creating master-detail reports or when the structure of a single report is not sufficient to describe the complexity of the desired output document. Subreport elements are introduced by the `<subreport>` tag in the JRXML file.

  A subreport is in fact a normal report that has been incorporated into another report. You can overlap subreports or make a subreport that contains other subreports, up to any level of nesting. Subreports are compiled and filled just like normal reports. Any report template can be used as a subreport when incorporated into another report template, without anything inside it having to change.

  Just like normal report templates, subreport templates are in fact `JasperReport` objects, which are obtained after compiling a `JasperDesign` object.

  Subreport elements have an expression that is evaluated at runtime to obtain the source of the `JasperReport` object to load. The so-called subreport expression is introduced by the `<subreportExpression>` tag (see `getExpression()`) and can return values from the following classes:
  - `java.lang.String` (default)
  - `java.io.File`
  - `java.io.InputStream`
  - `java.net.URL`
  - `net.sf.jasperreports.engine.JasperReport`

  Note: When the subreport expression returns a `java.lang.String` value, the engine tries to see whether the value represents a URL from which to load the subreport template object. If the value is not a valid URL representation, then the engine will try to locate a file on disk and load the subreport template from it, assuming that the value represents a file name. If no file is found, it will finally assume that the string value represents the location of a classpath resource and will try to load the subreport template from there. Only if all those fail will an exception be thrown.

  ### Caching Subreports

  A subreport element can load different subreport templates with every evaluation, giving users great flexibility in shaping their documents.

  However, most of the time, the subreport elements on a report are in fact static and their sources do not necessarily change with each new evaluation of the subreport expression. Usually, the subreport templates are loaded from fixed locations: files on disk or static URLs. If the same subreport template is filled multiple times on a report, there is no point in loading the subreport template object from the source file every time it is filled with data. To avoid this, one can instruct the reporting engine to cache the subreport template object. This way, one make sure that the subreport template is loaded from disk or from its particular location only once, after which it will be reused only when it must be filled.

  If the `isUsingCache` attribute (see `getUsingCache()` is set to true, the reporting engine will try to recognize previously loaded subreport template objects, using their specified source. For example, it will recognize a subreport object if its source is a file name that it has already loaded, or if it is the same URL.

  This caching functionality is available only for subreport elements that have expressions returning `java.lang.String` objects as the subreport template source, representing file names, URLs, or classpath resources. That's because the engine uses the subreport source string as the key to recognize that it is the same subreport template that it has cached.

  ### Subreport Parameters

  Since subreports are normal reports themselves, they are compiled and filled just like other reports. This means that they also require a data source from which to get the data when they are filled. They can also rely on parameters for additional information to use when being filled.

  There are two ways to supply parameter values to a subreport. You can supply a map containing the parameter values, as when filling a normal report with data, using one of the `fillReportXXX()` methods exposed by the `JasperFillManager` class. To do this, use the `<parametersMapExpression>` element (see `getParametersMapExpression()`), which introduces the expression that will be evaluated to obtain the specified parameters map. This expression should always return a `java.util.Map` object in which the keys are the parameter names.

  In addition to (or instead of) supplying the parameter values in a map, you can supply the parameter values individually, one by one, using a `<subreportParameter>` element (see `getParameters()`) for each relevant parameter. To do this, specify the name of the corresponding parameter using the mandatory `name` attribute and provide an expression that will be evaluated at runtime to obtain the value for that particular parameter, the value that will be supplied to the subreport-filling routines.

  Note that you can use both ways to provide subreport parameter values simultaneously. When this happens, the parameter values specified individually, using the `<subreportParameter>` element, override the parameter values present in the parameters map that correspond to the same subreport parameter. If the map does not contain corresponding parameter values already, the individually specified parameter values are added to the map.

  Caution: When you supply the subreport parameter values, be aware that the reporting engine will affect the `java.util.Map` object it receives, adding the built-in report parameter values that correspond to the subreport. This map is also affected by the individually specified subreport parameter values, as already explained.

  To avoid altering the original java.util.Map object that you send, wrap it in a different map before supplying it to the subreport-filling process, as follows:

  `new HashMap(myOriginalMap)`

  This way, the original map object remains unaffected and modifications are made to the wrapping map object. This is especially useful when you want to supply to the subreport the same set of parameters that the master report has received and you are using the built-in `REPORT_PARAMETERS_MAP` report parameter of the master report. However, you don't want to affect the value of this built-in parameter, so a clone of the original map needs to be used. Starting with JasperReports 3.0.1, `REPORT_PARAMETERS_MAP` is automatically cloned when it is used as subreport parameters map.

  ### Subreport Data Source

  Subreports require a data source in order to generate their content, just like normal reports.

  When filling a report, one must supply either a data source object or a connection object, depending on the report type.

  Subreports behave in the same way and expect to receive the same kind of input when they are being filled. One can supply to the subreport either a data source using the `<dataSourceExpression>` element (see `getDataSourceExpression()`) or a JDBC connection (see `getConnectionExpression()`) for the engine to execute the subreport's internal SQL query using the `<connectionExpression>` element. These two XML elements cannot both be present at the same time in a `<subreport>` element declaration. This is because you cannot supply both a data source and a connection for your subreport.

  The report engine expects that the data source expression will return a `JRDataSource` object or that the connection expression will return a `java.sql.Connnection` object - whichever is present.

  ### Returning Values from a Subreport

  Values calculated by a subreport can be returned to the parent report. More specifically, after a subreport is filled, values of the subreport variables can be either copied or accumulated (using an incrementer) to variables of the caller report.

  One or many `<returnValue>` elements (see `getReturnValues()`) can be used inside a `<subreport>` to specify values to be returned from the subreport.

  A subreport return value is represented by the `JRSubreportReturnValue` class that provides information about the subreport variable, master variable, calculation type and incrementer factory.

  Note that the value from the subreport is not returned on a column or page break, but only when the subreport filling is done. Also note that the calculation is a two-level process - that is, if the subreport computes a total average and the master accumulates values from the subreports using calculated averages, then the master result will be the average of the subreport averages, not the average of the combined subreport records.

  ### Subreport Runners

  By default, JasperReports uses multiple threads to render subreports. There is a separate thread for the master report and one thread for each subreport element found in the report template hierarchy. Each of these threads deals with the filling of its associated report template, which is either a master report or an embedded subreport. Even though multiple threads are involved when subreports are present, those threads do not actually run simultaneously; rather, they pass the control from one another at specific moments, usually when page breaks occur. At any one moment, there is only one report or subreport-filling thread in execution, the others being in wait state.

  Using multiple threads was the easiest way to add subreporting functionality in JasperReports. It allowed the reuse of the existing report-filling logic. However, while initially easy to implement, the solution proved to have some drawbacks due to the heavy use of threads. One of the most important limitations was that J2EE containers discourage any use of threads. Also, some operating systems manage threads poorly, which resulted in decreased performance and heavy memory usage.

  The alternate solution to this was found in a concept called Java continuations. From among several third-partly libraries implementing this concept that were available at the time, JasperReports proved to work well with Jakarta Commons Javaflow.

  In order to avoid breaking any existing functionality and also allow users to turn off multi-threading when working with subreports in JasperReports, the solution was to isolate subreport-filling logic into a separate abstract class called `JRSubreportRunnable`, which would have two interchangeable implementations:
  - `JRThreadSubreportRunner` - The initial thread-based implementation
  - `JRContinuationSubreportRunner` - A Javaflow-based implementation

  Switching between the preceding subreport runner implementation is not done through direct instantiation, but rather through a configuration property called `net.sf.jasperreports.subreport.runner.factory`. This configuration property should point to a `JRSubreportRunnerFactory` implementation able to produce the needed `JRSubreportRunnable` objects at runtime. That could be one of the following two:
  - `JRContinuationSubreportRunnerFactory`
  - `JRThreadSubreportRunnerFactory`

  The default value for the factory configuration property is `JRThreadSubreportRunnerFactory`, for backward-compatibility reasons.

  Note: A special JasperReports JAR file built using Javaflow byte code instrumentation is available for download with each JasperReports release and should be used when Java Continuations support during subreport filling is needed. In such cases, the Jakarta Commons Javaflow library is required; it can be found in the /lib directory of the JasperReports project distribution package.
  Version:
    $Id: JRSubreport.java 7070 2014-04-30 14:46:08Z lucianc $
  Author:
    Teodor Danciu (teodord@users.sourceforge.net)
  See Also:
    `JasperReport`, `JRSubreportReturnValue`, `JasperDesign`, `JRContinuationSubreportRunner`, `JRContinuationSubreportRunnerFactory`, `JRSubreportRunnable`, `JRSubreportRunnerFactory`, `JRThreadSubreportRunner`, `JRThreadSubreportRunnerFactory`

- - ### Method Summary

    Methods
    Modifier and Type | Method and Description
    --- | ---
    `JRExpression` | `getConnectionExpression()`
    `JRExpression` | `getDataSourceExpression()`
    `JRExpression` | `getExpression()`
    `OverflowType` | `getOverflowType()`
    `JRSubreportParameter[]` | `getParameters()`
    `JRExpression` | `getParametersMapExpression()`
    `JRSubreportReturnValue[]` | `getReturnValues()` Returns the list of subreport copied values.
    `java.lang.Boolean` | `getUsingCache()` Indicates if the engine is loading the current subreport from cache.
    `java.lang.Boolean` | `isOwnUsingCache()` Deprecated. Replaced by `getUsingCache()`.
    `java.lang.Boolean` | `isRunToBottom()` Specifies whether the subreport element will consume the entire vertical space available on the report page.
    `boolean` | `isUsingCache()` Deprecated. Replaced by `getUsingCache()`.
    `void` | `setOverflowType(OverflowType overflowType)`
    `void` | `setRunToBottom(java.lang.Boolean runToBottom)` Sets the flag that Specifies whether the subreport element will consume the entire vertical space available on the report page.
    `void` | `setUsingCache(java.lang.Boolean isUsingCache)` Specifies if the engine should be loading the current subreport from cache.

    - ### Methods inherited from interface net.sf.jasperreports.engine.JRElement

      `clone, collectExpressions, getElementGroup, getKey, getPositionTypeValue, getPrintWhenExpression, getPrintWhenGroupChanges, getPropertyExpressions, getStretchTypeValue, getX, getY, isPrintInFirstWholeBand, isPrintRepeatedValues, isPrintWhenDetailOverflows, isRemoveLineWhenBlank, setPositionType, setPrintInFirstWholeBand, setPrintRepeatedValues, setPrintWhenDetailOverflows, setRemoveLineWhenBlank, setStretchType, setWidth, setX`

    - ### Methods inherited from interface net.sf.jasperreports.engine.JRChild

      `clone`

    - ### Methods inherited from interface net.sf.jasperreports.engine.JRVisitable

      `visit`

    - ### Methods inherited from interface net.sf.jasperreports.engine.JRCloneable

      `clone`

    - ### Methods inherited from interface net.sf.jasperreports.engine.JRCommonElement

      `getBackcolor, getForecolor, getHeight, getModeValue, getOwnBackcolor, getOwnForecolor, getOwnModeValue, getWidth, setBackcolor, setForecolor, setMode`

    - ### Methods inherited from interface net.sf.jasperreports.engine.JRStyleContainer

      `getDefaultStyleProvider, getStyle, getStyleNameReference`

    - ### Methods inherited from interface net.sf.jasperreports.engine.JRPropertiesHolder

      `getParentProperties, getPropertiesMap, hasProperties`

    - ### Methods inherited from interface net.sf.jasperreports.engine.JRIdentifiable

      `getUUID`

- - ### Method Detail

    - #### isUsingCache

          boolean isUsingCache()

      Deprecated. Replaced by `getUsingCache()`.
      Indicates if the engine is loading the current subreport from cache. Implementations of this method rely on default values that depend on the type of the subreport expression if a value was not explicitly set of this flag.
      Returns:
        true if the subreport should be loaded from cache, false otherwise

    - #### getParametersMapExpression

          JRExpression getParametersMapExpression()

    - #### getParameters

          JRSubreportParameter[] getParameters()

    - #### getConnectionExpression

          JRExpression getConnectionExpression()

    - #### getDataSourceExpression

          JRExpression getDataSourceExpression()

    - #### getExpression

          JRExpression getExpression()

    - #### getReturnValues

          JRSubreportReturnValue[] getReturnValues()

      Returns the list of subreport copied values.
      Returns:
        the list of subreport copied values.

    - #### isOwnUsingCache

          java.lang.Boolean isOwnUsingCache()

      Deprecated. Replaced by `getUsingCache()`.
      Indicates if the engine is loading the current subreport from cache. Implementations of this method return the actual value for the internal flag that was explicitly set on this subreport.
      Returns:
        Boolean.TRUE if the subreport should be loaded from cache, Boolean.FALSE otherwise or null in case the flag was never explicitly set on this subreport element

    - #### getUsingCache

          java.lang.Boolean getUsingCache()

      Indicates if the engine is loading the current subreport from cache. Implementations of this method return the actual value for the internal flag that was explicitly set on this subreport.
      Returns:
        Boolean.TRUE if the subreport should be loaded from cache, Boolean.FALSE otherwise or null in case the flag was never explicitly set on this subreport element

    - #### setUsingCache

          void setUsingCache(java.lang.Boolean isUsingCache)

      Specifies if the engine should be loading the current subreport from cache. If set to Boolean.TRUE, the reporting engine will try to recognize previously loaded subreports using their specified source. For example, it will recognize an subreport if the subreport source is a file name that it has already loaded, or if it is the same URL.

      If set to null, the engine will rely on some default value which depends on the type of the subreport expression. The cache is turned on by default only for subreports that have `java.lang.String` objects in their expressions.

    - #### isRunToBottom

          java.lang.Boolean isRunToBottom()

      Specifies whether the subreport element will consume the entire vertical space available on the report page.
      Returns:
        whether the subreport element will consume the entire space down to the bottom of the page
      See Also:
        `setRunToBottom(Boolean)`

    - #### setRunToBottom

          void setRunToBottom(java.lang.Boolean runToBottom)

      Sets the flag that Specifies whether the subreport element will consume the entire vertical space available on the report page.

      This flag should be set to `true` if the subreport needs to always print its column and page footers at the bottom of the report page, even when the subreport data does not stretch to the bottom.

      Note that when `isFloatColumnFooter` is set for the subreport, the column footers will not be printed at the bottom of the page even if this flag is set.

      Parameters:
        `runToBottom` - whether the subreport element will consume the entire space down to the bottom of the page

    - #### getOverflowType

          OverflowType getOverflowType()

    - #### setOverflowType

          void setOverflowType(OverflowType overflowType)

© 2001-2010 Jaspersoft Corporation www.jaspersoft.com