The Oracle Report Bean

(Originally posted on the “old” Jason Bennett’s Developer Corner, Sunday, June 15, 2008)

The Oracle Report Bean is a cool little bit of code I developed this week that will let you to execute an Oracle Report from within your JEE or plain old Java application.  The bean allows you to configure all of the report execution parameters and contains methods to execute the report as a printed report or have the report streamed back to the client if the chosen format (PDF, RTF, HTML, XML, etc).  The code basically constructs the URL you need to access the Oracle Reports servlet (rwservlet). I’m actually using the Oracle Report Bean as the interface to Oracle Reports in my current ADF Faces project.

Hitting the highlights …

The bean provides a set of constants (static variables) that represent rwservlet keywords (commands).   The code uses two Hash Maps (HashMap classes) for storing parameters.  One Hash Map holds the reports servlet keywords and values, and the other holds input parameters and values for the actual report being executed.  The Hash Maps are hidden behind getter and setter methods.  When setting a reports servlet key word, the developer may either use one of the static keyword references provided by the bean, or simply add one of their choosing (it’s up to them to make sure it’s a legitimate keyword/parameter at that point).  Using the Hash Maps makes it easier to construct the URL later using a simple loop.

The bean provides two methods for executing the report. One method, executePrintedReport, passes the fully constructed URL to the reports servlet and returns the response (either HTML or XML) as a String.  A helper method, formatXMLResponse, is provided to format the response returned by the reports server in client friendly manner (NOTE: The developer needs to set the status format to XML to use this helper method). This method is specifically intended for use with reports bound for external destinations (printers, email, etc.).  The other method, executeBinaryReport, passes the fully constructed URL to the reports servlet and then returns a data stream (InputStream class).  This method is intended for use with reports whose content will be returned directly to the client (the destination for these reports should be set to CACHE).  Use the executeBinaryReport method when you need to return report results directly to the client (desformats PDF, RTF, HTML, XML).  The bean also provides a method that simply returns the URL for executing the report: getReportServerURL.

Sample Bean Usages …

The following code snippet demonstrates how to setup the bean to execute a printed report:

{

OracleReportBean testBean = new OracleReportBean(“appserver”,”7778″,null);

testBean.setReportServerParam(OracleReportBean.RS_PARAM_SERVER,”my_repserv”);

testBean.setKeyMap(“db_key”);

testBean.setReportServerParam(OracleReportBean.RS_PARAM_ENVID,”orcl”);

testBean.setReportServerParam(OracleReportBean.RS_PARAM_DESTYPE,

OracleReportBean.DESTYPE_PRINTER);

testBean.setReportServerParam(OracleReportBean.RS_PARAM_DESNAME,

“myPrinter-01″);

testBean.setReportServerParam(OracleReportBean.RS_PARAM_REPORT,

“MyReport.rdf”);

testBean.setReportServerParam(OracleReportBean.RS_PARAM_ORIENTATION,

OracleReportBean.ORIENTATION_PORTRAIT);

testBean.setReportServerParam(OracleReportBean.RS_PARAM_DESFORMAT,

OracleReportBean.DESFORMAT_HTML);

testBean.setReportParameter(“p_id”,”50″);

testBean.setReportParameter(“p_user”,”JASON BENNETT”);

System.out.println(testBean.formatXMLResponse(testBean.executePrintedReport()));

}

This code snippet demonstrates how to setup the bean to execute and retrieve a binary report (PDF, HTML, XML, RTF, …):

{

OracleReportBean testBean = new OracleReportBean(“appserver”,”7778″,null);

testBean.setReportServerParam(OracleReportBean.RS_PARAM_SERVER,”my_repserv”);

testBean.setKeyMap(“db_key”);

testBean.setReportServerParam(OracleReportBean.RS_PARAM_ENVID,”orcl”);

testBean.setReportServerParam(OracleReportBean.RS_PARAM_DESTYPE,

OracleReportBean.DESTYPE_CACHE);

testBean.setReportServerParam(OracleReportBean.RS_PARAM_REPORT,

“MyReport.rdf”);

testBean.setReportServerParam(OracleReportBean.RS_PARAM_ORIENTATION,

OracleReportBean.ORIENTATION_PORTRAIT);

testBean.setReportServerParam(OracleReportBean.RS_PARAM_DESFORMAT,

OracleReportBean.DESFORMAT_HTML);

testBean.setReportParameter(“p_id”,”50″);

testBean.setReportParameter(“p_user”,”JASON BENNETT”);

try{

BufferedReader br;

br = new BufferedReader(

new    InputStreamReader(testBean.executeBinaryReport()));

String inputString = null;

while((inputString = br.readLine()) != null){

System.out.println(inputString);

};

}catch(Exception e){

e.printStackTrace();

}

}

The Code …

Finally, here is the code for the Oracle Report Bean:

import java.io.BufferedReader;
import java.io.InputStream;

import java.net.URLConnection;
import java.net.URL;
import java.io.InputStreamReader;
import java.io.StringReader;

import java.util.HashMap;
import java.util.Iterator;

import oracle.xml.parser.v2.DOMParser;
import oracle.xml.parser.v2.XMLConstants;
import oracle.xml.parser.v2.XMLDocument;
import oracle.xml.parser.v2.XMLElement;
import org.w3c.dom.NodeList;
import org.xml.sax.InputSource;

/***
* This bean performs the following functions:
* Constructing the Report URL with various parameters passed in by client.
* Sending the report request.
* Execute printed report and retrieve return status in the indicated format.
* Execute a binary report (PDF, RTF, XML, with DESTYPE CACHE) and return the
* InputStream for processing.
*/
public class OracleReportBean {

/* Report Servlet Host Settings */
private String http_host = null;
private String http_port = null;

/* Default path as per generic Oracle Appserver install */
private String servlet_path = “/reports/rwservlet”;

/* Report Servlet URL params */
public static final String RS_PARAM_SERVER = “server”;
public static final String RS_PARAM_REPORT = “report”;
public static final String RS_PARAM_ENVID = “envid”;
public static final String RS_PARAM_DESTYPE = “destype”;
public static final String RS_PARAM_DESFORMAT = “desformat”;
public static final String RS_PARAM_STATUSFORMAT = “statusformat”;
public static final String RS_PARAM_DESNAME = “desname”;
public static final String RS_PARAM_PAGESTREAM = “pagestream”;
public static final String RS_PARAM_DELIMITER = “delimiter”;
public static final String RS_PARAM_ORIENTATION = “orientation”;
public static final String RS_PARAM_DISTRIBUTE = “distribute”;

private String value_keyMap = null;

/* Static values for destination formats */
public static final String DESFORMAT_PDF = “PDF”;
public static final String DESFORMAT_HTML = “HTML”;
public static final String DESFORMAT_POSTSCRIPT = “POSTSCRIPT”;
public static final String DESFORMAT_DELIMITED = “DELIMITED”;
public static final String DESFORMAT_XML = XML;
public static final String DESFORMAT_RTF = “RTF”;

/* Static values for destination types*/
public static final String DESTYPE_MAIL = “mail”;
public static final String DESTYPE_PRINTER = “printer”;
public static final String DESTYPE_FILE = “file”;
public static final String DESTYPE_LOCAL_FILE = “localFile”;
public static final String DESTYPE_CACHE = “cache”;

/* Static values for distribute */
public static final String DISTRIBUTE_YES = “YES”;
public static final String DISTRIBUTE_NO = “NO”;

/*Static values for status format */
public static final String STATUSFORMAT_XML = XML;
public static final String STATUSFORMAT_HTML = “HTML”;

/* Static values for report orientation */
public static final String ORIENTATION_PORTRAIT = “PORTRAIT”;
public static final String ORIENTATION_LANDSCAPE = “LANDSCAPE”;
public static final String ORIENTATION_DEFAULT = DEFAULT;

/* HashMap to hold individual report parameters*/
private HashMap reportParams = new HashMap();

/* HashMap to hold report server params */
private HashMap reportServerParams = new HashMap();

/* Report Servlet */
private StringBuffer reportURL = new StringBuffer();
private String XMLReturnStatus = null;

/***
* Constructor
*/
public OracleReportBean(String p_http_host,
String p_http_port,
String p_servlet_path)
{
http_host = p_http_host;
http_port = p_http_port;

/* If the servlet path is null, we assign the default path. */
if (p_servlet_path != null){
servlet_path = p_servlet_path;
}

/* Default the status format to XML */
setReportServerParam(RS_PARAM_STATUSFORMAT,STATUSFORMAT_XML);

}

/*****
* Private utility methods …
*
*/
private String buildKeyValueString(HashMap p_map){

String map_key = null;
String param_sep = “&”;
String param_equal = “=”;
StringBuffer keyValueBuffer = new StringBuffer();

if (!p_map.isEmpty()){

Iterator mapKeys = p_map.keySet().iterator();

while (mapKeys.hasNext()){
map_key = (String)mapKeys.next();
keyValueBuffer.append(map_key).append(param_equal).append(p_map.get(map_key));

if(mapKeys.hasNext()){
keyValueBuffer.append(param_sep);
}
}
}

return keyValueBuffer.toString();

}

/* Construct the URL for accessing the Oracle Reports Servlet */
private void constructURL(){

String param_sep = “&”;

/* Clearout current URL */
reportURL = new StringBuffer();

/* HOST Section */

reportURL.append(“http://”);

reportURL.append(http_host);

if (http_port != null){
reportURL.append(“:”).append(http_port);
}

/* Add “/” separator if necessary. */
if (servlet_path.indexOf(“/”) > 0){
reportURL.append(“/”);
}

reportURL.append(servlet_path);
reportURL.append(“?”);

if(value_keyMap != null){
reportURL.append(value_keyMap).append(param_sep);
}

/*Construct Report Server Parameter URL component*/
reportURL.append(buildKeyValueString(reportServerParams));

if(!reportServerParams.isEmpty()){
reportURL.append(param_sep);
}

/*Construct Report Parameters URL Component*/
reportURL.append(buildKeyValueString(reportParams));
}

/***
* Getters and Setters for the Reports Servlet
* URL parameter values.
*/

public void setReportServerParam(String p_param,
String p_value){
reportServerParams.put(p_param,p_value);
}

public String getReportServerParam(String p_param){
if(reportServerParams.containsKey(p_param)){
return (String)reportServerParams.get(p_param);
} else {
return null;
}
}

/* Set/Get the value of a Reports KeyMap file */
public void setKeyMap(String p_keyMap){
value_keyMap = p_keyMap;
}

public String getKeyMap(){
return value_keyMap;
}

/* Add/Update and retrieve individual report parameters */
public void setReportParameter(String paramName,
String paramValue){

reportParams.put(paramName,paramValue);
}

public String getReportParameter(String paramName){

if (reportParams.containsKey(paramName)){
return (String)reportParams.get(paramName);
} else {
return null;
}

}

/****
* Construct and return a URL that can be used to execute the report.
*/
public String getReportServerURL(){
constructURL();
return reportURL.toString();
}

/***
* Execute a report whose destination is a printer or other
* non-client destination. (i.e. the report is not coming back
* to the calling client in binary format …)
*/
public String executePrintedReport(){

String v_return_status = null;
StringBuffer serverResponse = new StringBuffer();

try{

BufferedReader br;

br = new BufferedReader(new InputStreamReader(executeBinaryReport()));

String inputString = null;
while((inputString = br.readLine()) != null){
serverResponse.append(inputString);
};

v_return_status = serverResponse.toString();

}catch(Exception e){
e.printStackTrace();
v_return_status = “Error printing report: “+e.getMessage();
}
return v_return_status;
}

/***
* This method is used to execute a binary report
* that is intended to be returned to the
* A binary report is a report that is returned as
* a physical file such as PDF, RTF, etc
* DESTYPE needs to be CACHE in order to get a return
* stream (file …).
*/
public InputStream executeBinaryReport() throws Exception{

URL url = new URL(getReportServerURL());
URLConnection urlc= url.openConnection();

return urlc.getInputStream();
}

/****
* This method takes the XML response generated by the Oracle Reports Server
* servlet and generates a more user friendly response message.
* NOTE: This only works for the XML statusformat type.
*/
public String formatXMLResponse(String p_response){

StringBuffer formattedResponse = new StringBuffer();

try{

DOMParser parser = new DOMParser();
parser.showWarnings(false);
parser.setValidationMode(XMLConstants.NONVALIDATING);
parser.parse(new InputSource(new StringReader(p_response)));

XMLDocument doc = parser.getDocument();

XMLElement elements = (XMLElement)doc.getDocumentElement();

NodeList nl = elements.getElementsByTagName(“error”);

if (nl.getLength() > 0){
String err_component = doc.selectSingleNode(“//error[1]/@component”).getNodeValue();
String err_code = doc.selectSingleNode(“//error[1]/@code”).getNodeValue();
String err_message = doc.selectSingleNode(“//error[1]/@message”).getNodeValue();

formattedResponse.append(“Oracle Reports job submit error; “).append(err_component);
formattedResponse.append(“-“).append(err_code).append(“: “).append(err_message);
}else{

String job_id = doc.selectSingleNode(“//job[1]/@id”).getNodeValue();
String job_status = doc.selectSingleNode(“//status[1]/text()”).getNodeValue();
String job_status_code = doc.selectSingleNode(“//status[1]/@code”).getNodeValue();

if ((job_id == null)||(job_status==null)||(job_status_code==null)){

formattedResponse.append(“Oracle Reports job submit problem; “).append(“Job Id=”).append(job_id);
formattedResponse.append(“, Code=”).append(job_status_code).append(“, Status=”).append(job_status);

}else{

formattedResponse.append(“Report submitted successfully!”);

}

}

}catch(Exception e){
e.printStackTrace();
String error = “Error processing Oracle Report Server response: “+e.getMessage();
System.err.println(error);
formattedResponse.append(error);
}

return formattedResponse.toString();

}
}

Comments are closed.