i-net Clear Reports contains an extensive API for programming the report server. This guide will give you an overview about the possibilities. More complete information can be found in the documentation, e.g. the list of libraries and the API documentation. You can find the documentation in the SDK or on the i-net Clear Reports website.
Please find the examples of this guide as java classes and some more examples in the folder "/documentation/Samples" of the SDK.
This guide describes the usage of the i-net Clear Reports API. Therefore it is necessary that i-net Clear Reports is installed either as report server or it is embedded into your own application so that you can access the API.
Note that the main JAR file to link your source to is ClearReports.jar and inetcore.jar, found in the core subdirectory of your installation. But you need more jar files from the core directory if you want embedded it in your application. For details see at Libraries of i-net Clear Reports.
To help you understand where you can change what, we'll show you first the sequence of code points of a typical report request. Many of these methods (as for example the PropertyChecker methods) can be overloaded by your own classes - they are highlighted in yellow and explained further below.
Servlet filters are executed before all other classes. The servlet filters has an effect both on the rendering as well as on the remote access.
Any implementation of the class javax.servlet.Filter can be used as servlet filter. There are a lot of third party implementations available.
To add a servlet filter to i-net Clear Reports, you should write a plugin and register your filter in the ServerPluginManager. For a sample see the sample UrlCookiePlugin
.
Using a servlet filter it is possible to forward a successful log-in to a front-end server to i-net Clear Reports so that a temporary data source can be created for the logged in user (session scope datasource).
Using a servlet filter you have complete control over the input(javax.servlet.HttpServletRequest)
and output(javax.servlet.HttpServletResponse)
.
For some output formats like the Applet Viewer or HTML the server will send the rendering result in multiple steps. Therefore it is necessary to cache the results between different request. Also, with the cache it is possible to share the rendered results between multiple users. This optional feature can reduce the load on the server and it can be enabled/disabled using the Configuration property: Reload On New Request. With the Plus edition the intermediate data can be saved to hard disk. This make larger reports possible.
You can find the cache API in the API documentation.
The following samples shows a simple usage of the Cache API to export to PDF:
Cache cache = Cache.getCache(); Properties reportProperties = new Properties(); reportProperties.put("report", "c:/myreport.rpt" ); reportProperties.put("export_fmt", "pdf" ); ReportCacheKey key = cache.getKey(reportProperties); int pageCount = cache.getPageCountAndWait(key); for (int i = 1; i <= pageCount; i++) { byte[] page = cache.getPageAndWait(key, i); .... // write to the target }
Cache cache = Cache.getCache(); Properties reportProperties = new Properties(); reportProperties.put("report", "c:/myreport.rpt" ); reportProperties.put("export_fmt", "pdf" ); ReportCacheKey key = cache.getKey(reportProperties); return new ReportCacheInputStream( key, 600_000 );
More samples for the usage of the Cache API can be found in the Java code samples directory: "<SDK>/documentation/Samples/Reporting/API/cache".
If you use the Cache API directly you don't need to implement the caching yourself. You'll have full control over the connection between client and server.
You can:
You can not:
The Cache API has 2 static methods getEngineFactory and setEngineFactory. With these methods you can register your own global EngineFactory. You can find the EngineFactory API in the API documentation. It is recommended to extend com.inet.report.cache.EngineFactoryImpl instead of implementing an EngineFactory from scratch.
With the EngineFactory you can:
You can not:
Another option is to implement the PropertiesChecker interface.
You can find the PropertiesChecker API in the API documentation.
There are multiple solutions to set a custom PropertyChecker:
PropertyChecker
of the currently used configuration. This can occur via GUI or API.
With the PropertyChecker you can accomplish much the same as with an overridden ReportServlet, though ReportServlet has more interaction points.
You can:
You can not:
In the method checkProperties(Engine, Properties, Object)
of the PropertyChecker
you can register an EngineFinishListener to the current engine ( Engine.addFinishListener(EngineFinishListener)
).
In the method engineFinish(EngineFinishEvent event)
of this EngineFinishListener you can use the method Engine.getErrorMsg()
to get the error message, if an error has occurred. If no error has occurred, this method returns a Null.
In case of an error you can use this error message in your email. Of course you can do this also with the errorhandler plugin.
If you want to manually set the data for a report then you can do it with any of the Engine.setData() methods. An alternative method is to set a data factory.
An instance of the class com.inet.report.DataFactory is the factory for the report data. Most implementations of the DataFactory use JDBC but it is also possible to set the data without JDBC. The advantages of the DataFactory class is that it is easier to set the data for sub reports. This is the only solution for setting individual data for each sub report.
There are multiple possible solutions.
The most simple solution is to set the class name of the DataFactory class in the Data Source Configuration on which the report is based.
Note: A data source configuration with the same name can have different underlying data sources on the server machine and the machine running i-net Designer.
Possible problems with this approach could be that:
In these cases i-net Clear Reports does its best to locate the data source via fallback solutions.
Another solution is to set your DataFactory class via API. You need access to the Engine instance after loading. To get the Engine instance you need to use one of the other described programming techniques.
Engine engine = ... DatabaseTables dbt = engine.getDatabaseTables(); for(int i=0;i<dbt.getDatasourceCount();i++) { Datasource ds = dbt.getDatasource(i); ds.setDataFactory(myDataFactory); }
The same must be repeated for each sub-report.
If you want to use your own DataFactory class that can be used for report design in i-net Designer and report execution then you need to implement your own DataFactory class that extends from com.inet.report.database.BaseDataFactory (if non JDBC data are used) or com.inet.report.Database (if customization for a used JDBC driver is needed). More details about the methods that need to be implemented can be found in the API documentation.
For more details about the creation of DataFactory class please refer to the sample DatabaseClassUsableInDesigner
in the directory documentation/developer/samples/jdbc
of the i-net Clear Reports installation.
If you want to implement an application without web interface or your own client-server communication protocol (for example CORBA or SOAP), the recommended solution is to extend the class RenderData of the Java Viewer (client side) and the class EngineRenderData/CacheRenderData on the server side. The most important method of EngineRenderData is createEngine(Properties). This is the factory method for the Engine. You need to transfer all method calls from the RenderData on client and back. The EngineRenderData class does not use the cache. The Engine and the rendered data is hold in the memory. The i-net Designer uses this class to generate the data for its embedded report viewer.
You can:
You can not:
The CacheRenderData is an alternative implementation of the RenderData interface. The difference to the EngineRenderData is that it uses the cache. Therefore you can't create the Engine itself.
You can:
You can not:
The classes com.inet.report.RDC and com.inet.report.Engine are the starting points if you want to work with the low-level API directly. If you use the low-level API then you will have to do many things like caching and client server communication yourself.
You can:
You can not:
Twip (twentieth of a point) is a screen-independent unit to ensure that the proportion and position of screen elements are the same on all graphical display systems. A twip is equal to a 20th of a printer's point.
The number of twips per pixel depends on hardware and screen resolution (e.g. 800x600: approx. 15 twips per pixel).
Cache | EngineFactory | PropertyChecker | DataFactory | |
---|---|---|---|---|
All Viewer Features 1) | No | Yes | Yes | Yes |
Report Cache | Yes | Yes | Yes | Yes |
Full control over the Engine creation | limited 2) | Yes | No | No |
Modify report parameters | Yes | No | Yes | No |
Modify HTML page | Yes | No | Yes | No |
Full control over the client server communication | Yes | No | No | No |
Complexity (1 – simple, 5 - difficult) | 3 | 2 | 1 | 1 |
Modify the Engine after loading | limited 3) | Yes | Yes | No |
Set the report data | No | limited 4) | limited 5) | Yes |
EngineRenderData | CacheRenderData | RDC and Engine | |
---|---|---|---|
All Viewer Features 6) | Yes | Yes | No |
Report Cache | No | Yes | No |
Full control over the Engine creation | Yes | No | Yes |
Modify report parameters | Yes | Yes | Yes |
Modify HTML page | Yes | Yes | Yes |
Full control over the client server communication | Yes | Yes | Yes |
Complexity (1 – simple, 5 - difficult) | 4 | 4 | 5 |
Modify the Engine after loading | Yes | No | Yes |
Set the report data | limited 7) | No | limited 8) |
Our recommendation is to use the EngineFactory. If you only want to set the data then your own DataFactory class is the best solution.