/* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (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.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package ro.nextreports.server.report.jasper; import java.io.File; import java.io.Serializable; import java.sql.Connection; import java.util.ArrayList; import java.util.HashMap; import java.util.List; import java.util.Map; import java.util.LinkedHashMap; import net.sf.jasperreports.engine.JasperPrint; import net.sf.jasperreports.engine.JasperReport; import net.sf.jasperreports.engine.JRException; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.jcrom.JcrFile; import ro.nextreports.server.domain.JasperContent; import ro.nextreports.server.domain.Report; import ro.nextreports.server.domain.Settings; import ro.nextreports.server.exception.FormatNotSupportedException; import ro.nextreports.server.exception.ReportEngineException; import ro.nextreports.server.report.ExportContext; import ro.nextreports.server.report.ExternalParameter; import ro.nextreports.server.report.ReportEngineAdapter; import ro.nextreports.server.report.jasper.util.JasperUtil; import ro.nextreports.server.report.util.ReportUtil; import ro.nextreports.server.service.StorageService; import ro.nextreports.server.util.ConnectionUtil; import ro.nextreports.server.util.ReplacedString; import ro.nextreports.server.util.StringUtil; import ro.nextreports.engine.queryexec.IdName; /** * Created by IntelliJ IDEA. * User: mihai.panaitescu * Date: Feb 14, 2008 * Time: 11:05:51 AM */ public class JasperEngine extends ReportEngineAdapter { private static final Logger LOG = LoggerFactory.getLogger(JasperEngine.class); private StorageService storageService; @Override public boolean supportPdfOutput() { return true; } @Override public boolean supportExcelOutput() { return true; } @Override public boolean supportHtmlOutput() { return true; } @Override public boolean supportCsvOutput() { return true; } @Override public boolean supportTxtOutput() { return true; } @Override public boolean supportRtfOutput() { return true; } @Override public boolean supportXmlOutput() { return true; } private JasperReport getJasperReport(ExportContext exportContext) throws Exception { JasperContent reportContent = (JasperContent) exportContext.getReportContent(); String name = reportContent.getMaster().getName(); Settings settings = storageService.getSettings(); name = settings.getJasper().getHome() + ReportUtil.FILE_SEPARATOR + JasperUtil.getUnique(name, exportContext.getId()) + "." + JasperUtil.JASPER_COMPILED_EXT; File jasperFile = new File(name); if (!jasperFile.exists()) { JasperReportsUtil.compileReport(storageService, reportContent, exportContext.getId()); } if (LOG.isDebugEnabled()) { LOG.debug("jasperFile = " + jasperFile); } JasperReportsUtil.copyImages(settings.getJasper().getHome(), reportContent.getImageFiles()); return JasperReportsUtil.getJasper(name); } @Override public byte[] exportReportToPdf(ExportContext exportContext) throws FormatNotSupportedException, ReportEngineException, InterruptedException { Connection conn = null; try { conn = ConnectionUtil.createConnection(storageService, exportContext.getReportDataSource()); JasperReport jr = getJasperReport(exportContext); if (LOG.isDebugEnabled()) { LOG.debug("parameterValues = " + exportContext.getReportParameterValues()); } JasperPrint jp = JasperReportsUtil.fillReport(storageService, exportContext.getKey(), jr, exportContext.getReportParameterValues(), conn); return JasperReportsUtil.getPdf(jp); } catch (InterruptedException e) { throw e; } catch (Exception e) { LOG.error(e.getMessage(), e); throw new ReportEngineException(e); } finally { ConnectionUtil.closeConnection(conn); } } @Override public byte[] exportReportToRtf(ExportContext exportContext) throws FormatNotSupportedException, ReportEngineException, InterruptedException { Connection conn = null; try { conn = ConnectionUtil.createConnection(storageService, exportContext.getReportDataSource()); JasperReport jr = getJasperReport(exportContext); JasperPrint jp = JasperReportsUtil.fillReport(storageService, exportContext.getKey(), jr, exportContext.getReportParameterValues(), conn); return JasperReportsUtil.getRtf(jp); } catch (InterruptedException e) { throw e; } catch (Exception e) { LOG.error(e.getMessage(), e); throw new ReportEngineException(e); } finally { ConnectionUtil.closeConnection(conn); } } @Override public byte[] exportReportToExcel(ExportContext exportContext) throws FormatNotSupportedException, ReportEngineException, InterruptedException { Connection conn = null; try { conn = ConnectionUtil.createConnection(storageService, exportContext.getReportDataSource()); JasperReport jr = getJasperReport(exportContext); JasperPrint jp = JasperReportsUtil.fillReport(storageService, exportContext.getKey(), jr, exportContext.getReportParameterValues(), conn); Map<String, Boolean> xlsParameters = new HashMap<String, Boolean>(); Settings settings = storageService.getSettings(); System.out.println(settings.getJasper()); xlsParameters.put(JasperUtil.IS_DETECT_CELL_TYPE, settings.getJasper().isDetectCellType()); xlsParameters.put(JasperUtil.IS_REMOVE_EMPTY_SPACE_BETWEEN_ROWS, settings.getJasper().isRemoveEmptySpaceBetweenRows()); xlsParameters.put(JasperUtil.IS_WHITE_PAGE_BACKGROUND, settings.getJasper().isWhitePageBackground()); return JasperReportsUtil.getExcel(jp, xlsParameters); } catch (InterruptedException e) { throw e; } catch (Exception e) { LOG.error(e.getMessage(), e); throw new ReportEngineException(e); } finally { ConnectionUtil.closeConnection(conn); } } @Override public byte[] exportReportToHtml(ExportContext exportContext) throws FormatNotSupportedException, ReportEngineException, InterruptedException { Connection conn = null; try { conn = ConnectionUtil.createConnection(storageService, exportContext.getReportDataSource()); JasperReport jr = getJasperReport(exportContext); JasperPrint jp = JasperReportsUtil.fillReport(storageService, exportContext.getKey(), jr, exportContext.getReportParameterValues(), conn); return JasperReportsUtil.getHTML(storageService, jp); } catch (InterruptedException e) { throw e; } catch (Exception e) { LOG.error(e.getMessage(), e); throw new ReportEngineException(e); } finally { ConnectionUtil.closeConnection(conn); } } @Override public byte[] exportReportToCsv(ExportContext exportContext) throws FormatNotSupportedException, ReportEngineException, InterruptedException { Connection conn = null; try { conn = ConnectionUtil.createConnection(storageService, exportContext.getReportDataSource()); JasperReport jr = getJasperReport(exportContext); JasperPrint jp = JasperReportsUtil.fillReport(storageService, exportContext.getKey(), jr, exportContext.getReportParameterValues(), conn); return JasperReportsUtil.getCSV(jp); } catch (InterruptedException e) { throw e; } catch (Exception e) { LOG.error(e.getMessage(), e); throw new ReportEngineException(e); } finally { ConnectionUtil.closeConnection(conn); } } @Override public byte[] exportReportToTxt(ExportContext exportContext) throws FormatNotSupportedException, ReportEngineException, InterruptedException { Connection conn = null; try { conn = ConnectionUtil.createConnection(storageService, exportContext.getReportDataSource()); JasperReport jr = getJasperReport(exportContext); JasperPrint jp = JasperReportsUtil.fillReport(storageService, exportContext.getKey(), jr, exportContext.getReportParameterValues(), conn); return JasperReportsUtil.getTxt(jp); } catch (InterruptedException e) { throw e; } catch (Exception e) { LOG.error(e.getMessage(), e); throw new ReportEngineException(e); } finally { ConnectionUtil.closeConnection(conn); } } @Override public byte[] exportReportToXml(ExportContext exportContext) throws FormatNotSupportedException, ReportEngineException, InterruptedException { Connection conn = null; try { conn = ConnectionUtil.createConnection(storageService, exportContext.getReportDataSource()); JasperReport jr = getJasperReport(exportContext); JasperPrint jp = JasperReportsUtil.fillReport(storageService, exportContext.getKey(), jr, exportContext.getReportParameterValues(), conn); return JasperReportsUtil.getXml(jp); } catch (InterruptedException e) { throw e; } catch (Exception e) { LOG.error(e.getMessage(), e); throw new ReportEngineException(e); } finally { ConnectionUtil.closeConnection(conn); } } public StorageService getStorageService() { return storageService; } public void setStorageService(StorageService storageService) { this.storageService = storageService; } public Serializable getParameter(ExternalParameter parameter) { JasperParameter jp = new JasperParameter(); jp.setName(parameter.getName()); jp.setDescription(parameter.getDescription()); jp.setValueClassName(parameter.getValueClassName()); jp.setValues(parameter.getValues()); jp.setMandatory(true); if (ExternalParameter.COMBO_TYPE.equals(parameter.getType())) { jp.setType(JasperParameterSource.COMBO); } else { jp.setType(JasperParameterSource.LIST); } return jp; } public Map<String, Serializable> getReportUserParameters(Report report, List<ExternalParameter> externalParameters) throws Exception { Connection con = null; try { JasperReport jr = getJasperReport(report); Map<String, Serializable> map = JasperReportsUtil.getJasperReportUserParameters(jr); if (report.getDataSource() == null) { throw new Exception("Report has no data source!"); } con = ConnectionUtil.createConnection(storageService, report.getDataSource()); for (String key : map.keySet()) { JasperParameter jp = (JasperParameter) map.get(key); //System.out.println(">>> name=" +jp.getName() + " jp.dep=" + jp.isDependent()); JasperParameterSource sp = getParameterSources(report, jp); //System.out.println(">> " + sp); //System.out.println(" jp type = " + jp.getValueClassName()); ArrayList<IdName> values = new ArrayList<IdName>(); if (sp != null) { if (!sp.getType().equals(JasperParameterSource.SINGLE)) { String select = sp.getSelect(); jp.setSelect(select); jp.setMandatory(sp.isMandatory()); // see if values can be loaded if (!jp.isDependent()) { //System.out.println("--- select=" + select); // external parameters may be used in select source for Jasper parameters // for now test only for those with a single rawValue (and replace the parameter name // with parameter rawValue) for (ExternalParameter ep : externalParameters) { List<IdName> list = ep.getValues(); if (list.size() == 1) { ReplacedString rs = StringUtil.replaceString(select, ep.getName(), "'" + list.get(0).getName() + "'"); if (rs.isReplaced()) { select = rs.getS(); } } } if ((select != null) && !select.trim().equals("")) { values.addAll(ConnectionUtil.getValues(select, con)); } jp.setValues(values); } else { jp.setValues(new ArrayList<IdName>()); } jp.setType(sp.getType()); } else { jp.setType(JasperParameterSource.SINGLE); jp.setMandatory(sp.isMandatory()); } } else { jp.setType(JasperParameterSource.SINGLE); jp.setMandatory(true); } } // overwite with external parameters for (ExternalParameter ep : externalParameters) { for (String name : map.keySet()) { if (name.equals(ep.getName())) { map.put(name, getParameter(ep)); break; } } } return map; } finally { ConnectionUtil.closeConnection(con); } } private JasperReport getJasperReport(Report report) throws Exception { JasperContent reportContent = (JasperContent) report.getContent(); String name = reportContent.getMaster().getName(); Settings settings = storageService.getSettings(); name = settings.getJasper().getHome() + File.separator + JasperUtil.getUnique(name, report.getId()) + "." + JasperUtil.JASPER_COMPILED_EXT; //System.out.println("name="+name); File f = new File(name); JasperReport jr; if (!f.exists()) { // byte[] xml = reportContent.getMaster().getXml(); JasperReportsUtil.compileReport(storageService, reportContent, report.getId()); } jr = JasperReportsUtil.getJasper(name); JasperReportsUtil.copyImages(settings.getJasper().getHome(), reportContent.getImageFiles()); return jr; } // useful for edit jasper parameters : do not need here the values as in getReportUserParameters public Map<String, Serializable> getReportUserParametersForEdit(Report report) throws Exception { Map<String, Serializable> result = new LinkedHashMap<String, Serializable>(); JasperReport jr = getJasperReport(report); Map<String, Serializable> map = JasperReportsUtil.getJasperReportUserParameters(jr); for (String key : map.keySet()) { JasperParameter jp = (JasperParameter) map.get(key); JasperParameterSource sp = getParameterSources(report, jp); // this parameter is not defined inside the file if (sp == null) { sp = new JasperParameterSource(jp.getName()); sp.setValueClassName(JasperReportsUtil.getValueClassName(storageService, report.getDataSource(), jp)); } result.put(sp.getName(), sp); } return result; } private JasperParameterSource getParameterSources(Report report, JasperParameter parameter) throws Exception { JasperContent reportContent = (JasperContent) report.getContent(); List<JasperParameterSource> list = JasperUtil.getParameterSources(reportContent); if (list == null) { return null; } for (JasperParameterSource parameterSource : list) { if (parameterSource.getName().equals(parameter.getName())) { return parameterSource; } } return null; } public void clearReportFiles(Report report) throws Exception { JasperReportsUtil.deleteJasperCompiledFiles(storageService, report); } public void stopExport(String key) { JasperAsynchronousFillHandle currentRunner = JasperRunnerFactory.getRunner(key); System.out.println(">>> stop key==" + key); System.out.println(">>> runner=" + currentRunner); if (currentRunner != null) { System.out.println(">>> JasperReporterEngine : stop"); try { currentRunner.cancellFill(); } catch (JRException e) { e.printStackTrace(); } } else { // stop before the runner is created, but after the "running query" process // was started JasperRunnerFactory.addRunner(key, null); } } public List<String> getImages(Report report) { List<String> images = new ArrayList<String>(); JasperContent reportContent = (JasperContent) report.getContent(); for (JcrFile file : reportContent.getImageFiles()) { images.add(file.getName()); } return images; } }