001: /*
002: * Copyright (C) 2006 by Open Source Software Solutions, LLC and Contributors
003: *
004: * This program is free software; you can redistribute it and/or modify it
005: * under the terms of the GNU General Public License as published by the Free
006: * Software Foundation; either version 2 of the License, or (at your option)
007: * any later version.
008: *
009: * This program is distributed in the hope that it will be useful, but WITHOUT
010: * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
011: * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
012: * more details.
013: *
014: * You should have received a copy of the GNU General Public License along with
015: * this program; if not, write to the Free Software Foundation, Inc., 59 Temple
016: * Place - Suite 330, Boston, MA 02111-1307, USA.
017: *
018: * Original Author : Roberto Nibali - rnibali@pyx.ch
019: * Contributor(s) : Erik Swenson - erik@oreports.com
020: *
021: */
022:
023: package org.efs.openreports.engine;
024:
025: import java.io.ByteArrayInputStream;
026: import java.io.ByteArrayOutputStream;
027: import java.util.ArrayList;
028: import java.util.Collection;
029: import java.util.Iterator;
030: import java.util.List;
031: import java.util.Map;
032:
033: import org.apache.log4j.Logger;
034: import org.eclipse.birt.report.engine.api.HTMLRenderOption;
035: import org.eclipse.birt.report.engine.api.IGetParameterDefinitionTask;
036: import org.eclipse.birt.report.engine.api.IParameterDefnBase;
037: import org.eclipse.birt.report.engine.api.IParameterGroupDefn;
038: import org.eclipse.birt.report.engine.api.IRenderOption;
039: import org.eclipse.birt.report.engine.api.IReportEngine;
040: import org.eclipse.birt.report.engine.api.IReportRunnable;
041: import org.eclipse.birt.report.engine.api.IRunAndRenderTask;
042: import org.eclipse.birt.report.engine.api.IScalarParameterDefn;
043: import org.eclipse.birt.report.model.api.OdaDataSourceHandle;
044: import org.eclipse.birt.report.model.api.ReportDesignHandle;
045: import org.eclipse.birt.report.model.api.activity.SemanticException;
046: import org.efs.openreports.ReportConstants.ExportType;
047: import org.efs.openreports.engine.input.ReportEngineInput;
048: import org.efs.openreports.engine.output.ReportEngineOutput;
049: import org.efs.openreports.objects.Report;
050: import org.efs.openreports.objects.ReportDataSource;
051: import org.efs.openreports.objects.ReportParameter;
052: import org.efs.openreports.providers.BirtProvider;
053: import org.efs.openreports.providers.DataSourceProvider;
054: import org.efs.openreports.providers.DirectoryProvider;
055: import org.efs.openreports.providers.PropertiesProvider;
056: import org.efs.openreports.providers.ProviderException;
057:
058: /**
059: * Eclipse BIRT ReportEngine implementation. This implementation sets the
060: * BIRTHome directory to the 'platform' directory underneath the 'reports'
061: * directory. All images created during report generation are stored in the
062: * 'reports/images/temp' directory.
063: *
064: * @author Roberto Nibali
065: * @author Erik Swenson
066: *
067: */
068: public class BirtReportEngine extends ReportEngine {
069: protected static Logger log = Logger
070: .getLogger(BirtReportEngine.class);
071:
072: public BirtReportEngine(DataSourceProvider dataSourceProvider,
073: DirectoryProvider directoryProvider,
074: PropertiesProvider propertiesProvider) {
075: super (dataSourceProvider, directoryProvider, propertiesProvider);
076: }
077:
078: /**
079: * Generates a report from a BIRT report design.
080: */
081: @SuppressWarnings("unchecked")
082: @Override
083: public ReportEngineOutput generateReport(ReportEngineInput input)
084: throws ProviderException {
085: Report report = input.getReport();
086: Map<String, Object> parameters = input.getParameters();
087:
088: ReportEngineOutput output = new ReportEngineOutput();
089: ByteArrayOutputStream out = new ByteArrayOutputStream();
090:
091: IReportEngine engine = BirtProvider
092: .getBirtEngine(directoryProvider.getReportDirectory()
093: + "platform");
094:
095: // Set options for task
096: HTMLRenderOption renderOption = new HTMLRenderOption();
097: renderOption.setOutputStream(out);
098: renderOption.setImageDirectory(directoryProvider
099: .getTempDirectory());
100: renderOption.setBaseImageURL("report-images");
101:
102: try {
103: String designFile = directoryProvider.getReportDirectory()
104: + report.getFile();
105:
106: log.info("Loading BIRT report design: " + report.getFile());
107:
108: IReportRunnable design = engine
109: .openReportDesign(designFile);
110:
111: handleDataSourceOverrides(design);
112:
113: if (input.getExportType() == ExportType.PDF) {
114: output
115: .setContentType(ReportEngineOutput.CONTENT_TYPE_PDF);
116: renderOption
117: .setOutputFormat(IRenderOption.OUTPUT_FORMAT_PDF);
118: } else if (input.getExportType() == ExportType.HTML) {
119: output
120: .setContentType(ReportEngineOutput.CONTENT_TYPE_HTML);
121: renderOption
122: .setOutputFormat(IRenderOption.OUTPUT_FORMAT_HTML);
123: } else if (input.getExportType() == ExportType.XLS) {
124: output
125: .setContentType(ReportEngineOutput.CONTENT_TYPE_XLS);
126: renderOption.setOutputFormat("xls");
127: } else {
128: log.error("Export type not yet implemented: "
129: + input.getExportType());
130: }
131:
132: IRunAndRenderTask task = engine
133: .createRunAndRenderTask(design);
134: task.setRenderOption(renderOption);
135: task.setParameterValues(parameters);
136: task.validateParameters();
137:
138: if (input.getLocale() != null) {
139: task.setLocale(input.getLocale());
140: }
141:
142: if (input.getXmlInput() != null) {
143: ByteArrayInputStream stream = new ByteArrayInputStream(
144: input.getXmlInput().getBytes());
145: task
146: .getAppContext()
147: .put(
148: "org.eclipse.datatools.enablement.oda.xml.inputStream",
149: stream);
150: }
151:
152: log.info("Generating BIRT report: " + report.getName());
153:
154: task.run();
155: task.close();
156:
157: log.info("Finished Generating BIRT report: "
158: + report.getName());
159:
160: output.setContent(out.toByteArray());
161: } catch (Throwable e) {
162: log.error("generateReport Exception", e);
163: throw new ProviderException(e.toString());
164: }
165:
166: return output;
167: }
168:
169: /*
170: * Overrides BIRT DataSources with OpenReports DataSources. In order
171: * for DataSources to be overriden, the name of the DataSource in the
172: * BIRT rptdesign file must match the name of an existing OpenReports
173: * DataSource.
174: */
175: private void handleDataSourceOverrides(IReportRunnable design) {
176: ReportDesignHandle reportDH = (ReportDesignHandle) design
177: .getDesignHandle();
178:
179: List<?> birtDataSources = reportDH.getAllDataSources();
180:
181: if (birtDataSources == null)
182: return;
183:
184: Iterator<?> iterator = birtDataSources.iterator();
185: while (iterator.hasNext()) {
186: Object dataSource = iterator.next();
187: if (dataSource instanceof OdaDataSourceHandle) {
188: OdaDataSourceHandle dataSH = (OdaDataSourceHandle) dataSource;
189:
190: try {
191: ReportDataSource reportDataSource = dataSourceProvider
192: .getDataSource(dataSH.getName());
193:
194: if (reportDataSource != null) {
195: log.info("Overriding BIRT DataSource: "
196: + dataSH.getName());
197:
198: log
199: .debug("Original connection properties for: "
200: + dataSH.getName());
201: log.debug("URL: "
202: + dataSH.getStringProperty("odaURL"));
203: log
204: .debug("DRIVER: "
205: + dataSH
206: .getStringProperty("odaDriverClass"));
207: log.debug("USER: "
208: + dataSH.getStringProperty("odaUser"));
209:
210: try {
211: dataSH.setStringProperty("odaURL",
212: reportDataSource.getUrl());
213: dataSH.setStringProperty("odaDriverClass",
214: reportDataSource
215: .getDriverClassName());
216: dataSH.setStringProperty("odaUser",
217: reportDataSource.getUsername());
218: dataSH.setStringProperty("odaPassword",
219: reportDataSource.getPassword());
220: } catch (SemanticException e) {
221: log.error("SemanticException", e);
222: }
223:
224: log.debug("New connection properties for: "
225: + dataSH.getName());
226: log.debug("URL: "
227: + dataSH.getStringProperty("odaURL"));
228: log
229: .debug("DRIVER: "
230: + dataSH
231: .getStringProperty("odaDriverClass"));
232: log.debug("USER: "
233: + dataSH.getStringProperty("odaUser"));
234: } else {
235: log.info("Unknown data source: "
236: + dataSH.getName());
237: }
238: } catch (ProviderException pe) {
239: log.error("ProviderException", pe);
240: }
241: }
242: }
243:
244: design.setDesignHandle(reportDH);
245: }
246:
247: @Override
248: @SuppressWarnings("unchecked")
249: public List buildParameterList(Report report)
250: throws ProviderException {
251: IReportEngine engine = BirtProvider
252: .getBirtEngine(directoryProvider.getReportDirectory()
253: + "platform");
254:
255: String designFile = directoryProvider.getReportDirectory()
256: + report.getFile();
257: IReportRunnable design = null;
258:
259: try {
260: design = engine.openReportDesign(designFile);
261: } catch (Throwable e) {
262: log.error("getParameterNames Exception", e);
263: throw new ProviderException(e.toString());
264: }
265:
266: IGetParameterDefinitionTask task = engine
267: .createGetParameterDefinitionTask(design);
268:
269: Collection<IParameterDefnBase> params = task
270: .getParameterDefns(true);
271:
272: ArrayList<ReportParameter> parameters = new ArrayList<ReportParameter>();
273:
274: Iterator<IParameterDefnBase> iter = params.iterator();
275: // Iterate over all parameters
276: while (iter.hasNext()) {
277: IParameterDefnBase param = iter.next();
278: // Group section found
279: if (param instanceof IParameterGroupDefn) {
280: // Get Group Name
281: IParameterGroupDefn group = (IParameterGroupDefn) param;
282:
283: // Get the parameters within a group
284: Iterator<IScalarParameterDefn> i2 = group.getContents()
285: .iterator();
286: while (i2.hasNext()) {
287: IScalarParameterDefn scalar = i2.next();
288:
289: ReportParameter rp = new ReportParameter();
290: rp.setClassName("java.lang.String");
291: rp.setDescription(scalar.getName());
292: rp.setName(scalar.getName());
293: rp.setType(ReportParameter.TEXT_PARAM);
294:
295: parameters.add(rp);
296: }
297: } else {
298: // Parameters are not in a group
299: IScalarParameterDefn scalar = (IScalarParameterDefn) param;
300:
301: ReportParameter rp = new ReportParameter();
302: rp.setClassName("java.lang.String");
303: rp.setDescription(scalar.getName());
304: rp.setName(scalar.getName());
305: rp.setType(ReportParameter.TEXT_PARAM);
306:
307: parameters.add(rp);
308: }
309: }
310:
311: task.close();
312:
313: return parameters;
314: }
315: }
|