Sunday, January 28, 2007

An ADF Faces and XML Publisher Success Story

Deciding on an output mechanism for the application
After months of developing an application using ADF Faces and ADF Business components it came time to solve the last of my integration and design issues: Integrating a reporting/output mechanism. Early in the project I considered the option of using Oracle Reports or doing (redoing) printable versions of the entire entry form. With over 40 sections to the online application form, neither of these options seemed desirable or suitable.

At a recent conference XML Publisher generated quite a lot of interest so I thought I would download it and see what the hype was about. It didn't take long to work out that XML Publisher was going to be the tool of choice for my application. The original Word documents that the application was built from could be used with the data plugged straight in to where it needed to go. One of the big gains was not having to worry about formatting, this alone saved a huge amount of time.

Integrating XML Publisher with JDeveloper
Deepak Vohra has produced an article on OTN called Integrating Oracle XML Publisher with Oracle JDeveloper 10g which provided examples of using the XML Publisher API's in a simple Java Class. To start of with I created a small Java project based on one class which I executed from its Main method. This allowed me to get all the class paths and libraries sorted out and have me a good understanding of the XML Publisher Java API's. I was able to produce and merge PDF documents including page numbering in a very short space of time. I had to set enough memory for the XMP Publisher API's to overcome an out of memory error (Add "-Xmx256m"to your project run properties). The next step was to integrate this into a sandbox J2EE project and start writing to the browser response stream rather than disk. This presented a few challenges immediately, mostly around the location of the Data Template and XSL files which defined the output to be produced. In fact any interaction with the file system would prove to be a problem due to the relative execution changing to the location of the OC4J and not the class that is running. The other key problems were getting a pooled connection to the database and coding any file system operations to run in the embedded OC4J (XP) and target 10.1.3 middle tier (Linux).

Key design problems and their solutions
Getting a pooled connection for use by XML Publisher was solved by exposing a client method from the Application Module which returned a database connection from the connection pool. Getting the connection is described here in Steve Muench's blog.

The next design problem was where to actually call the XML Publisher API's to do all of the processing. The answer in short was a Managed Bean. The bean references the binding layer to get its parameters and is called by a JSP, which sets the response stream for the XML Publisher PDFDocMerger to write its PDF output to.

As for the interaction with the file system, I used a system properties table within the database which contained the various directories for the XML Data Templates and XSL style sheets for the output. I coded an AM method which used System.getProperties().getProperty("os.name"); to work out what OS the OC4J was running under and get the property for that Operating System eg. xmlp.windows.template.dir would get the full path on Windows for the XML Publisher template directory. (not quite write once - run anywhere, but close enough)

Summary
XML Publisher has been a huge win for this particular project and has successfully plugged a huge gap in the output mechanism for the application. The API's are comprehensive and every time looked to see if it could do something, the answer seemed to be yes and more! XML Publisher will definately be my preferred reporting tool for future ADF based projects.

5 comments:

Anonymous said...

Hi Brenden
Glad you got to grips with the APIs so quickly and found BIP so useful.
Cheers, Tim

Natasha & Anugrah said...

Hi Brenden
We are also working on a similar requirement. Working on Deepak Vohra's example, i could get to create the reports using the main method of the java API calling class. But am unable to map the locations of the xsl files and xml data files to pass them to the API when using ADF. Please help us here.

Brenden Anstey said...

Hi Natasha & Anugrah,
In the particular project that inspired this blog entry I put them in a location on the file system eg. /oracle/dev/project/xmlp and stored this location in a properties table in the database.
I had no success including the files in my deployment file resources and always got a file not found error. Two approaches I would consider next time would be to:
1. Store the documents in a CLOB in the database and simply use ADF BC read the documents into a stream.
2. Deploy the XML files with the application in the web content and use java.net.URL to read the documents into a stream.
I would favour option 1 because you could easily develop a few screens to maintain the XML documents without needing to redeploy the application.
regards,
Brenden

Anonymous said...

Hmm. what is the licensing like for xmlpublisher? I took a look at BI publisher and we were looking at .5 mil to do it. Is xmlpublisher a separate product that comes with Soa?

Brenden Anstey said...

Hi John,
sounds like you've been given wrong info from sales (unless you are doing a full implementation including Hyperion). What you are after is a BIP licence included with the App Server (50k per CPU) or you can go for user licence which is $30 per user with a minimum of 1000 users (30k). Alternatively you can apply to sales for a discount for using/packaging the API's standalone. I know of one case where a customer was successful in doing so. The argument is that the licensing structure doesn’t make sense when you compare what the API’s provide compared to the BI Server.
good luck,
Brenden