190 lines
9.5 KiB
Java
190 lines
9.5 KiB
Java
package net.sf.jasperreports.engine.design;
|
|
|
|
import java.io.File;
|
|
import java.io.Serializable;
|
|
import java.util.Collection;
|
|
import java.util.Iterator;
|
|
import java.util.List;
|
|
import java.util.ListIterator;
|
|
import java.util.Random;
|
|
import net.sf.jasperreports.crosstabs.JRCrosstab;
|
|
import net.sf.jasperreports.crosstabs.design.JRDesignCrosstab;
|
|
import net.sf.jasperreports.engine.JRDataset;
|
|
import net.sf.jasperreports.engine.JRException;
|
|
import net.sf.jasperreports.engine.JRExpressionCollector;
|
|
import net.sf.jasperreports.engine.JRReport;
|
|
import net.sf.jasperreports.engine.JRRuntimeException;
|
|
import net.sf.jasperreports.engine.JasperReport;
|
|
import net.sf.jasperreports.engine.fill.JREvaluator;
|
|
import net.sf.jasperreports.engine.util.JRProperties;
|
|
import net.sf.jasperreports.engine.util.JRSaver;
|
|
import net.sf.jasperreports.engine.util.JRStringUtil;
|
|
|
|
public abstract class JRAbstractCompiler implements JRCompiler {
|
|
private static final int NAME_SUFFIX_RANDOM_MAX = 1000000;
|
|
|
|
private static final Random random = new Random();
|
|
|
|
private final boolean needsSourceFiles;
|
|
|
|
protected JRAbstractCompiler(boolean needsSourceFiles) {
|
|
this.needsSourceFiles = needsSourceFiles;
|
|
}
|
|
|
|
public static String getUnitName(JasperReport report, JRDataset dataset) {
|
|
return getUnitName((JRReport)report, dataset, report.getCompileNameSuffix());
|
|
}
|
|
|
|
protected static String getUnitName(JRReport report, JRDataset dataset, String nameSuffix) {
|
|
if (dataset.isMainDataset()) {
|
|
className = report.getName();
|
|
} else {
|
|
className = report.getName() + "_" + dataset.getName();
|
|
}
|
|
String className = JRStringUtil.getLiteral(className) + nameSuffix;
|
|
return className;
|
|
}
|
|
|
|
public static String getUnitName(JasperReport report, JRCrosstab crosstab) {
|
|
return getUnitName((JRReport)report, crosstab.getId(), report.getCompileNameSuffix());
|
|
}
|
|
|
|
protected static String getUnitName(JRReport report, JRCrosstab crosstab, JRExpressionCollector expressionCollector, String nameSuffix) {
|
|
Integer crosstabId = expressionCollector.getCrosstabId(crosstab);
|
|
if (crosstabId == null)
|
|
throw new JRRuntimeException("Crosstab ID not found.");
|
|
return getUnitName(report, crosstabId.intValue(), nameSuffix);
|
|
}
|
|
|
|
protected static String getUnitName(JRReport report, int crosstabId, String nameSuffix) {
|
|
return JRStringUtil.getLiteral(report.getName()) + "_CROSSTAB" + crosstabId + nameSuffix;
|
|
}
|
|
|
|
public final JasperReport compileReport(JasperDesign jasperDesign) throws JRException {
|
|
checkLanguage(jasperDesign.getLanguage());
|
|
JRExpressionCollector expressionCollector = JRExpressionCollector.collector((JRReport)jasperDesign);
|
|
verifyDesign(jasperDesign, expressionCollector);
|
|
String nameSuffix = createNameSuffix();
|
|
boolean isKeepJavaFile = JRProperties.getBooleanProperty("net.sf.jasperreports.compiler.keep.java.file");
|
|
File tempDirFile = null;
|
|
if (isKeepJavaFile || this.needsSourceFiles) {
|
|
String tempDirStr = JRProperties.getProperty("net.sf.jasperreports.compiler.temp.dir");
|
|
tempDirFile = new File(tempDirStr);
|
|
if (!tempDirFile.exists() || !tempDirFile.isDirectory())
|
|
throw new JRException("Temporary directory not found : " + tempDirStr);
|
|
}
|
|
List datasets = jasperDesign.getDatasetsList();
|
|
List crosstabs = jasperDesign.getCrosstabs();
|
|
JRCompilationUnit[] units = new JRCompilationUnit[datasets.size() + crosstabs.size() + 1];
|
|
units[0] = createCompileUnit(jasperDesign, jasperDesign.getMainDesignDataset(), expressionCollector, tempDirFile, nameSuffix);
|
|
int sourcesCount = 1;
|
|
for (Iterator iterator = datasets.iterator(); iterator.hasNext(); sourcesCount++) {
|
|
JRDesignDataset dataset = iterator.next();
|
|
units[sourcesCount] = createCompileUnit(jasperDesign, dataset, expressionCollector, tempDirFile, nameSuffix);
|
|
}
|
|
for (Iterator it = crosstabs.iterator(); it.hasNext(); sourcesCount++) {
|
|
JRDesignCrosstab crosstab = it.next();
|
|
units[sourcesCount] = createCompileUnit(jasperDesign, crosstab, expressionCollector, tempDirFile, nameSuffix);
|
|
}
|
|
String classpath = JRProperties.getProperty("net.sf.jasperreports.compiler.classpath");
|
|
try {
|
|
String compileErrors = compileUnits(units, classpath, tempDirFile);
|
|
if (compileErrors != null)
|
|
throw new JRException("Errors were encountered when compiling report expressions class file:\n" + compileErrors);
|
|
JRReportCompileData reportCompileData = new JRReportCompileData();
|
|
reportCompileData.setMainDatasetCompileData(units[0].getCompileData());
|
|
for (ListIterator listIterator1 = datasets.listIterator(); listIterator1.hasNext(); ) {
|
|
JRDesignDataset dataset = listIterator1.next();
|
|
reportCompileData.setDatasetCompileData((JRDataset)dataset, units[listIterator1.nextIndex()].getCompileData());
|
|
}
|
|
for (ListIterator listIterator = crosstabs.listIterator(); listIterator.hasNext(); ) {
|
|
JRDesignCrosstab crosstab = listIterator.next();
|
|
Integer crosstabId = expressionCollector.getCrosstabId((JRCrosstab)crosstab);
|
|
reportCompileData.setCrosstabCompileData(crosstabId.intValue(), units[datasets.size() + listIterator.nextIndex()].getCompileData());
|
|
}
|
|
JasperReport jasperReport = new JasperReport((JRReport)jasperDesign, getCompilerClass(), reportCompileData, expressionCollector, nameSuffix);
|
|
return jasperReport;
|
|
} catch (JRException e) {
|
|
throw e;
|
|
} catch (Exception e) {
|
|
throw new JRException("Error compiling report design.", e);
|
|
} finally {
|
|
if (this.needsSourceFiles && !isKeepJavaFile)
|
|
deleteSourceFiles(units);
|
|
}
|
|
}
|
|
|
|
private static String createNameSuffix() {
|
|
return "_" + System.currentTimeMillis() + "_" + random.nextInt(1000000);
|
|
}
|
|
|
|
protected String getCompilerClass() {
|
|
return getClass().getName();
|
|
}
|
|
|
|
private void verifyDesign(JasperDesign jasperDesign, JRExpressionCollector expressionCollector) throws JRException {
|
|
Collection brokenRules = JRVerifier.verifyDesign(jasperDesign, expressionCollector);
|
|
if (brokenRules != null && brokenRules.size() > 0)
|
|
throw new JRValidationException(brokenRules);
|
|
}
|
|
|
|
private JRCompilationUnit createCompileUnit(JasperDesign jasperDesign, JRDesignDataset dataset, JRExpressionCollector expressionCollector, File saveSourceDir, String nameSuffix) throws JRException {
|
|
String unitName = getUnitName((JRReport)jasperDesign, (JRDataset)dataset, nameSuffix);
|
|
JRSourceCompileTask sourceTask = new JRSourceCompileTask(jasperDesign, dataset, expressionCollector, unitName);
|
|
JRCompilationSourceCode sourceCode = generateSourceCode(sourceTask);
|
|
File sourceFile = getSourceFile(saveSourceDir, unitName, sourceCode);
|
|
return new JRCompilationUnit(unitName, sourceCode, sourceFile, expressionCollector.getExpressions((JRDataset)dataset));
|
|
}
|
|
|
|
private JRCompilationUnit createCompileUnit(JasperDesign jasperDesign, JRDesignCrosstab crosstab, JRExpressionCollector expressionCollector, File saveSourceDir, String nameSuffix) throws JRException {
|
|
String unitName = getUnitName((JRReport)jasperDesign, (JRCrosstab)crosstab, expressionCollector, nameSuffix);
|
|
JRSourceCompileTask sourceTask = new JRSourceCompileTask(jasperDesign, crosstab, expressionCollector, unitName);
|
|
JRCompilationSourceCode sourceCode = generateSourceCode(sourceTask);
|
|
File sourceFile = getSourceFile(saveSourceDir, unitName, sourceCode);
|
|
return new JRCompilationUnit(unitName, sourceCode, sourceFile, expressionCollector.getExpressions((JRCrosstab)crosstab));
|
|
}
|
|
|
|
private File getSourceFile(File saveSourceDir, String unitName, JRCompilationSourceCode sourceCode) throws JRException {
|
|
File sourceFile = null;
|
|
if (saveSourceDir != null) {
|
|
String fileName = getSourceFileName(unitName);
|
|
sourceFile = new File(saveSourceDir, fileName);
|
|
JRSaver.saveClassSource(sourceCode.getCode(), sourceFile);
|
|
}
|
|
return sourceFile;
|
|
}
|
|
|
|
private void deleteSourceFiles(JRCompilationUnit[] units) {
|
|
for (int i = 0; i < units.length; i++)
|
|
units[i].getSourceFile().delete();
|
|
}
|
|
|
|
public JREvaluator loadEvaluator(JasperReport jasperReport) throws JRException {
|
|
return loadEvaluator(jasperReport, jasperReport.getMainDataset());
|
|
}
|
|
|
|
public JREvaluator loadEvaluator(JasperReport jasperReport, JRDataset dataset) throws JRException {
|
|
String unitName = getUnitName(jasperReport, dataset);
|
|
JRReportCompileData reportCompileData = (JRReportCompileData)jasperReport.getCompileData();
|
|
Serializable compileData = reportCompileData.getDatasetCompileData(dataset);
|
|
return loadEvaluator(compileData, unitName);
|
|
}
|
|
|
|
public JREvaluator loadEvaluator(JasperReport jasperReport, JRCrosstab crosstab) throws JRException {
|
|
String unitName = getUnitName(jasperReport, crosstab);
|
|
JRReportCompileData reportCompileData = (JRReportCompileData)jasperReport.getCompileData();
|
|
Serializable compileData = reportCompileData.getCrosstabCompileData(crosstab);
|
|
return loadEvaluator(compileData, unitName);
|
|
}
|
|
|
|
protected abstract JREvaluator loadEvaluator(Serializable paramSerializable, String paramString) throws JRException;
|
|
|
|
protected abstract void checkLanguage(String paramString) throws JRException;
|
|
|
|
protected abstract JRCompilationSourceCode generateSourceCode(JRSourceCompileTask paramJRSourceCompileTask) throws JRException;
|
|
|
|
protected abstract String compileUnits(JRCompilationUnit[] paramArrayOfJRCompilationUnit, String paramString, File paramFile) throws JRException;
|
|
|
|
protected abstract String getSourceFileName(String paramString);
|
|
}
|