/* * This program is free software; you can redistribute it and/or modify it under the * terms of the GNU Lesser General Public License, version 2.1 as published by the Free Software * Foundation. * * You should have received a copy of the GNU Lesser General Public License along with this * program; if not, you can obtain a copy at http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html * or from the Free Software Foundation, Inc., * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. * * This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; * without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. * See the GNU Lesser General Public License for more details. * * Copyright 2006 - 2009 Pentaho Corporation. All rights reserved. * */ package org.pentaho.platform.plugin.action.jfreereport; import java.io.ByteArrayOutputStream; import java.io.IOException; import java.io.InputStream; import java.util.Iterator; import java.util.Properties; import java.util.Set; import java.util.zip.ZipEntry; import java.util.zip.ZipInputStream; import javax.activation.DataSource; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; import org.pentaho.actionsequence.dom.actions.JFreeReportAction; import org.pentaho.commons.connection.ActivationHelper; import org.pentaho.commons.connection.IPentahoConnection; import org.pentaho.commons.connection.IPentahoResultSet; import org.pentaho.jfreereport.castormodel.reportspec.ReportSpec; import org.pentaho.jfreereport.wizard.utility.CastorUtility; import org.pentaho.jfreereport.wizard.utility.report.ReportGenerationUtility; import org.pentaho.jfreereport.wizard.utility.report.ReportParameterUtility; import org.pentaho.platform.api.data.IDatasourceService; import org.pentaho.platform.api.engine.IActionParameter; import org.pentaho.platform.engine.core.system.PentahoSystem; import org.pentaho.platform.engine.services.connection.PentahoConnectionFactory; import org.pentaho.platform.plugin.action.jfreereport.helper.PentahoTableDataFactory; import org.pentaho.platform.plugin.action.jfreereport.helper.PentahoTableModel; import org.pentaho.platform.plugin.action.messages.Messages; import org.pentaho.reporting.engine.classic.core.MasterReport; /** * The report-wizard component generates a report definition from a report-spec * file. Use this component, if want to use the standard-report process only or * if you have no need to tweak the processing. * <p/> * @created May 15, 2006 * @author Michael D'Amour */ public class ReportWizardSpecComponent extends JFreeReportComponent { private static final long serialVersionUID = 3435921119638344882L; private ReportSpec reportSpec; public ReportWizardSpecComponent() { } @Override public Log getLogger() { return LogFactory.getLog(ReportWizardSpecComponent.class); } @Override public boolean validateAction() { JFreeReportAction jFreeReportAction = (JFreeReportAction) getActionDefinition(); return (jFreeReportAction.getReportDefinition() != null) && super.validateAction(); } @Override protected boolean executeReportAction() { boolean result = true; try { reportSpec = getReportSpec(); result = super.executeReportAction(); } catch (IOException ex) { error(ex.getLocalizedMessage()); result = false; } return result; } @SuppressWarnings("deprecation") @Override public MasterReport getReport() throws Exception { MasterReport report = null; if (reportSpec != null) { ByteArrayOutputStream outputStream = new ByteArrayOutputStream(); ReportGenerationUtility.createJFreeReportXML(reportSpec, outputStream, 0, 0, false, "", 0, 0); //$NON-NLS-1$ String reportDefinition = new String(outputStream.toByteArray()); report = createReport(reportDefinition); } else { report = super.getReport(); } return report; } @Override protected PentahoTableDataFactory getDataFactory() throws ClassNotFoundException, InstantiationException, IllegalAccessException, Exception { PentahoTableDataFactory factory = null; if (reportSpec != null) { if (!isDefinedInput(AbstractJFreeReportComponent.REPORTGENERATEDEFN_REPORTTEMP_PERFQRY) || "true".equals(getInputParameter(AbstractJFreeReportComponent.REPORTGENERATEDEFN_REPORTTEMP_PERFQRY))) { //$NON-NLS-1$ if (reportSpec.getReportSpecChoice().getXqueryUrl() != null) { // handle xquery } else { IPentahoResultSet pentahoResultSet = getResultSet(getReportSpec()); factory = new PentahoTableDataFactory(); pentahoResultSet.beforeFirst(); factory.addTable(AbstractJFreeReportComponent.DATACOMPONENT_DEFAULTINPUT, new PentahoTableModel( pentahoResultSet)); } } else { factory = super.getDataFactory(); } } else { factory = super.getDataFactory(); } return factory; } @SuppressWarnings("deprecation") public ReportSpec getReportSpec() throws IOException { JFreeReportAction jFreeReportAction = (JFreeReportAction) getActionDefinition(); DataSource dataSource = new ActivationHelper.PentahoStreamSourceWrapper(jFreeReportAction .getReportDefinitionDataSource()); ReportSpec reportSpec = null; reportSpec = loadFromZip(dataSource.getInputStream()); if (reportSpec == null) { dataSource = new ActivationHelper.PentahoStreamSourceWrapper(jFreeReportAction.getReportDefinitionDataSource()); reportSpec = (ReportSpec) CastorUtility.getInstance().readCastorObject(dataSource.getInputStream(), ReportSpec.class); } return reportSpec; } @SuppressWarnings("deprecation") private ReportSpec loadFromZip(final InputStream reportSpecInputStream) { try { ZipInputStream zis = new ZipInputStream(reportSpecInputStream); ZipEntry reportSpecEntry = findReportSpec(zis); if (reportSpecEntry == null) { return null; } // is this really sane? Blindly using the first zip entry is ... argh! // maybe you should use GZipped streams instead... return (ReportSpec) CastorUtility.getInstance().readCastorObject(zis, ReportSpec.class); } catch (Exception e) { return null; } } /** * Look through the Zip stream and find an entry whose name is .xreportspec. * If the entry is found, return it, otherwise return null. * * @param zStrm * @return If the entry is found, return it, otherwise return null. * @throws IOException */ private ZipEntry findReportSpec(final ZipInputStream zStrm) throws IOException { ZipEntry reportSpecEntry = null; // for loop has no body for (reportSpecEntry = zStrm.getNextEntry(); (null != reportSpecEntry) && !reportSpecEntry.getName().endsWith(".xreportspec"); reportSpecEntry = zStrm //$NON-NLS-1$ .getNextEntry()) { ; } return reportSpecEntry; } public IPentahoResultSet getResultSet(final ReportSpec reportSpec) throws Exception { String jndiName = reportSpec.getReportSpecChoice().getJndiSource(); IPentahoConnection connection = null; if (reportSpec.getIsMDX()) { // did this ever work?? String connectStr = ""; //$NON-NLS-1$ IDatasourceService datasourceService = PentahoSystem.getObjectFactory().get(IDatasourceService.class ,null); String dsName = datasourceService.getDSBoundName(jndiName); if (dsName != null) { connectStr = "dataSource=" + dsName + "; Catalog=mondrian"; //$NON-NLS-1$ //$NON-NLS-2$ } else { error(Messages.getInstance().getErrorString("MDXBaseComponent.ERROR_0005_INVALID_CONNECTION")); //$NON-NLS-1$ return null; } Properties props = new Properties(); props.setProperty(IPentahoConnection.CONNECTION, connectStr); props.setProperty(IPentahoConnection.PROVIDER, reportSpec.getMondrianCubeDefinitionPath()); connection = PentahoConnectionFactory.getConnection(IPentahoConnection.MDX_DATASOURCE, props, getSession(), this); } else { connection = PentahoConnectionFactory.getConnection(IPentahoConnection.SQL_DATASOURCE, jndiName, getSession(), this); } String query = ReportParameterUtility.setupParametersForActionSequence(reportSpec.getQuery()); query = setupQueryParameters(query); IPentahoResultSet res = connection.executeQuery(query); return res; } public String setupQueryParameters(String query) { Set inputNames = getInputNames(); Iterator iter = inputNames.iterator(); while (iter.hasNext()) { String inputName = (String) iter.next(); final IActionParameter inputParameter = getInputParameter(inputName); final Object value = inputParameter.getValue(); if ((value instanceof String) == false) { continue; } String paramValue = (String) value; String param = "\\{" + inputName + "\\}"; //$NON-NLS-1$ //$NON-NLS-2$ query = query.replaceAll(param, paramValue); } return query; } }