<= Previous | Next => | Table of Contents DataVision User's Manual

4 Incorporating DataVision Into a Java Application

It isn't difficult to incorporate DataVision into a Java application. Instantiate a Report object and have it read the XML file and possibly a parameter value XML file, then give the report object a layout engine object (such as LaTeXLE).

To run a report from a JSP page, see Running DataVision from JSP below.

To run your application you will need to include in your classpath the five JAR files that are in the lib directory. They include

Here is the code you need to run a report from within your application. First, we will present some code chunks interspersed with insightful commentary. A few complete examples, showing different data sources and layout engines, will round out this section.

Creating a report object

First, create a report object.

Report report = new Report();

Specifying a database data source

What happens next depends upon the data source that the report XML file describes. If it's a database, we have to give some information (the database password) to the report before we read the XML file. If the data source is a text file, we need to specify some things after the XML file is read and the data source object is created.

The report's connection to a database can be specified one of three ways. You can supply a database password, a java.sql.Connection object, or a jimm.datavision.sql.Database object.

If you supply a password, the XML file's database connection information will be used to create a new connection. This is what normally happens when you open a report via the GUI, for example.

Both of the other methods (supplying a connection or database object) ignore the database connection information in the report XML file. If you supply a connection it will not be closed by the report, even if the report's database connection is reset by calling Database.reset. You will have to close the connection yourself after the report is done running.

The only reason you would supply a jimm.datavision.sql.Database object is to reuse one between different report instances. The advantage of reusing a database object is that the database metadata (table names, column names, and more) will only be read once no matter how many reports use it. Reading the metadata is time-consuming.

// Give the report enough information to connect to a database
// data source. Pick one of the following three lines.
report.setDatabasePassword("mypassword");
// or
report.setDatabaseConnection(aJdbcConnection);
// or
report.setDataSource(new Database(...));

Reading the report description XML file

Next, call Report.read (formerly called readFile) to read a report's description XML. This method can take as an argument a file name, a java.io.Reader, a java.io.InputStreamReader, or an org.xml.sax.InputSource. The InputSource constructor can take a java.io.InputStream, a java.io.Reader, or a String that specifies a system identifier. If the system identifier is a URI (a URL), it must be fully resolved.

// Read the report XML from a file or various stream types.
report.read(xmlFileNameOrStream); // Must be after database info

Specifying a text file data source

If the data source is a text file instead of a database, we need to tell the data source which file to read and optionally override the separator character specified in the XML file. If no character is defined in either the XML file or your code, the default character (comma) is used.

The method CharSepSource.setInput can take as an argument a file name, a java.io.Reader, or a java.io.InputStreamReader.

CharSepSource src = (CharSepSource)report.getDataSource();
src.setSepChar('\t'); // Optional; overrides default and XML file value
src.setInput(fileNameOrStream);

Reading parameter values

If necessary, read parameter values. The method Report.setParameterXMLInput (formerly called setParameterXMLFile) is used to read parameter values from XML. This method takes the same arguments as Report.read, described above.

// If necessary, read parameter values.
if (report.hasParameterFields())
    report.setParameterXMLInput(paramXMLFileNameOrStream);

Setting the layout engine

Next, give the report a layout engine. This example uses the LaTeX layout engine. You could use HTML, PDF, Swing, or any other one.

report.setLayoutEngine(new LaTeXLE(aWriter));

Running the report

Finally, run the report either in a separate thread or in the current thread. Report.run runs the report in a separate thread. It does not wait for the thread to finish. You will have to write the code to wait. If you call Report.runReport, the report is run synchronously; the method does not return until the report is done running.

// Pick one of the following two.
report.run();         // Run the report in a separate thread.
// or
report.runReport();   // Run the report in this thread.

Telling a Swing layout engine to exit

If you use a Swing layout engine, there is one more thing you may want to do: exit. When the user closes the Swing report window, the application does not automatically quit---the event loop keeps running.

The SwingLE layout engine has a method called close. It does not exit the application, but we can create an anonymous class that overrides that method and closes the application when the window is closed. Here's how:

LayoutEngine le = new SwingLE() {
    public void close() {
        super.close();
        System.exit();
    }
};
report.setLayoutEngine(le);

Similarly, when the last design window is closed DataVision normally exits. The method DesignWin.setExitWhenLastWinClosed does what it says: it lets you determine if DataVision should exit when the last design window is closed.

All together now

Here's the whole thing all together. This code will run a report that uses a database connection to read data, reads the report XML file, reads a parameter file if necessary, and outputs to a PDF file.

Report report = new Report();
report.setDatabasePassword("mypassword");
report.read("reportXmlFile");
if (report.hasParameterFields())
    report.setParameterXMLInput("paramXmlFile");
PrintWriter out = new PrintWriter(new FileWriter("output.pdf"));
report.setLayoutEngine(new PDFLE(out));
report.runReport();

4.1 Asking for Parameter Values

There are two ways a report gets parameter values: either by asking the user or by reading a parameter XML file. If you want the user to be prompted for input, you should not give the report a parameter file name. Instead, you should tell the system that you want to use a Swing window to prompt the user for parameter values by using the following code some time before running the report:

ErrorHandler.useGUI(true);

When a report runs, it asks itself, "Do I have any parameters that need values?" If the answer is yes, it then asks itself, "Am I using a GUI?" If the answer to that question is "yes", it opens a Swing window to ask the user for parameter values. If the answer is "no", it reads the parameter XML file you gave it on the command line or from your code (see the previous section's example code).

To specify a parameter file on the command line, use the -r command line option. See Running DataVision from the Command Line for details.

To specify a parameter's value within your code, you need to ask the report object to find it and then set its value. Note we are talking about setting individual parameter values manually instead of reading them from an XML file or input stream.

// Ask the report to find the parameter for you
Parameter p = report.findParameter(new Long(myParamID));
// or p = report.findParameterByName("My Parameter Name");

// Set the parameter's value. This sets a single value.
p.setValue(0, "The New Value");
// To set more values (if it is a range or a list of values), keep
// calling setValue().
// p.setValue(1, "Another Value");

Now, the tricky part: telling the report that it does not have to read a parameter XML file or ask the user for values. My untested suggestion: create a subclass of Report and override askForParameters. In that new method, set the parameter values and then tell the report that you are done.

protected void askForParameters() {
    // Ask the report to find the parameter for you
    Parameter p = findParameter(new Long(myParamID));

    // Set the parameter's value. This sets a single value.
    p.setValue(0, "The New Value");

    // The next two lines are necessary.
    askedForParameters = true;
    parametersHaveValues = true;
}

4.2 Running DataVision from JSP

You can run a report in a JSP page, but you can't display its output directly, even if you use the HTML layout engine. You need to save the output to a (possibly temporary) file and then display the contents of that file or let the user download it.

For an example JSP page, see datavision.jsp in the examples directory. The comment at the top of that file contains directions for installing and running it from Tomcat.

4.3 Running DataVision as an Applet

DataVision can be run as an applet. The file applet.html contains an example "applet" tag suitable for use with DataVision.

The applet code is still under development; expect some problems.

In the example file applet.html, the "archive" attribute does not contain a database JAR file or jcalendar.jar. To run reports instead of just design them, you would have to add your JDBC JAR file and jcalendar.jar to this list. Why aren't those files in the list already? Because the applet code is being developed first to allow report design. Running reports should work; I just haven't tested it yet.

Since JRuby uses a custom class loader, you will have to either sign the applet or edit the client's java.policy file and add the line

permission java.lang.RuntimePermission "getClassLoader";

Many thanks to Edwin Ramirez, who has funded development of DataVision in order to create the applet code. All of his suggestions and feature requests have been folded into DataVision.


<= Previous | Next => | Table of Contents   DataVision User's Manual