/* TODO Since this is the back-end (logic) part of the JasperEngine the direct use of HttpServletResponse,
* HttpServletRequest and ServletContext objects shuold be pushed back to JasperReportServlet that is
* the front-end (control) part of the engine */
File[] compiledSubreports = null;
SpagoBIAccessUtils util = new SpagoBIAccessUtils();
// identity string for object execution
UUIDGenerator uuidGen = UUIDGenerator.getInstance();
UUID uuid_local = uuidGen.generateTimeBasedUUID();
//String executionId = uuid_local.toString();
//executionId = executionId.replaceAll("-", "");
String flgTemplateStandard = "true";
//ContentServiceProxy contentProxy=new ContentServiceProxy(userId,session);
ContentServiceProxy contentProxy=new ContentServiceProxy(userUniqueIdentifier,session);
try {
String tmpDirectory = System.getProperty("java.io.tmpdir");
// all jar needed by JR to succesfully compile a report should be on this path
// (by default is WEB_INF/lib)
setJRClasspath(getJRLibDir(servletContext));
HashMap requestParameters = ParametersDecoder.getDecodedRequestParameters(servletRequest);
Content template=contentProxy.readTemplate( documentId,requestParameters);
if (template==null){
logger.error("The document haven't the template.documentId="+documentId+" userUniqueIdentifier="+userUniqueIdentifier);
return;
}
logger.debug("Read the template."+template.getFileName());
InputStream is = null;
BASE64Decoder bASE64Decoder = new BASE64Decoder();
byte[] templateContent = bASE64Decoder.decodeBuffer(template.getContent());
is = new java.io.ByteArrayInputStream(templateContent);
if (template.getFileName().indexOf(".zip") > -1) {
flgTemplateStandard = "false";
}
/* Dynamic template management: if the template is a zip file it is opened and every class are added to
* the classpath
*
*/
boolean propertiesLoaded=false;
if (flgTemplateStandard.equalsIgnoreCase("false")) {
logger.debug("The template is a .ZIP file");
File fileZip = new File(getJRTempDir(servletContext, prefixDirTemplate), JS_FILE_ZIP + JS_EXT_ZIP);
FileOutputStream foZip = new FileOutputStream(fileZip);
foZip.write(templateContent);
foZip.close();
util.unzip(fileZip, getJRTempDir(servletContext, prefixDirTemplate));
JarFile zipFile = new JarFile(fileZip);
Enumeration totalZipEntries = zipFile.entries();
File jarFile = null;
while (totalZipEntries.hasMoreElements()) {
ZipEntry entry = (ZipEntry) totalZipEntries.nextElement();
if (entry.getName().endsWith(".jar")) {
jarFile = new File(getJRTempDirName(servletContext, prefixDirTemplate)+ entry.getName());
// set classloader with jar
ClassLoader previous = Thread.currentThread().getContextClassLoader();
DynamicClassLoader dcl = new DynamicClassLoader(jarFile, previous);
Thread.currentThread().setContextClassLoader(dcl);
}
else if (entry.getName().endsWith(".jrxml")) {
// set InputStream with jrxml
File jrxmlFile = new File(getJRTempDirName(servletContext, prefixDirTemplate)+ entry.getName());
InputStream isJrxml = new FileInputStream(jrxmlFile);
byte[] templateJrxml = new byte[0];
templateJrxml = util.getByteArrayFromInputStream(isJrxml);
is = new java.io.ByteArrayInputStream(templateJrxml);
}
if (entry.getName().endsWith(".properties")) {
propertiesLoaded=true;
}
}
}
// Set the temporary location for the files generated on-the-fly by JR
// (by default is the current user tmp-dir)
setJRTempDir(tmpDirectory);
logger.debug("Compiling template file ...");
Monitor monitorCompileTemplate =MonitorFactory.start("JasperReportRunner.compileTemplate");
JasperReport report = JasperCompileManager.compileReport(is);
monitorCompileTemplate.stop();
logger.debug("Template file compiled succesfully");
parameters = adaptReportParams(parameters, report);
// Add locale
if(parameters.get("SBI_LANGUAGE")!=null && parameters.get("SBI_COUNTRY")!=null){
Locale locale=null;
String language=(String)parameters.get("SBI_LANGUAGE");
String country=(String)parameters.get("SBI_COUNTRY");
logger.debug("Internazionalization in "+language);
locale=new Locale(language,country,"");
parameters.put("REPORT_LOCALE", locale);
ResourceBundle rs=null;
if(propertiesLoaded==false){
//if properties file are not loaded by template load them from resources
SourceBean config=null;
if (getClass().getResource("/engine-config.xml")!=null){
InputSource source=new InputSource(getClass().getResourceAsStream("/engine-config.xml"));
config = SourceBean.fromXMLStream(source);
}
SourceBean sb = (SourceBean)config.getAttribute("RESOURCE_PATH_JNDI_NAME");
String path = (String) sb.getCharacters();
String resPath= SpagoBIUtilities.readJndiResource(path);
resPath+="/jasper_messages/";
ClassLoader previous = Thread.currentThread().getContextClassLoader();
ResourceClassLoader dcl = new ResourceClassLoader(resPath,previous);
//Thread.currentThread().setContextClassLoader(dcl);
try{
//rs=PropertyResourceBundle.getBundle("messages",locale, Thread.currentThread().getContextClassLoader());
rs=PropertyResourceBundle.getBundle("messages",locale, dcl);
}
catch (Exception e) {
logger.error("could not find properties message");
}
parameters.put("REPORT_RESOURCE_BUNDLE", rs);
}
}
Monitor monitorSubReport = MonitorFactory.start("JasperReportRunner.compileSubReport");
// compile subreports
//compiledSubreports = compileSubreports(parameters, getJRCompilationDir(servletContext, executionId),contentProxy, requestParameters);
compiledSubreports = compileSubreports(parameters, servletContext, contentProxy, requestParameters);
monitorSubReport.stop();
// set classloader
ClassLoader previous = Thread.currentThread().getContextClassLoader();
ClassLoader current = URLClassLoader.newInstance(new URL[]{getJRCompilationDir(servletContext, prefixDirTemplate).toURL()}, previous);
Thread.currentThread().setContextClassLoader(current);
// Create the virtualizer
if(isVirtualizationActive()) {
logger.debug("Virtualization of fill process is active");
//parameters.put(JRParameter.REPORT_VIRTUALIZER, getVirtualizer(tmpDirectory, servletContext));
parameters.put(JRParameter.REPORT_VIRTUALIZER, getSwapVirtualizer(tmpDirectory, servletContext));
//parameters.put(JRParameter.REPORT_VIRTUALIZER, getGzipVirtualizer());
}
logger.debug("Filling report ...");
Monitor monitorFillingReport =MonitorFactory.start("JasperReportRunner.FillingReport");
JasperPrint jasperPrint = JasperFillManager.fillReport(report, parameters, conn);
monitorFillingReport.stop();
logger.debug("Report filled succesfully");
logger.debug("Exporting report ...");
String outputType = (String) parameters.get("outputType");
if(outputType == null) {
logger.debug("Output type is not specified. Default type will be used");
outputType = "html";
//outputType = ExporterFactory.getDefaultType();
}
logger.debug("Output format is [" + outputType + "]");
Monitor monitorExportReport =MonitorFactory.start("JasperReportRunner.ExportReport");
JRExporter exporter = ExporterFactory.getExporter(outputType);
String mimeType = ExporterFactory.getMIMEType(outputType);
if(exporter != null) logger.debug("Configured exporter class [" + exporter.getClass().getName() + "]");
else logger.debug("Exporter class [null]");
logger.debug("Configured MIME type [" + mimeType + "]");
// for base types use default exporter, mimeType and parameters if these
// are not specified by configuration file
if (outputType.equalsIgnoreCase("csv")) {
if(mimeType == null) mimeType = "text/plain";
servletResponse.setContentType(mimeType);
if(exporter == null) exporter = new JRCsvExporter();
} else if (outputType.equalsIgnoreCase("html")) {
if(mimeType == null) mimeType = "text/html";
servletResponse.setContentType(mimeType);
if(exporter == null) exporter = new JRHtmlExporter();
exporter.setParameter(JRHtmlExporterParameter.IS_USING_IMAGES_TO_ALIGN, Boolean.FALSE);
exporter.setParameter(JRHtmlExporterParameter.BETWEEN_PAGES_HTML, "");
// define the map structure for report images
HashMap m_imagesMap = new HashMap();
String mapName = uuid_local.toString();
servletRequest.getSession().setAttribute(mapName, m_imagesMap);
exporter.setParameter(JRHtmlExporterParameter.IMAGES_MAP ,m_imagesMap);
//exporter.setParameter(JRHtmlExporterParameter.IMAGES_URI, "image.jsp?mapname="+mapName+"&image=");
exporter.setParameter(JRHtmlExporterParameter.IMAGES_URI, "JRImageServlet?mapname="+mapName+"&image=");
/* commented by Davide Zerbetto on 12/10/2009: there are problems with MIF (Ext ManagedIFrame library) library
// setting HTML header: this is necessary in order to inject the document.domain directive
String head = getHTMLHeader();
exporter.setParameter(JRHtmlExporterParameter.HTML_HEADER, head);
*/
} else if (outputType.equalsIgnoreCase("xls")) {
if(mimeType == null) mimeType = "application/vnd.ms-excel";
servletResponse.setContentType(mimeType);
//if(exporter == null) exporter = new JRXlsExporter();
if(exporter == null) exporter = new JExcelApiExporter();
} else if (outputType.equalsIgnoreCase("rtf")) {
if(mimeType == null) mimeType = "application/rtf";
servletResponse.setContentType(mimeType);
if(exporter == null) exporter = new JRRtfExporter();
} else if (outputType.equalsIgnoreCase("xml")) {
if(mimeType == null) mimeType = "text/xml";
servletResponse.setContentType(mimeType);
if(exporter == null) exporter = new JRXmlExporter();
} else if (outputType.equalsIgnoreCase("txt")) {
if(mimeType == null) mimeType = "text/plain";
servletResponse.setContentType(mimeType);
if(exporter == null) exporter = new JRTextExporter();
exporter.setParameter(JRTextExporterParameter.PAGE_HEIGHT,new Integer(100));
exporter.setParameter(JRTextExporterParameter.PAGE_WIDTH,new Integer(100));
} else if (outputType.equalsIgnoreCase("pdf")) {
if(mimeType == null) mimeType = "application/pdf";
servletResponse.setContentType(mimeType);
if(exporter == null) exporter = new JRPdfExporter();
} else if (outputType.equalsIgnoreCase("JPG")) {
byte[] bytes = getImageBytes(report, jasperPrint);
if(mimeType == null) mimeType = "application/jpeg";
out.write(bytes);
return;
} else if (outputType.equalsIgnoreCase("JPGBASE64")) {
byte[] bytes = getImagesBase64Bytes(report, jasperPrint);
if(mimeType == null) mimeType = "text/plain";
out.write(bytes);
return;
} else {
if(mimeType != null && exporter != null) servletResponse.setContentType(mimeType);
else {
logger.warn("Impossible to load exporter for type " + outputType);
logger.warn("Pdf exporter will be used");
servletResponse.setContentType("application/pdf");
exporter = new JRPdfExporter();
}
}
logger.debug("MIME type of response is [" + servletResponse.getContentType()+ "]");
logger.debug("Exporter class used is [" + exporter.getClass().getName()+ "]");
exporter.setParameter(JRExporterParameter.JASPER_PRINT, jasperPrint);
exporter.setParameter(JRExporterParameter.OUTPUT_STREAM, out);
exporter.exportReport();
monitorExportReport.stop();
logger.debug("Report exported succesfully");
} catch(Throwable e) {
logger.error("An exception has occured", e);
throw new Exception(e);
} finally {
// delete tmp dir for dynamic template management only if it's empty (without subreport files)
//File tmpDir = getJRTempDir(servletContext, executionId, prefixDirTemplate).getParentFile();
File tmpDir = getJRTempDir(servletContext, prefixDirTemplate);
String[] files = tmpDir.list();
if (files.length == 0){
util.deleteDirectory(tmpDir);
logger.debug("Delating temporary directory: " + tmpDir);
}
monitor.stop();
logger.debug("OUT");
}