Java tutorial
/* * The contents of this file are subject to the Mozilla Public License * Version 1.1 (the "License"); you may not use this file except in * compliance with the License. You may obtain a copy of the License at * http://www.mozilla.org/MPL/ * * Software distributed under the License is distributed on an "AS IS" * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See the * License for the specific language governing rights and limitations * under the License. * * The Original Code is Ziptie Client Framework. * * The Initial Developer of the Original Code is AlterPoint. * Portions created by AlterPoint are Copyright (C) 2006, * AlterPoint, Inc. All Rights Reserved. * * Contributor(s): */ package org.xerela.server.birt; import java.io.File; import java.io.FileFilter; import java.io.IOException; import java.util.HashMap; import java.util.LinkedHashMap; import java.util.Map; import org.apache.log4j.Logger; import org.eclipse.birt.report.engine.api.EngineConstants; import org.eclipse.birt.report.engine.api.EngineException; import org.eclipse.birt.report.engine.api.HTMLCompleteImageHandler; import org.eclipse.birt.report.engine.api.HTMLRenderContext; import org.eclipse.birt.report.engine.api.HTMLRenderOption; import org.eclipse.birt.report.engine.api.IImage; import org.eclipse.birt.report.engine.api.IPDFRenderOption; import org.eclipse.birt.report.engine.api.IRenderOption; import org.eclipse.birt.report.engine.api.IRenderTask; import org.eclipse.birt.report.engine.api.IReportDocument; import org.eclipse.birt.report.engine.api.IReportEngine; import org.eclipse.birt.report.engine.api.PDFRenderOption; import org.eclipse.birt.report.engine.api.RenderOption; import org.hibernate.Criteria; import org.hibernate.classic.Session; import org.hibernate.criterion.Restrictions; import org.xerela.provider.tools.PluginExecRecord; import org.xerela.server.birt.internal.BirtActivator; import org.xerela.zap.jta.TransactionElf; /** * RenderElf * * This class provides a method to render a BIRT intermediate format file into * a final output format. It contains a simple cache of final report temporary * files so that the most recently requested files are kept in the cache to * allow serving to the client without re-processing. */ @SuppressWarnings("deprecation") public final class RenderElf { private static final Logger LOGGER = Logger.getLogger(RenderElf.class); private static OutputRenderMap<String, File> outputRenderMap; private static Map<String, String> formatMimeMap; static { outputRenderMap = new OutputRenderMap<String, File>(); formatMimeMap = new HashMap<String, String>(); formatMimeMap.put("pdf", "application/pdf"); //$NON-NLS-1$ //$NON-NLS-2$ formatMimeMap.put("html", "text/html"); //$NON-NLS-1$ //$NON-NLS-2$ formatMimeMap.put("xls", "application/vnd.ms-excel"); //$NON-NLS-1$//$NON-NLS-2$ } private RenderElf() { // private constructor } /** * Get the cached version of a report. Returns <code>null</code> if the * report is not cached. * * @param execId the GUID of the report * @param format the desired format of the report * @return a <code>File</code> pointing to the report, or null if not in * cache */ public static File getCachedReport(int execId, String format) { File file = outputRenderMap.get(execId + format); return (file != null && file.exists() ? file : null); } /** * Render the BIRT intermediate file into the requested output format. * * @param rptDocFile a file containing BIRT intermediate output format * @param format the format specifier ("pdf", "html", "xls", etc.) * @return the file containing the final rendered output * @throws EngineException * @throws IOException */ @SuppressWarnings("unchecked") public static File render(File rptDocFile, int execId, String format) throws EngineException, IOException { File outFile = outputRenderMap.get(execId + format); if (outFile != null && outFile.exists()) { return outFile; } boolean owner = TransactionElf.beginOrJoinTransaction(); try { Session session = BirtActivator.getSessionFactory().getCurrentSession(); Criteria criteria = session.createCriteria(PluginExecRecord.class); criteria.add(Restrictions.sqlRestriction("execution_id = " + execId)); //$NON-NLS-1$ PluginExecRecord pluginExec = (PluginExecRecord) criteria.uniqueResult(); outFile = File.createTempFile("birt", "." + format); //$NON-NLS-1$ //$NON-NLS-2$ outFile.deleteOnExit(); IReportEngine reportEngine = BirtActivator.getReportPluginManager() .getReportEngine(pluginExec.getPluginName()); try { IReportDocument reportDoc = reportEngine.openReportDocument(rptDocFile.getAbsolutePath()); IRenderTask renderTask = reportEngine.createRenderTask(reportDoc); IRenderOption options = new RenderOption(); options.setOutputFileName(outFile.getAbsolutePath()); if ("pdf".equalsIgnoreCase(format)) //$NON-NLS-1$ { reportEngine.getConfig().getAppContext().put(EngineConstants.APPCONTEXT_CHART_RESOLUTION, Integer.valueOf(600)); options.setOutputFormat(IRenderOption.OUTPUT_FORMAT_PDF); PDFRenderOption pdfOptions = new PDFRenderOption(options); pdfOptions.setOption(IPDFRenderOption.FIT_TO_PAGE, new Boolean(true)); pdfOptions.setOption(IPDFRenderOption.PAGEBREAK_PAGINATION_ONLY, new Boolean(false)); renderTask.setRenderOption(pdfOptions); } else if ("html".equalsIgnoreCase(format)) //$NON-NLS-1$ { options.setOutputFormat(IRenderOption.OUTPUT_FORMAT_HTML); HTMLRenderOption htmlOptions = new HTMLRenderOption(options); htmlOptions.setSupportedImageFormats("PNG"); //$NON-NLS-1$ htmlOptions.setBaseImageURL(String.format("pluginDetail?executionId=%d&image=", execId)); //$NON-NLS-1$ htmlOptions.setImageHandler(new HTMLImageHandler(outFile.getName().replace("." + format, ""))); //$NON-NLS-1$ //$NON-NLS-2$ renderTask.setRenderOption(htmlOptions); } renderTask.render(); renderTask.close(); if (!outFile.exists() || outFile.length() == 0) { LOGGER.error("Zero length report output file."); //$NON-NLS-1$ } outputRenderMap.put(execId + format, outFile); } finally { reportEngine.destroy(); } } finally { if (owner) { TransactionElf.commit(); } } return outFile; } /** * Get the MIME type for files with the specified extension. * * @param extension the file extension * @return the MIME type for the extension or <code>null</code> */ public static String getMimeType(String extension) { return formatMimeMap.get(extension); } private static class HTMLImageHandler extends HTMLCompleteImageHandler { private String reportPrefix; public HTMLImageHandler(String prefix) { super(); this.reportPrefix = prefix; } @Override protected File createUniqueFile(String imageDir, String prefix, String postfix) { File file = super.createUniqueFile(imageDir, reportPrefix + prefix, postfix); file.deleteOnExit(); return file; } @Override protected String handleImage(IImage image, Object context, String prefix, boolean needMap) { String url = super.handleImage(image, context, prefix, false).replace("./", ""); //$NON-NLS-1$ //$NON-NLS-2$ HTMLRenderContext ctx = (HTMLRenderContext) context; return ctx.getBaseImageURL() + url; } } /** * Simple eviction cache. Retains twenty instances and then starts evicting eldest. * */ private static class OutputRenderMap<K, V> extends LinkedHashMap<K, V> { private static final long serialVersionUID = -5407155526999157659L; private final Integer RETENSION_COUNT = Integer.getInteger("org.xerela.report.cachesize", 20); //$NON-NLS-1$ @Override protected boolean removeEldestEntry(java.util.Map.Entry<K, V> eldest) { boolean remove = this.size() > RETENSION_COUNT; if (remove) { remove(eldest.getKey()); } return remove; } @Override public V remove(Object key) { V remove = super.remove(key); File file = (File) remove; file.delete(); final String pathStub = file.getName().replaceFirst("\\.[a-z]+$", ""); //$NON-NLS-1$ //$NON-NLS-2$ File parentDir = new File(file.getParent()); File[] listFiles = parentDir.listFiles(new FileFilter() { public boolean accept(File pathname) { return pathname.getName().startsWith(pathStub); } }); for (File die : listFiles) { die.delete(); } return remove; } } }