1 28 package net.sf.jasperreports.engine.design; 29 30 import java.io.File ; 31 import java.io.Serializable ; 32 import java.util.Collection ; 33 import java.util.Iterator ; 34 import java.util.List ; 35 import java.util.ListIterator ; 36 import java.util.Random ; 37 38 import net.sf.jasperreports.crosstabs.JRCrosstab; 39 import net.sf.jasperreports.crosstabs.design.JRDesignCrosstab; 40 import net.sf.jasperreports.engine.JRDataset; 41 import net.sf.jasperreports.engine.JRException; 42 import net.sf.jasperreports.engine.JRExpressionCollector; 43 import net.sf.jasperreports.engine.JRReport; 44 import net.sf.jasperreports.engine.JRRuntimeException; 45 import net.sf.jasperreports.engine.JasperReport; 46 import net.sf.jasperreports.engine.fill.JREvaluator; 47 import net.sf.jasperreports.engine.util.JRProperties; 48 import net.sf.jasperreports.engine.util.JRSaver; 49 import net.sf.jasperreports.engine.util.JRStringUtil; 50 51 57 public abstract class JRAbstractCompiler implements JRCompiler 58 { 59 private static final int NAME_SUFFIX_RANDOM_MAX = 1000000; 60 private static final Random random = new Random (); 61 62 private final boolean needsSourceFiles; 63 64 71 protected JRAbstractCompiler(boolean needsSourceFiles) 72 { 73 this.needsSourceFiles = needsSourceFiles; 74 } 75 76 77 84 public static String getUnitName(JasperReport report, JRDataset dataset) 85 { 86 return getUnitName(report, dataset, report.getCompileNameSuffix()); 87 } 88 89 protected static String getUnitName(JRReport report, JRDataset dataset, String nameSuffix) 90 { 91 String className; 92 if (dataset.isMainDataset()) 93 { 94 className = report.getName(); 95 } 96 else 97 { 98 className = report.getName() + "_" + dataset.getName(); 99 } 100 101 className = JRStringUtil.getLiteral(className) + nameSuffix; 102 103 return className; 104 } 105 106 113 public static String getUnitName(JasperReport report, JRCrosstab crosstab) 114 { 115 return getUnitName(report, crosstab.getId(), report.getCompileNameSuffix()); 116 } 117 118 119 protected static String getUnitName(JRReport report, JRCrosstab crosstab, JRExpressionCollector expressionCollector, String nameSuffix) 120 { 121 Integer crosstabId = expressionCollector.getCrosstabId(crosstab); 122 if (crosstabId == null) 123 { 124 throw new JRRuntimeException("Crosstab ID not found."); 125 } 126 127 return getUnitName(report, crosstabId.intValue(), nameSuffix); 128 } 129 130 protected static String getUnitName(JRReport report, int crosstabId, String nameSuffix) 131 { 132 return JRStringUtil.getLiteral(report.getName()) + "_CROSSTAB" + crosstabId + nameSuffix; 133 } 134 135 public final JasperReport compileReport(JasperDesign jasperDesign) throws JRException 136 { 137 checkLanguage(jasperDesign.getLanguage()); 139 140 JRExpressionCollector expressionCollector = JRExpressionCollector.collector(jasperDesign); 142 143 verifyDesign(jasperDesign, expressionCollector); 145 146 String nameSuffix = createNameSuffix(); 147 148 boolean isKeepJavaFile = JRProperties.getBooleanProperty(JRProperties.COMPILER_KEEP_JAVA_FILE); 150 File tempDirFile = null; 151 if (isKeepJavaFile || needsSourceFiles) 152 { 153 String tempDirStr = JRProperties.getProperty(JRProperties.COMPILER_TEMP_DIR); 154 155 tempDirFile = new File (tempDirStr); 156 if (!tempDirFile.exists() || !tempDirFile.isDirectory()) 157 { 158 throw new JRException("Temporary directory not found : " + tempDirStr); 159 } 160 } 161 162 List datasets = jasperDesign.getDatasetsList(); 163 List crosstabs = jasperDesign.getCrosstabs(); 164 165 JRCompilationUnit[] units = new JRCompilationUnit[datasets.size() + crosstabs.size() + 1]; 166 167 units[0] = createCompileUnit(jasperDesign, jasperDesign.getMainDesignDataset(), expressionCollector, tempDirFile, nameSuffix); 169 170 int sourcesCount = 1; 171 for (Iterator it = datasets.iterator(); it.hasNext(); ++sourcesCount) 172 { 173 JRDesignDataset dataset = (JRDesignDataset) it.next(); 174 units[sourcesCount] = createCompileUnit(jasperDesign, dataset, expressionCollector, tempDirFile, nameSuffix); 176 } 177 178 for (Iterator it = crosstabs.iterator(); it.hasNext(); ++sourcesCount) 179 { 180 JRDesignCrosstab crosstab = (JRDesignCrosstab) it.next(); 181 units[sourcesCount] = createCompileUnit(jasperDesign, crosstab, expressionCollector, tempDirFile, nameSuffix); 183 } 184 185 String classpath = JRProperties.getProperty(JRProperties.COMPILER_CLASSPATH); 186 187 try 188 { 189 String compileErrors = compileUnits(units, classpath, tempDirFile); 191 if (compileErrors != null) 192 { 193 throw new JRException("Errors were encountered when compiling report expressions class file:\n" + compileErrors); 194 } 195 196 JRReportCompileData reportCompileData = new JRReportCompileData(); 198 reportCompileData.setMainDatasetCompileData(units[0].getCompileData()); 199 200 for (ListIterator it = datasets.listIterator(); it.hasNext();) 201 { 202 JRDesignDataset dataset = (JRDesignDataset) it.next(); 203 reportCompileData.setDatasetCompileData(dataset, units[it.nextIndex()].getCompileData()); 204 } 205 206 for (ListIterator it = crosstabs.listIterator(); it.hasNext();) 207 { 208 JRDesignCrosstab crosstab = (JRDesignCrosstab) it.next(); 209 Integer crosstabId = expressionCollector.getCrosstabId(crosstab); 210 reportCompileData.setCrosstabCompileData(crosstabId.intValue(), units[datasets.size() + it.nextIndex()].getCompileData()); 211 } 212 213 JasperReport jasperReport = 215 new JasperReport( 216 jasperDesign, 217 getCompilerClass(), 218 reportCompileData, 219 expressionCollector, 220 nameSuffix 221 ); 222 223 return jasperReport; 224 } 225 catch (JRException e) 226 { 227 throw e; 228 } 229 catch (Exception e) 230 { 231 throw new JRException("Error compiling report design.", e); 232 } 233 finally 234 { 235 if (needsSourceFiles && !isKeepJavaFile) 236 { 237 deleteSourceFiles(units); 238 } 239 } 240 } 241 242 243 private static String createNameSuffix() 244 { 245 return "_" + System.currentTimeMillis() + "_" + random.nextInt(NAME_SUFFIX_RANDOM_MAX); 246 } 247 248 249 protected String getCompilerClass() 250 { 251 return getClass().getName(); 252 } 253 254 255 private void verifyDesign(JasperDesign jasperDesign, JRExpressionCollector expressionCollector) throws JRException 256 { 257 Collection brokenRules = JRVerifier.verifyDesign(jasperDesign, expressionCollector); 258 if (brokenRules != null && brokenRules.size() > 0) 259 { 260 StringBuffer sbuffer = new StringBuffer (); 261 sbuffer.append("Report design not valid : "); 262 int i = 1; 263 for(Iterator it = brokenRules.iterator(); it.hasNext(); i++) 264 { 265 sbuffer.append("\n\t " + i + ". " + (String )it.next()); 266 } 267 throw new JRException(sbuffer.toString()); 268 } 269 } 270 271 private JRCompilationUnit createCompileUnit(JasperDesign jasperDesign, JRDesignDataset dataset, JRExpressionCollector expressionCollector, File saveSourceDir, String nameSuffix) throws JRException 272 { 273 String unitName = JRAbstractCompiler.getUnitName(jasperDesign, dataset, nameSuffix); 274 275 JRSourceCompileTask sourceTask = new JRSourceCompileTask(jasperDesign, dataset, expressionCollector, unitName); 276 String sourceCode = generateSourceCode(sourceTask); 277 278 File sourceFile = getSourceFile(saveSourceDir, unitName, sourceCode); 279 280 return new JRCompilationUnit(unitName, sourceCode, sourceFile, expressionCollector.getExpressions(dataset)); 281 } 282 283 private JRCompilationUnit createCompileUnit(JasperDesign jasperDesign, JRDesignCrosstab crosstab, JRExpressionCollector expressionCollector, File saveSourceDir, String nameSuffix) throws JRException 284 { 285 String unitName = JRAbstractCompiler.getUnitName(jasperDesign, crosstab, expressionCollector, nameSuffix); 286 287 JRSourceCompileTask sourceTask = new JRSourceCompileTask(jasperDesign, crosstab, expressionCollector, unitName); 288 String sourceCode = generateSourceCode(sourceTask); 289 290 File sourceFile = getSourceFile(saveSourceDir, unitName, sourceCode); 291 292 return new JRCompilationUnit(unitName, sourceCode, sourceFile, expressionCollector.getExpressions(crosstab)); 293 } 294 295 296 private File getSourceFile(File saveSourceDir, String unitName, String sourceCode) throws JRException 297 { 298 File sourceFile = null; 299 if (saveSourceDir != null) 300 { 301 String fileName = getSourceFileName(unitName); 302 sourceFile = new File (saveSourceDir, fileName); 303 304 JRSaver.saveClassSource(sourceCode, sourceFile); 305 } 306 return sourceFile; 307 } 308 309 private void deleteSourceFiles(JRCompilationUnit[] units) 310 { 311 for (int i = 0; i < units.length; i++) 312 { 313 units[i].getSourceFile().delete(); 314 } 315 } 316 317 public JREvaluator loadEvaluator(JasperReport jasperReport) throws JRException 318 { 319 return loadEvaluator(jasperReport, jasperReport.getMainDataset()); 320 } 321 322 public JREvaluator loadEvaluator(JasperReport jasperReport, JRDataset dataset) throws JRException 323 { 324 String unitName = JRAbstractCompiler.getUnitName(jasperReport, dataset); 325 JRReportCompileData reportCompileData = (JRReportCompileData) jasperReport.getCompileData(); 326 Serializable compileData = reportCompileData.getDatasetCompileData(dataset); 327 return loadEvaluator(compileData, unitName); 328 } 329 330 public JREvaluator loadEvaluator(JasperReport jasperReport, JRCrosstab crosstab) throws JRException 331 { 332 String unitName = JRAbstractCompiler.getUnitName(jasperReport, crosstab); 333 JRReportCompileData reportCompileData = (JRReportCompileData) jasperReport.getCompileData(); 334 Serializable compileData = reportCompileData.getCrosstabCompileData(crosstab); 335 return loadEvaluator(compileData, unitName); 336 } 337 338 339 347 protected abstract JREvaluator loadEvaluator(Serializable compileData, String unitName) throws JRException; 348 349 350 356 protected abstract void checkLanguage(String language) throws JRException; 357 358 359 366 protected abstract String generateSourceCode(JRSourceCompileTask sourceTask) throws JRException; 367 368 369 381 protected abstract String compileUnits(JRCompilationUnit[] units, String classpath, File tempDirFile) throws JRException; 382 383 384 394 protected abstract String getSourceFileName(String unitName); 395 } 396 | Popular Tags |