/*
* Copyright 2012-2015 Cenote GmbH.
*
* Licensed 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 de.cenote.jasperstarter;
import de.cenote.jasperstarter.gui.ParameterPrompt;
import de.cenote.jasperstarter.types.DsType;
import de.cenote.jasperstarter.types.InputType;
import de.cenote.jasperstarter.types.OutputFormat;
import de.cenote.tools.printing.Printerlookup;
import java.awt.Image;
import java.awt.MediaTracker;
import java.awt.Panel;
import java.awt.Toolkit;
import java.io.File;
import java.io.IOException;
import java.lang.reflect.InvocationTargetException;
import java.sql.Connection;
import java.sql.SQLException;
import java.text.DateFormat;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Locale;
import java.util.Map;
import java.util.logging.Level;
import java.util.logging.Logger;
import javax.print.PrintService;
import javax.print.attribute.HashPrintRequestAttributeSet;
import javax.print.attribute.HashPrintServiceAttributeSet;
import javax.print.attribute.PrintRequestAttributeSet;
import javax.print.attribute.PrintServiceAttributeSet;
import javax.print.attribute.standard.Copies;
import javax.swing.JOptionPane;
import javax.swing.UIManager;
import javax.swing.UnsupportedLookAndFeelException;
import net.sf.jasperreports.engine.JREmptyDataSource;
import net.sf.jasperreports.engine.JRException;
import net.sf.jasperreports.engine.JRParameter;
import net.sf.jasperreports.engine.JasperCompileManager;
import net.sf.jasperreports.engine.JasperExportManager;
import net.sf.jasperreports.engine.JasperFillManager;
import net.sf.jasperreports.engine.JasperPrint;
import net.sf.jasperreports.engine.JasperReport;
import net.sf.jasperreports.engine.data.JRCsvDataSource;
import net.sf.jasperreports.engine.data.JRXmlDataSource;
import net.sf.jasperreports.engine.data.JsonDataSource;
import net.sf.jasperreports.engine.design.JasperDesign;
import net.sf.jasperreports.engine.export.HtmlExporter;
import net.sf.jasperreports.engine.export.JRCsvExporter;
import net.sf.jasperreports.engine.export.JRCsvMetadataExporter;
import net.sf.jasperreports.engine.export.JRPrintServiceExporter;
import net.sf.jasperreports.engine.export.JRRtfExporter;
import net.sf.jasperreports.engine.export.JRXlsExporter;
import net.sf.jasperreports.engine.export.JRXlsMetadataExporter;
import net.sf.jasperreports.engine.export.oasis.JROdsExporter;
import net.sf.jasperreports.engine.export.oasis.JROdtExporter;
import net.sf.jasperreports.engine.export.ooxml.JRDocxExporter;
import net.sf.jasperreports.engine.export.ooxml.JRPptxExporter;
import net.sf.jasperreports.engine.export.ooxml.JRXlsxExporter;
import net.sf.jasperreports.engine.util.JRLoader;
import net.sf.jasperreports.engine.util.JRSaver;
import net.sf.jasperreports.engine.xml.JRXmlLoader;
import net.sf.jasperreports.export.SimpleCsvExporterConfiguration;
import net.sf.jasperreports.export.SimpleCsvMetadataExporterConfiguration;
import net.sf.jasperreports.export.SimpleExporterInput;
import net.sf.jasperreports.export.SimpleHtmlExporterConfiguration;
import net.sf.jasperreports.export.SimpleHtmlExporterOutput;
import net.sf.jasperreports.export.SimpleOutputStreamExporterOutput;
import net.sf.jasperreports.export.SimplePrintServiceExporterConfiguration;
import net.sf.jasperreports.export.SimpleWriterExporterOutput;
import net.sf.jasperreports.export.SimpleXlsExporterConfiguration;
import net.sf.jasperreports.export.SimpleXlsMetadataReportConfiguration;
import net.sf.jasperreports.export.SimpleXlsReportConfiguration;
import net.sf.jasperreports.export.SimpleXlsxReportConfiguration;
import net.sf.jasperreports.view.JasperViewer;
import org.apache.commons.lang.LocaleUtils;
/**
*
* @author Volker Voßkämper <vvo at cenote.de>
* @version $Revision: 5b92831f1a80:54 branch:default $
*/
public class Report {
private Config config;
private File inputFile;
private InputType initialInputType;
private JasperDesign jasperDesign;
private JasperReport jasperReport;
private JasperPrint jasperPrint;
private File output;
private Locale defaultLocale;
/**
*
* @param inputFile
* @throws IllegalArgumentException
*/
Report(Config config, File inputFile) throws IllegalArgumentException {
this.config = config;
// store the given default to reset to it in fill()
defaultLocale = Locale.getDefault();
this.inputFile = inputFile;
Object inputObject = null;
// Load the input file and try to evaluate the filetype
// this fails in case of an jrxml file
try {
inputObject = JRLoader.loadObject(inputFile);
Boolean casterror = true;
try {
jasperReport = (JasperReport) inputObject;
casterror = false;
initialInputType = InputType.JASPER_REPORT;
} catch (ClassCastException ex) {
// nothing to do here
}
try {
jasperPrint = (JasperPrint) inputObject;
casterror = false;
initialInputType = InputType.JASPER_PRINT;
} catch (ClassCastException ex) {
// nothing to do here
}
if (casterror) {
throw new IllegalArgumentException("input file: \"" + inputFile + "\" is not of a valid type");
}
} catch (JRException ex) {
try {
// now try to load it as jrxml
jasperDesign = JRXmlLoader.load(inputFile.getAbsolutePath());
initialInputType = InputType.JASPER_DESIGN;
compile();
} catch (JRException ex1) {
throw new IllegalArgumentException("input file: \"" + inputFile + "\" is not a valid jrxml file", ex1);
}
}
// generating output basename
// get the basename of inputfile
String inputBasename = inputFile.getName().split("\\.(?=[^\\.]+$)")[0];
if (!config.hasOutput()) {
// if output is omitted, use parent dir of input file
File parent = inputFile.getParentFile();
if (parent != null) {
this.output = parent;
} else {
this.output = new File(inputBasename);
}
} else {
this.output = new File(config.getOutput()).getAbsoluteFile();
}
if (this.output.isDirectory()) {
// if output is an existing directory, add the basename of input
this.output = new File(this.output, inputBasename);
}
if (config.isVerbose()) {
System.out.println("Input absolute : " + inputFile.getAbsolutePath());
try {
System.out.println("Input canonical: " + inputFile.getCanonicalPath());
} catch (IOException ex) {
Logger.getLogger(Report.class.getName()).log(Level.SEVERE, null, ex);
}
System.out.println("Input: " + inputFile.getName());
System.out.println("Input basename: " + inputBasename);
if (config.hasOutput()) {
File outputParam = new File(config.getOutput()).getAbsoluteFile();
System.out.println("OutputParam: " + outputParam.getAbsolutePath());
}
System.out.println("Output: " + output.getAbsolutePath());
try {
System.out.println("Output canonical: " + output.getCanonicalPath());
} catch (IOException ex) {
Logger.getLogger(Report.class.getName()).log(Level.SEVERE, null, ex);
}
}
}
private void compile() throws JRException {
jasperReport = JasperCompileManager.compileReport(jasperDesign);
// this option is only available if command process is active
if (config.isWriteJasper()) {
String inputBasename = inputFile.getName().split("\\.(?=[^\\.]+$)")[0];
String outputDir = inputFile.getParent();
File outputFile = new File(outputDir + "/" + inputBasename + ".jasper");
JRSaver.saveObject(jasperReport, outputFile);
}
}
public void compileToFile() {
if (initialInputType == InputType.JASPER_DESIGN) {
try {
JRSaver.saveObject(jasperReport, this.output.getAbsolutePath() + ".jasper");
} catch (JRException ex) {
throw new IllegalArgumentException("outputFile" + this.output.getAbsolutePath() + ".jasper" + "could not be written");
}
} else {
throw new IllegalArgumentException("input file: \"" + inputFile + "\" is not a valid jrxml file");
}
}
public void fill() throws InterruptedException {
if (initialInputType != InputType.JASPER_PRINT) {
// get commandLineReportParams
Map<String, Object> parameters = getCmdLineReportParams();
// if prompt...
if (config.hasAskFilter()) {
JRParameter[] reportParams = jasperReport.getParameters();
parameters = promptForParams(reportParams, parameters, jasperReport.getName());
}
try {
if (parameters.containsKey("REPORT_LOCALE")) {
if (parameters.get("REPORT_LOCALE") != null) {
Locale.setDefault((Locale) parameters.get("REPORT_LOCALE"));
}
}
if (DsType.none.equals(config.getDbType())) {
jasperPrint = JasperFillManager.fillReport(jasperReport, parameters, new JREmptyDataSource());
} else if (DsType.csv.equals(config.getDbType())) {
Db db = new Db();
JRCsvDataSource ds = db.getCsvDataSource(config);
jasperPrint = JasperFillManager.fillReport(jasperReport, parameters, ds);
} else if (DsType.xml.equals(config.getDbType())) {
Db db = new Db();
JRXmlDataSource ds = db.getXmlDataSource(config);
jasperPrint = JasperFillManager.fillReport(jasperReport, parameters, ds);
} else if (DsType.json.equals(config.getDbType())) {
Db db = new Db();
JsonDataSource ds = db.getJsonDataSource(config);
jasperPrint = JasperFillManager.fillReport(jasperReport, parameters, ds);
} else {
Db db = new Db();
Connection con = db.getConnection(config);
jasperPrint = JasperFillManager.fillReport(jasperReport, parameters, con);
con.close();
}
// reset to default
Locale.setDefault(defaultLocale);
} catch (SQLException ex) {
throw new IllegalArgumentException("Unable to connect to database: " + ex.getMessage(), ex);
} catch (JRException e) {
throw new IllegalArgumentException("Error filling report" + e.getMessage(), e);
} catch (ClassNotFoundException e) {
throw new IllegalArgumentException("Unable to load driver: " + e.getMessage(), e);
} finally {
// reset to default
Locale.setDefault(defaultLocale);
}
List<OutputFormat> formats = config.getOutputFormats();
try {
if (formats.contains(OutputFormat.jrprint)) {
JRSaver.saveObject(jasperPrint, this.output.getAbsolutePath() + ".jrprint");
}
} catch (JRException e) {
throw new IllegalArgumentException("Unable to write to file: " + this.output.getAbsolutePath() + ".jrprint", e);
}
}
}
public void print() throws JRException {
PrintRequestAttributeSet printRequestAttributeSet = new HashPrintRequestAttributeSet();
//printRequestAttributeSet.add(MediaSizeName.ISO_A4);
if (config.hasCopies()){
printRequestAttributeSet.add(new Copies(config.getCopies().intValue()));
}
PrintServiceAttributeSet printServiceAttributeSet = new HashPrintServiceAttributeSet();
//printServiceAttributeSet.add(new PrinterName("Fax", null));
JRPrintServiceExporter exporter = new JRPrintServiceExporter();
if (config.hasReportName()) {
jasperPrint.setName(config.getReportName());
}
exporter.setExporterInput(new SimpleExporterInput(jasperPrint));
SimplePrintServiceExporterConfiguration expConfig = new SimplePrintServiceExporterConfiguration();
if (config.hasPrinterName()) {
String printerName = config.getPrinterName();
PrintService service = Printerlookup.getPrintservice(printerName, Boolean.TRUE, Boolean.TRUE);
expConfig.setPrintService(service);
if (config.isVerbose()) {
System.out.println(
"printer-name: " + ((service == null)
? "No printer found with name \""
+ printerName + "\"! Using default." : "found: "
+ service.getName()));
}
}
//exporter.setParameter(JRExporterParameter.PAGE_INDEX, pageIndex);
//exporter.setParameter(JRExporterParameter.START_PAGE_INDEX, pageStartIndex);
//exporter.setParameter(JRExporterParameter.END_PAGE_INDEX, pageEndIndex);
expConfig.setPrintRequestAttributeSet(printRequestAttributeSet);
expConfig.setPrintServiceAttributeSet(printServiceAttributeSet);
expConfig.setDisplayPageDialog(Boolean.FALSE);
if (config.isWithPrintDialog()) {
setLookAndFeel();
expConfig.setDisplayPrintDialog(Boolean.TRUE);
} else {
expConfig.setDisplayPrintDialog(Boolean.FALSE);
}
exporter.setConfiguration(expConfig);
exporter.exportReport();
}
public void view() throws JRException {
setLookAndFeel();
JasperViewer.viewReport(jasperPrint, false);
}
public void exportPdf() throws JRException {
JasperExportManager.exportReportToPdfFile(jasperPrint,
this.output.getAbsolutePath() + ".pdf");
}
public void exportRtf() throws JRException {
JRRtfExporter exporter = new JRRtfExporter();
exporter.setExporterInput(new SimpleExporterInput(jasperPrint));
exporter.setExporterOutput(new SimpleWriterExporterOutput(this.output
.getAbsolutePath() + ".rtf"));
exporter.exportReport();
}
public void exportDocx() throws JRException {
JRDocxExporter exporter = new JRDocxExporter();
exporter.setExporterInput(new SimpleExporterInput(jasperPrint));
exporter.setExporterOutput(new SimpleOutputStreamExporterOutput(this.output
.getAbsolutePath() + ".docx"));
exporter.exportReport();
}
public void exportOdt() throws JRException {
JROdtExporter exporter = new JROdtExporter();
exporter.setExporterInput(new SimpleExporterInput(jasperPrint));
exporter.setExporterOutput(new SimpleOutputStreamExporterOutput(this.output
.getAbsolutePath() + ".odt"));
exporter.exportReport();
}
public void exportHtml() throws JRException {
JasperExportManager.exportReportToHtmlFile(jasperPrint,
this.output.getAbsolutePath() + ".html");
}
public void exportXml() throws JRException {
JasperExportManager.exportReportToXmlFile(jasperPrint,
this.output.getAbsolutePath() + ".xml", false);
}
public void exportXls() throws JRException {
Map<String, String> dateFormats = new HashMap<String, String>();
dateFormats.put("EEE, MMM d, yyyy", "ddd, mmm d, yyyy");
JRXlsExporter exporter = new JRXlsExporter();
SimpleXlsReportConfiguration repConfig = new SimpleXlsReportConfiguration();
exporter.setExporterInput(new SimpleExporterInput(jasperPrint));
exporter.setExporterOutput(new SimpleOutputStreamExporterOutput(
this.output.getAbsolutePath() + ".xls"));
repConfig.setDetectCellType(Boolean.TRUE);
repConfig.setFormatPatternsMap(dateFormats);
exporter.setConfiguration(repConfig);
exporter.exportReport();
}
// the XLS Metadata Exporter
public void exportXlsMeta() throws JRException {
Map<String, String> dateFormats = new HashMap<String, String>();
dateFormats.put("EEE, MMM d, yyyy", "ddd, mmm d, yyyy");
JRXlsMetadataExporter exporter = new JRXlsMetadataExporter();
SimpleXlsMetadataReportConfiguration repConfig = new SimpleXlsMetadataReportConfiguration();
exporter.setExporterInput(new SimpleExporterInput(jasperPrint));
exporter.setExporterOutput(new SimpleOutputStreamExporterOutput(
this.output.getAbsolutePath() + ".xls"));
repConfig.setDetectCellType(Boolean.TRUE);
repConfig.setFormatPatternsMap(dateFormats);
exporter.setConfiguration(repConfig);
exporter.exportReport();
}
public void exportXlsx() throws JRException {
Map<String, String> dateFormats = new HashMap<String, String>();
dateFormats.put("EEE, MMM d, yyyy", "ddd, mmm d, yyyy");
JRXlsxExporter exporter = new JRXlsxExporter();
SimpleXlsxReportConfiguration repConfig = new SimpleXlsxReportConfiguration();
exporter.setExporterInput(new SimpleExporterInput(jasperPrint));
exporter.setExporterOutput(new SimpleOutputStreamExporterOutput(
this.output.getAbsolutePath() + ".xlsx"));
repConfig.setDetectCellType(Boolean.TRUE);
repConfig.setFormatPatternsMap(dateFormats);
exporter.setConfiguration(repConfig);
exporter.exportReport();
}
public void exportCsv() throws JRException {
JRCsvExporter exporter = new JRCsvExporter();
SimpleCsvExporterConfiguration configuration = new SimpleCsvExporterConfiguration();
configuration.setFieldDelimiter(config.getOutFieldDel());
exporter.setConfiguration(configuration);
exporter.setExporterInput(new SimpleExporterInput(jasperPrint));
exporter.setExporterOutput(new SimpleWriterExporterOutput(
this.output.getAbsolutePath() + ".csv", config.getOutCharset()));
exporter.exportReport();
}
// the CSV Metadata Exporter
public void exportCsvMeta() throws JRException {
JRCsvMetadataExporter exporter = new JRCsvMetadataExporter();
SimpleCsvMetadataExporterConfiguration configuration = new SimpleCsvMetadataExporterConfiguration();
configuration.setFieldDelimiter(config.getOutFieldDel());
exporter.setConfiguration(configuration);
exporter.setExporterInput(new SimpleExporterInput(jasperPrint));
exporter.setExporterOutput(new SimpleWriterExporterOutput(
this.output.getAbsolutePath() + ".csv", config.getOutCharset()));
exporter.exportReport();
}
public void exportOds() throws JRException {
JROdsExporter exporter = new JROdsExporter();
exporter.setExporterInput(new SimpleExporterInput(jasperPrint));
exporter.setExporterOutput(new SimpleOutputStreamExporterOutput(
this.output.getAbsolutePath() + ".ods"));
exporter.exportReport();
}
public void exportPptx() throws JRException {
JRPptxExporter exporter = new JRPptxExporter();
exporter.setExporterInput(new SimpleExporterInput(jasperPrint));
exporter.setExporterOutput(new SimpleOutputStreamExporterOutput(
this.output.getAbsolutePath() + ".pptx"));
exporter.exportReport();
}
public void exportXhtml() throws JRException {
HtmlExporter exporter = new HtmlExporter();
exporter.setExporterInput(new SimpleExporterInput(jasperPrint));
exporter.setExporterOutput(new SimpleHtmlExporterOutput(this.output
.getAbsolutePath() + ".x.html"));
exporter.exportReport();
}
private Map<String, Object> getCmdLineReportParams() {
JRParameter[] jrParameterArray = jasperReport.getParameters();
Map<String, JRParameter> jrParameters = new HashMap<String, JRParameter>();
Map<String, Object> parameters = new HashMap<String, Object>();
List<String> params;
if (config.hasParams()) {
params = config.getParams();
for (JRParameter rp : jrParameterArray) {
jrParameters.put(rp.getName(), rp);
}
String paramName = null;
//String paramType = null;
String paramValue = null;
for (String p : params) {
try {
paramName = p.split("=")[0];
paramValue = p.split("=", 2)[1];
if (config.isVerbose()) {
System.out.println("Using report parameter: "
+ paramName + " = " + paramValue);
}
} catch (Exception e) {
throw new IllegalArgumentException("Wrong report param format! " + p, e);
}
if (!jrParameters.containsKey(paramName)) {
throw new IllegalArgumentException("Parameter '"
+ paramName + "' does not exist in report!");
}
JRParameter reportParam = jrParameters.get(paramName);
try {
// special parameter handlers must also implemeted in
// ParameterPanel.java
if (Date.class
.equals(reportParam.getValueClass())) {
// Date must be in ISO8601 format. Example 2012-12-31
DateFormat dateFormat = new SimpleDateFormat("yy-MM-dd");
parameters.put(paramName, (Date) dateFormat.parse(paramValue));
} else if (Image.class
.equals(reportParam.getValueClass())) {
Image image =
Toolkit.getDefaultToolkit().createImage(
JRLoader.loadBytes(new File(paramValue)));
MediaTracker traker = new MediaTracker(new Panel());
traker.addImage(image, 0);
try {
traker.waitForID(0);
} catch (Exception e) {
throw new IllegalArgumentException(
"Image tracker error: " + e.getMessage(), e);
}
parameters.put(paramName, image);
} else if (Locale.class
.equals(reportParam.getValueClass())) {
parameters.put(paramName, LocaleUtils.toLocale(paramValue));
} else {
// handle generic parameters with string constructor
try {
parameters.put(paramName,
reportParam.getValueClass()
.getConstructor(String.class)
.newInstance(paramValue));
} catch (InstantiationException ex) {
throw new IllegalArgumentException("Parameter '"
+ paramName + "' of type '"
+ reportParam.getValueClass().getName()
+ " caused " + ex.getClass().getName()
+ " " + ex.getMessage(), ex);
} catch (IllegalAccessException ex) {
throw new IllegalArgumentException("Parameter '"
+ paramName + "' of type '"
+ reportParam.getValueClass().getName()
+ " caused " + ex.getClass().getName()
+ " " + ex.getMessage(), ex);
} catch (InvocationTargetException ex) {
Throwable cause = ex.getCause();
throw new IllegalArgumentException("Parameter '"
+ paramName + "' of type '"
+ reportParam.getValueClass().getName()
+ " caused " + cause.getClass().getName()
+ " " + cause.getMessage(), cause);
} catch (NoSuchMethodException ex) {
throw new IllegalArgumentException("Parameter '"
+ paramName + "' of type '"
+ reportParam.getValueClass().getName()
+ " with value '" + paramValue
+ "' is not supported by JasperStarter!", ex);
}
}
} catch (NumberFormatException e) {
throw new IllegalArgumentException("NumberFormatException: " + e.getMessage() + "\" in \"" + p + "\"", e);
} catch (java.text.ParseException e) {
throw new IllegalArgumentException(e.getMessage() + "\" in \"" + p + "\"", e);
} catch (JRException e) {
throw new IllegalArgumentException("Unable to load image from: " + paramValue, e);
}
}
}
return parameters;
}
public static void setLookAndFeel() {
try {
// Set System L&F
UIManager.setLookAndFeel(
UIManager.getSystemLookAndFeelClassName());
} catch (UnsupportedLookAndFeelException e) {
e.printStackTrace();
} catch (ClassNotFoundException e) {
e.printStackTrace();
} catch (InstantiationException e) {
e.printStackTrace();
} catch (IllegalAccessException e) {
e.printStackTrace();
}
}
private Map<String, Object> promptForParams(JRParameter[] reportParams, Map<String, Object> params, String reportName) throws InterruptedException {
boolean isForPromptingOnly = false;
boolean isUserDefinedOnly = false;
boolean emptyOnly = false;
switch (config.getAskFilter()) {
case ae:
emptyOnly = true;
case a:
isForPromptingOnly = false;
isUserDefinedOnly = false;
break;
case ue:
emptyOnly = true;
case u:
isUserDefinedOnly = true;
break;
case pe:
emptyOnly = true;
case p:
isUserDefinedOnly = true;
isForPromptingOnly = true;
break;
}
Report.setLookAndFeel();
ParameterPrompt prompt = new ParameterPrompt(null, reportParams, params,
reportName, isForPromptingOnly, isUserDefinedOnly, emptyOnly);
if (JOptionPane.OK_OPTION != prompt.show()) {
throw new InterruptedException("User aborted at parameter promt!");
}
if (config.isVerbose()) {
System.out.println("----------------------------");
System.out.println("Parameter prompt:");
for (Object key : params.keySet()) {
System.out.println(key + " = " + params.get(key));
}
System.out.println("----------------------------");
}
return params;
}
public JRParameter[] getReportParameters() throws IllegalArgumentException {
JRParameter[] returnval = null;
if (jasperReport != null) {
returnval = jasperReport.getParameters();
} else {
throw new IllegalArgumentException(
"Parameters could not be read from "
+ inputFile.getAbsolutePath());
}
return returnval;
}
}