Using the DocumentBundle Reader and Writer

Document Bundles

With version 0.8.10, the Pentaho Reporting Engine Classic uses and OpenDocumentFormat (ODF)
based report file format. Report definitions, datasources and images are stored in a single archive, which simplifies the report-deployment.

Loading Reports from a Document-Bundle

The reporting engine automatically detects whether a report is a plain XML file (Simple-XML or Extended-XML File-Format) or a report-bundle. For end-users and developers, there is no difference in handling such files.

JFreeReportBoot.getInstance().start();

File reportLocation = new File ("/home/user/report.prpt");

final ResourceManager resourceManager = new ResourceManager();
resourceManager.registerDefaults();
final Resource resource = resourceManager.createDirectly (reportLocation);
final JFreeReport report = (JFreeReport) resource.getResource();

Writing a report-definition

You can export a JFreeReport object and all data-sources and inline-images into a document-bundle by using the BundleWriter class.

 final JFreeReport report; // created elsewhere ..

 final MemoryDocumentBundle documentBundle = new MemoryDocumentBundle();
 final BundleWriter writer = new BundleWriter();
 writer.writeReport(documentBundle, report);
 BundleUtilities.writeAsZip(new File("/tmp/report3.prpt"), documentBundle);

Resource-Types

External resources in the Classic-Engine can be referenced in two different ways.

Linked Resources

A linked resource is referenced by an absolute URL from within the report definition. The report bundle does not contain the contents of the referenced resource. Everytime a report is processed, the resource will be loaded from the specified location.

As linked resources are not stored inside the report bundle, all reports will always use the same file. If the referenced resource is updated, all reports will instantly use the new version of the resource. However, if the resource is loaded or moved to a different location, the link between the report and the referenced resource will be broken and the report definition needs to be updated.

Linked resources pointing to the local file system will break as soon as the report is published to a remote server.

Embedded Resources

Embedded resources are copied into the report resource bundle and the reporting engine loads the resources from the bundle whenever the report is executed.

Updates to the original resource have no effect on the reports. Whenever the report-definition should use the updated resource, the report-bundle must be updated. Moving the report definition to a different machine also moves all the embedded resources.

A resource is considered embedded, if the fully resolved path points to a location inside the resource-bundle. This will only happen, if the report was loaded from a document bundle ("content-base" and "source" attribute contain a Document-Bundle-ResourceKey) and if the path in the content-element is a relative path and does not specify a external URL.

Any resource that does not fulfill the embedded-constraints is automatically treated as linked resource.

Design-Time Report-Bundle management

During a editor session, the design tool (for instance the Report-Designer) has to maintain a DocumentBundle that contains all embedded resources.

Loading a report into a editable document-bundle

 File reportDefinitionFile = new File ("/tmp/report.prpt");

// this resource manager only loads the bundle. The bundle itself will provide another
// resource manager that must be used to access content from inside the bundle.
 final ResourceManager resManager = new ResourceManager();
 resManager.registerDefaults();

// load the document bundle ..
 final Resource resource = resManager.createDirectly(reportDefinitionFile, DocumentBundle.class);
 final DocumentBundle bundle = (DocumentBundle) resource.getResource();

// and copy it into a editable bundle structure.
 final MemoryDocumentBundle editableBundle = new MemoryDocumentBundle();
 BundleUtilities.copyInto(editableBundle, bundle);

// finally load the report from the editable bundle.
 final ResourceManager bundleManager = editableBundle.getResourceManager();
 final ResourceKey key = editableBundle.createResourceKey("content.xml");
 final Resource reportResource = bundleManager.create(key, editableBundle.getBundleMainKey(), JFreeReport.class);
 final JFreeReport report = (JFreeReport) reportResource.getResource();

Adding embedded content

Copy the raw-data of the resource into the editable bundle.

 final File imageFile = new File ("/home/user/butterfly.wmf");
 final ResourceKey butterflyKey = bundleManager.createKey(imageUrl);
 BundleUtilities.copyInto(editableBundle, "/images/butterfly.wmf", butterflyKey, resourceManager);

Add a element that displays the content.

 final ReportHeader header = report.getReportHeader();
 ContentElementFactory cef = new ContentElementFactory();
 cef.setContent("/images/butterfly.wmf");
 cef.setMinimumWidth(new Float(200));
 cef.setMinimumHeight(new Float(200));
 header.addElement(cef.createElement());

Writing the report-bundle

Writing the document bundle uses the same step as above. Do not use the 'editableBundle' to write the report, as the BundleWriter will never overwrite existing content in a document-bundle. If you do not use a fresh bundle, the created document-bundle will contain garbage entries.

The BundleWriter will only copy embedded content that was defined in Element-Attributes and Expression-Properties that have the role "Content". If additional unreferenced content should be contained in the bundle, you have to copy these resources manually before writing the bundle as ZIP-File.