1 /*
2 * JasperReports - Free Java Reporting Library.
3 * Copyright (C) 2001 - 2019 TIBCO Software Inc. All rights reserved.
4 * http://www.jaspersoft.com
5 *
6 * Unless you have purchased a commercial license agreement from Jaspersoft,
7 * the following license terms apply:
8 *
9 * This program is part of JasperReports.
10 *
11 * JasperReports is free software: you can redistribute it and/or modify
12 * it under the terms of the GNU Lesser General Public License as published by
13 * the Free Software Foundation, either version 3 of the License, or
14 * (at your option) any later version.
15 *
16 * JasperReports is distributed in the hope that it will be useful,
17 * but WITHOUT ANY WARRANTY; without even the implied warranty of
18 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19 * GNU Lesser General Public License for more details.
20 *
21 * You should have received a copy of the GNU Lesser General Public License
22 * along with JasperReports. If not, see <http://www.gnu.org/licenses/>.
23 */
24 package net.sf.jasperreports.engine;
25
26 import java.io.File;
27 import java.io.InputStream;
28 import java.io.OutputStream;
29 import java.lang.reflect.Constructor;
30 import java.lang.reflect.InvocationTargetException;
31 import java.util.Collection;
32
33 import net.sf.jasperreports.crosstabs.JRCrosstab;
34 import net.sf.jasperreports.engine.design.JRCompiler;
35 import net.sf.jasperreports.engine.design.JRJavacCompiler;
36 import net.sf.jasperreports.engine.design.JRJdk13Compiler;
37 import net.sf.jasperreports.engine.design.JRJdtCompiler;
38 import net.sf.jasperreports.engine.design.JRValidationFault;
39 import net.sf.jasperreports.engine.design.JRVerifier;
40 import net.sf.jasperreports.engine.design.JasperDesign;
41 import net.sf.jasperreports.engine.fill.JREvaluator;
42 import net.sf.jasperreports.engine.fill.JasperReportsContextAware;
43 import net.sf.jasperreports.engine.util.JRClassLoader;
44 import net.sf.jasperreports.engine.util.JRLoader;
45 import net.sf.jasperreports.engine.util.JRSaver;
46 import net.sf.jasperreports.engine.xml.JRXmlLoader;
47 import net.sf.jasperreports.engine.xml.JRXmlWriter;
48
49
50 /**
51 * Facade class for compiling report designs into the ready-to-fill form
52 * and for getting the XML representation of report design objects for
53 * storage or network transfer.
54 * <p>
55 * This class exposes all the library's report compilation functionality. It has
56 * various methods that allow the users to compile JRXML report templates found in files
57 * on disk or that come from input streams. It also lets people compile in-memory report
58 * templates by directly passing a
59 * {@link net.sf.jasperreports.engine.design.JasperDesign} object and receiving the
60 * corresponding {@link net.sf.jasperreports.engine.JasperReport} object.
61 * </p><p>
62 * Other utility methods include report template verification and JRXML report template
63 * generation for in-memory constructed
64 * {@link net.sf.jasperreports.engine.design.JasperDesign} class instances. These
65 * instances are especially useful in GUI tools that simplify report design work.
66 * </p><p>
67 * The facade class relies on the report template language to determine an appropriate report compiler.
68 * The report compilation facade first reads a configuration property called
69 * {@link net.sf.jasperreports.engine.design.JRCompiler#COMPILER_PREFIX net.sf.jasperreports.compiler.<language>} to determine whether a compiler
70 * implementation has been configured for the specific report language. If such a property
71 * is found, its value is used as compiler implementation class name and the facade
72 * instantiates a compiler object and delegates the report compilation to it. By default,
73 * JasperReports includes configuration properties that map the Groovy and JavaScript
74 * report compilers to the <code>groovy</code> and <code>javascript</code>
75 * report languages, respectively.
76 * </p><p>
77 * If the report uses Java as language and no specific compiler has been set for this
78 * language, the report compilation facade employs a built-in fall back mechanism that
79 * picks the best Java-based report compiler available in the environment in which the
80 * report compilation process takes place.
81 * </p><p>
82 * The facade first reads the
83 * configuration property called {@link net.sf.jasperreports.engine.design.JRCompiler#COMPILER_CLASS net.sf.jasperreports.compiler.class} to allow
84 * users to override its built-in compiler-detection logic by providing the name of the report
85 * compiler implementation to use directly.
86 * </p><p>
87 * If the property is not provided, the facade first tries to see if the JDT compiler from the
88 * Eclipse Foundation is available in the application's classpath. If it is, the
89 * {@link net.sf.jasperreports.engine.design.JRJdtCompiler} implementation is used.
90 * </p><p>
91 * If the JDT compiler is not available, the compilation facade then tries to locate the JDK
92 * 1.3-compatible Java compiler from Sun Microsystems. This is normally found in the
93 * <code>tools.jar</code> file that comes with the JDK installation.
94 * </p><p>
95 * If all these fail, the last thing the fall back mechanism does is to try to launch the
96 * <code>javac.exe</code> program from the command line in order to compile the temporarily
97 * generated Java source file on the fly.
98 * </p>
99 * <h3>Configuration Properties to Customize Report Compilation</h3>
100 * JasperReports offers various mechanisms for letting users
101 * customize its behavior. One of these mechanisms is a complete set of configuration
102 * properties. The following list contains all the configuration properties that customize
103 * report compilation.
104 * <dl>
105 * <dt>{@link net.sf.jasperreports.engine.design.JRCompiler#COMPILER_PREFIX net.sf.jasperreports.compiler.<language>}<dt>
106 * <dd>Such properties are used for indicating the name of the class that implements the
107 * {@link net.sf.jasperreports.engine.design.JRCompiler} interface to be instantiated by
108 * the engine for a specific report language
109 * when the default compilation is used through this facade class. The
110 * value for such a configuration property can be the name of one of the built-in
111 * implementations of this interface shipped with the library as listed previously, or the
112 * name of a custom-made implementing class.
113 * <br/>
114 * One can configure report compilers for custom report languages and override the default
115 * compiler mappings by setting JasperReports properties of the form
116 * {@link net.sf.jasperreports.engine.design.JRCompiler#COMPILER_PREFIX net.sf.jasperreports.compiler.<language>} to the desired compiler
117 * implementation class names. In particular, the mechanism that automatically chooses a
118 * Java report compiler can be superseded by explicitly setting the
119 * <code>net.sf.jasperreports.compiler.java</code> property to the name of one of the built-in
120 * Java compiler classes or of a custom compiler implementation class.
121 * <br/>
122 * Note that the classes implementing the {@link net.sf.jasperreports.engine.design.JRCompiler}
123 * interface can also be used directly in
124 * the programs without having to call them through this facade class.</dd>
125 * <dt>{@link net.sf.jasperreports.engine.xml.JRReportSaxParserFactory#COMPILER_XML_VALIDATION net.sf.jasperreports.compiler.xml.validation}<dt>
126 * <dd>The XML validation, which is on by default, can be turned off by setting this
127 * configuration property to
128 * false. When turned off, the XML parser no longer validates the supplied JRXML
129 * against its associated XSD. This might prove useful in some environments, although it is
130 * not recommended.</dd>
131 * <dt>{@link net.sf.jasperreports.engine.design.JRCompiler#COMPILER_CLASSPATH net.sf.jasperreports.compiler.classpath}<dt>
132 * <dd>This property
133 * supplies the classpath. JDK-based compilers require that the classpath be
134 * supplied as a parameter. They cannot use the current JVM classpath. The supplied
135 * classpath resolves class references inside the Java code they are compiling.
136 * <br/>
137 * This property is not used by the JDT-based report compiler, which simply uses the parent
138 * application's classpath during Java source file compilation.</dd>
139 * <dt>{@link net.sf.jasperreports.engine.design.JRCompiler#COMPILER_TEMP_DIR net.sf.jasperreports.compiler.temp.dir}<dt>
140 * <dd>The temporary location for the files generated on the fly is by default the current working
141 * directory. It can be changed by supplying a value to this
142 * configuration property. This is used by
143 * the JDT-based compiler only when it is requested that a copy of the on-the-fly generated
144 * Java class be kept for debugging purposes as specified by the next configuration
145 * property, because normally this report compiler does not work with files on disk.</dd>
146 * <dt>{@link net.sf.jasperreports.engine.design.JRCompiler#COMPILER_KEEP_JAVA_FILE net.sf.jasperreports.compiler.keep.java.file}<dt>
147 * <dd>Sometimes, for debugging purposes, it is useful to have the generated <code>*.java</code> file or
148 * generated script in order to fix compilation problems related to report expressions. By
149 * default, the engine deletes this file after report compilation, along with its corresponding
150 * <code>*.class</code> file. To keep it, however, set this configuration property to true.</dd>
151 * </dl>
152 * <h3>JDT Compiler-Specific Configuration Properties</h3>
153 * The JRJdtCompiler report compiler can use special JasperReports configuration
154 * properties to configure the underlying JDT Java compiler. This report compiler collects
155 * all the JasperReports configuration properties (the ones usually set in the
156 * jasperreports.properties file) that start with the <code>org.eclipse.jdt.core.</code> prefix
157 * and passes them to the JDT Java compiler when compiling the generated Java class to
158 * evaluate report expressions.
159 * <p>
160 * One of the uses of this mechanism is to instruct the JDT compiler to observe Java 1.5
161 * code compatibility. To do so, the following properties should be set:</p>
162 * <ul>
163 * <li><code>org.eclipse.jdt.core.compiler.source=1.5</code></li>
164 * <li><code>org.eclipse.jdt.core.compiler.compliance=1.5</code></li>
165 * <li><code>org.eclipse.jdt.core.compiler.codegen.TargetPlatform=1.5</code></li>
166 * </ul>
167 * @see net.sf.jasperreports.engine.JasperReport
168 * @see net.sf.jasperreports.engine.design.JasperDesign
169 * @see net.sf.jasperreports.engine.design.JRCompiler
170 * @see net.sf.jasperreports.engine.design.JRJdtCompiler
171 * @see net.sf.jasperreports.engine.design.JRVerifier
172 * @see net.sf.jasperreports.engine.xml.JRXmlLoader
173 * @see net.sf.jasperreports.engine.xml.JRXmlWriter
174 * @see net.sf.jasperreports.engine.util.JRLoader
175 * @see net.sf.jasperreports.engine.util.JRSaver
176 * @author Teodor Danciu (teodord@users.sourceforge.net)
177 */
178 public final class JasperCompileManager
179 {
180 public static final String EXCEPTION_MESSAGE_KEY_INSTANTIATE_REPORT_COMPILER_FAILURE = "engine.instantiate.report.compiler.failure";
181 public static final String EXCEPTION_MESSAGE_KEY_REPORT_COMPILER_CLASS_NOT_FOUND = "engine.report.compiler.class.not.found";
182 public static final String EXCEPTION_MESSAGE_KEY_REPORT_COMPILER_NOT_SET = "engine.report.compiler.not.set";
183
184 private JasperReportsContext jasperReportsContext;
185
186
187 /**
188 *
189 */
190 private JasperCompileManager(JasperReportsContext jasperReportsContext)
191 {
192 this.jasperReportsContext = jasperReportsContext;
193 }
194
195
196 /**
197 *
198 */
199 private static JasperCompileManager getDefaultInstance()
200 {
201 return new JasperCompileManager(DefaultJasperReportsContext.getInstance());
202 }
203
204
205 /**
206 *
207 */
208 public static JasperCompileManager getInstance(JasperReportsContext jasperReportsContext)
209 {
210 return new JasperCompileManager(jasperReportsContext);
211 }
212
213
214 /**
215 * Compiles the XML report design file specified by the parameter.
216 * The result of this operation is another file that will contain the serialized
217 * {@link net.sf.jasperreports.engine.JasperReport} object representing the compiled report design,
218 * having the same name as the report design as declared in the XML plus the <code>*.jasper</code> extension,
219 * located in the same directory as the XML source file.
220 *
221 * @param sourceFileName XML source file name
222 * @return resulting file name containing a serialized {@link net.sf.jasperreports.engine.JasperReport} object
223 */
224 public String compileToFile(String sourceFileName) throws JRException
225 {
226 File sourceFile = new File(sourceFileName);
227
228 JasperDesign jasperDesign = JRXmlLoader.load(sourceFileName);
229
230 File destFile = new File(sourceFile.getParent(), jasperDesign.getName() + ".jasper");
231 String destFileName = destFile.toString();
232
233 compileToFile(jasperDesign, destFileName);
234
235 return destFileName;
236 }
237
238
239 /**
240 * Compiles the XML report design file received as the first parameter, placing the result
241 * in the file specified by the second parameter.
242 * The resulting file will contain a serialized instance of a
243 * {@link net.sf.jasperreports.engine.JasperReport} object representing
244 * the compiled report design.
245 *
246 * @param sourceFileName XML source file name
247 * @param destFileName file name to place the result into
248 */
249 public void compileToFile(
250 String sourceFileName,
251 String destFileName
252 ) throws JRException
253 {
254 JasperDesign jasperDesign = JRXmlLoader.load(sourceFileName);
255
256 compileToFile(jasperDesign, destFileName);
257 }
258
259
260 /**
261 * Compiles the report design object received as the first parameter, placing the result
262 * in the file specified by the second parameter.
263 * The resulting file will contain a serialized instance of a
264 * {@link net.sf.jasperreports.engine.JasperReport} object representing the compiled report design.
265 *
266 * @param jasperDesign source report design object
267 * @param destFileName file name to place the compiled report design into
268 */
269 public void compileToFile(
270 JasperDesign jasperDesign,
271 String destFileName
272 ) throws JRException
273 {
274 JasperReport jasperReport = compile(jasperDesign);
275
276 JRSaver.saveObject(jasperReport, destFileName);
277 }
278
279
280 /**
281 * Compiles the XML report design file received as parameter, and returns
282 * the compiled report design object.
283 *
284 * @param sourceFileName XML source file name
285 * @return compiled report design object
286 */
287 public JasperReport compile(String sourceFileName) throws JRException
288 {
289 JasperDesign jasperDesign = JRXmlLoader.load(sourceFileName);
290
291 return compile(jasperDesign);
292 }
293
294
295 /**
296 * Compiles the XML representation of the report design read from the supplied input stream and
297 * writes the generated compiled report design object to the output stream specified
298 * by the second parameter.
299 *
300 * @param inputStream XML source input stream
301 * @param outputStream output stream to write the compiled report design to
302 */
303 public void compileToStream(
304 InputStream inputStream,
305 OutputStream outputStream
306 ) throws JRException
307 {
308 JasperDesign jasperDesign = JRXmlLoader.load(inputStream);
309
310 compileToStream(jasperDesign, outputStream);
311 }
312
313
314 /**
315 * Compiles the report design object represented by the first parameter and
316 * writes the generated compiled report design object to the output stream specified
317 * by the second parameter.
318 *
319 * @param jasperDesign source report design object
320 * @param outputStream output stream to write the compiled report design to
321 */
322 public void compileToStream(
323 JasperDesign jasperDesign,
324 OutputStream outputStream
325 ) throws JRException
326 {
327 JasperReport jasperReport = compile(jasperDesign);
328
329 JRSaver.saveObject(jasperReport, outputStream);
330 }
331
332
333 /**
334 * Compiles the serialized report design object read from the supplied input stream and
335 * returns the generated compiled report design object.
336 *
337 * @param inputStream XML source input stream
338 * @return compiled report design object
339 */
340 public JasperReport compile(InputStream inputStream) throws JRException
341 {
342 JasperDesign jasperDesign = JRXmlLoader.load(inputStream);
343
344 return compile(jasperDesign);
345 }
346
347
348 /**
349 * Compiles the report design object received as parameter and
350 * returns the generated compiled report design object.
351 *
352 * @param jasperDesign source report design object
353 * @return compiled report design object
354 * @see net.sf.jasperreports.engine.design.JRCompiler
355 */
356 public JasperReport compile(JasperDesign jasperDesign) throws JRException
357 {
358 return getCompiler(jasperDesign).compileReport(jasperDesign);
359 }
360
361
362 /**
363 * Verifies the validity and consistency of the report design object.
364 * Returns a collection of {@link JRValidationFault errors}, if problems are found in the report design.
365 *
366 * @param jasperDesign report design object to verify
367 * @return collection of {@link JRValidationFault JRValidationFault} if problems are found
368 * @see net.sf.jasperreports.engine.design.JRVerifier
369 */
370 public Collection<JRValidationFault> verify(JasperDesign jasperDesign)
371 {
372 return JRVerifier.verifyDesign(jasperDesign);
373 }
374
375
376 /**
377 *
378 */
379 public JREvaluator getEvaluator(JasperReport jasperReport, JRDataset dataset) throws JRException
380 {
381 JRCompiler compiler = getCompiler(jasperReport);
382 JREvaluator evaluator = compiler.loadEvaluator(jasperReport, dataset);
383 initialize(evaluator);
384 return evaluator;
385 }
386
387
388 /**
389 *
390 */
391 public JREvaluator getEvaluator(JasperReport jasperReport, JRCrosstab crosstab) throws JRException
392 {
393 JRCompiler compiler = getCompiler(jasperReport);
394 JREvaluator evaluator = compiler.loadEvaluator(jasperReport, crosstab);
395 initialize(evaluator);
396 return evaluator;
397 }
398
399
400 /**
401 *
402 */
403 public JREvaluator getEvaluator(JasperReport jasperReport) throws JRException
404 {
405 return getEvaluator(jasperReport, jasperReport.getMainDataset());
406 }
407
408 protected void initialize(JREvaluator evaluator)
409 {
410 if (evaluator instanceof JasperReportsContextAware)
411 {
412 ((JasperReportsContextAware) evaluator).setJasperReportsContext(jasperReportsContext);
413 }
414 }
415
416
417 /**
418 * Generates the XML representation of the report design loaded from the specified filename.
419 * The result of this operation is an "UTF-8" encoded XML file having the same name as
420 * the report design, plus the <code>*.jasper.jrxml</code> extension, located in the same directory as
421 * the source file.
422 *
423 * @param sourceFileName source file name containing the report design object
424 * @return XML representation of the report design
425 */
426 public String writeToXmlFile(
427 String sourceFileName
428 ) throws JRException
429 {
430 File sourceFile = new File(sourceFileName);
431
432 /* We need the report name. */
433 JRReport report = (JRReport)JRLoader.loadObject(sourceFile);
434
435 File destFile = new File(sourceFile.getParent(), report.getName() + ".jasper.jrxml");
436 String destFileName = destFile.toString();
437
438 writeToXmlFile(report, destFileName);
439
440 return destFileName;
441 }
442
443
444 /**
445 * Generates the XML representation of the report design loaded from the first file parameter
446 * and place it in the file specified by the second parameter. The result is "UTF-8" encoded.
447 *
448 * @param sourceFileName source file name containing the report design object
449 * @param destFileName output file name to write the XML report design representation to
450 */
451 public void writeToXmlFile(
452 String sourceFileName,
453 String destFileName
454 ) throws JRException
455 {
456 JRReport report = (JRReport)JRLoader.loadObjectFromFile(sourceFileName);
457
458 writeToXmlFile(report, destFileName);
459 }
460
461
462 /**
463 * Generates the XML representation of the report design supplied as the first parameter
464 * and place it in the file specified by the second parameter. The result is "UTF-8" encoded.
465 *
466 * @param report source report design object
467 * @param destFileName output file name to write the XML report design representation to
468 * @see net.sf.jasperreports.engine.xml.JRXmlWriter
469 */
470 public void writeToXmlFile(
471 JRReport report,
472 String destFileName
473 ) throws JRException
474 {
475 new JRXmlWriter(jasperReportsContext).write(
476 report,
477 destFileName,
478 "UTF-8"
479 );
480 }
481
482
483 /**
484 * Generates the XML representation of the serialized report design object read from the supplied
485 * input stream abd writes it to the specified output stream, using the "UTF-8" encoding.
486 *
487 * @param inputStream source input stream to read the report design object from
488 * @param outputStream output stream to write the XML report design representation to
489 */
490 public void writeToXmlStream(
491 InputStream inputStream,
492 OutputStream outputStream
493 ) throws JRException
494 {
495 JRReport report = (JRReport)JRLoader.loadObject(inputStream);
496
497 writeToXmlStream(report, outputStream);
498 }
499
500
501 /**
502 * Generates the XML representation of the report design object supplied as parameter
503 * and writes it to the specified output stream, using the "UTF-8" encoding.
504 *
505 * @param report source report design object
506 * @param outputStream output stream to write the XML report design representation to
507 * @see net.sf.jasperreports.engine.xml.JRXmlWriter
508 */
509 public void writeToXmlStream(
510 JRReport report,
511 OutputStream outputStream
512 ) throws JRException
513 {
514 new JRXmlWriter(jasperReportsContext).write(
515 report,
516 outputStream,
517 "UTF-8"
518 );
519 }
520
521
522 /**
523 * Generates the XML representation of the report design object supplied as parameter
524 * using the "UTF-8" enconding.
525 *
526 * @param report source report design object
527 * @return XML representation of the report design
528 * @see net.sf.jasperreports.engine.xml.JRXmlWriter
529 */
530 public String writeToXml(JRReport report)
531 {
532 return new JRXmlWriter(jasperReportsContext).write(report, "UTF-8");
533 }
534
535
536
537
538 /**
539 * @see #compileToFile(String)
540 */
541 public static String compileReportToFile(String sourceFileName) throws JRException
542 {
543 return getDefaultInstance().compileToFile(sourceFileName);
544 }
545
546
547 /**
548 * @see #compileToFile(String, String)
549 */
550 public static void compileReportToFile(
551 String sourceFileName,
552 String destFileName
553 ) throws JRException
554 {
555 getDefaultInstance().compileToFile(sourceFileName, destFileName);
556 }
557
558
559 /**
560 * @see #compileToFile(JasperDesign, String)
561 */
562 public static void compileReportToFile(
563 JasperDesign jasperDesign,
564 String destFileName
565 ) throws JRException
566 {
567 getDefaultInstance().compileToFile(jasperDesign, destFileName);
568 }
569
570
571 /**
572 * @see #compile(String)
573 */
574 public static JasperReport compileReport(String sourceFileName) throws JRException
575 {
576 return getDefaultInstance().compile(sourceFileName);
577 }
578
579
580 /**
581 * @see #compileToStream(InputStream, OutputStream)
582 */
583 public static void compileReportToStream(
584 InputStream inputStream,
585 OutputStream outputStream
586 ) throws JRException
587 {
588 getDefaultInstance().compileToStream(inputStream, outputStream);
589 }
590
591
592 /**
593 * @see #compileToStream(JasperDesign, OutputStream)
594 */
595 public static void compileReportToStream(
596 JasperDesign jasperDesign,
597 OutputStream outputStream
598 ) throws JRException
599 {
600 getDefaultInstance().compileToStream(jasperDesign, outputStream);
601 }
602
603
604 /**
605 * @see #compile(InputStream)
606 */
607 public static JasperReport compileReport(InputStream inputStream) throws JRException
608 {
609 return getDefaultInstance().compile(inputStream);
610 }
611
612
613 /**
614 * @see #compile(JasperDesign)
615 */
616 public static JasperReport compileReport(JasperDesign jasperDesign) throws JRException
617 {
618 return getDefaultInstance().compile(jasperDesign);
619 }
620
621
622 /**
623 * @see #verify(JasperDesign)
624 */
625 public static Collection<JRValidationFault> verifyDesign(JasperDesign jasperDesign)
626 {
627 return getDefaultInstance().verify(jasperDesign);
628 }
629
630
631 /**
632 * @see #getEvaluator(JasperReport, JRDataset)
633 */
634 public static JREvaluator loadEvaluator(JasperReport jasperReport, JRDataset dataset) throws JRException
635 {
636 return getDefaultInstance().getEvaluator(jasperReport, dataset);
637 }
638
639
640 /**
641 * @see #getEvaluator(JasperReport, JRCrosstab)
642 */
643 public static JREvaluator loadEvaluator(JasperReport jasperReport, JRCrosstab crosstab) throws JRException
644 {
645 return getDefaultInstance().getEvaluator(jasperReport, crosstab);
646 }
647
648
649 /**
650 * @see #getEvaluator(JasperReport)
651 */
652 public static JREvaluator loadEvaluator(JasperReport jasperReport) throws JRException
653 {
654 return getDefaultInstance().getEvaluator(jasperReport);
655 }
656
657
658 /**
659 * @see #writeToXmlFile(String)
660 */
661 public static String writeReportToXmlFile(
662 String sourceFileName
663 ) throws JRException
664 {
665 return getDefaultInstance().writeToXmlFile(sourceFileName);
666 }
667
668
669 /**
670 * @see #writeToXmlFile(String, String)
671 */
672 public static void writeReportToXmlFile(
673 String sourceFileName,
674 String destFileName
675 ) throws JRException
676 {
677 getDefaultInstance().writeToXmlFile(
678 sourceFileName,
679 destFileName
680 );
681 }
682
683
684 /**
685 * @see #writeToXmlFile(JRReport, String)
686 */
687 public static void writeReportToXmlFile(
688 JRReport report,
689 String destFileName
690 ) throws JRException
691 {
692 getDefaultInstance().writeToXmlFile(report, destFileName);
693 }
694
695
696 /**
697 * @see #writeToXmlStream(InputStream, OutputStream)
698 */
699 public static void writeReportToXmlStream(
700 InputStream inputStream,
701 OutputStream outputStream
702 ) throws JRException
703 {
704 getDefaultInstance().writeToXmlStream(inputStream, outputStream);
705 }
706
707
708 /**
709 * @see #writeToXmlStream(JRReport, OutputStream)
710 */
711 public static void writeReportToXmlStream(
712 JRReport report,
713 OutputStream outputStream
714 ) throws JRException
715 {
716 getDefaultInstance().writeToXmlStream(report, outputStream);
717 }
718
719
720 /**
721 * @see #writeToXml(JRReport)
722 */
723 public static String writeReportToXml(JRReport report)
724 {
725 return getDefaultInstance().writeToXml(report);
726 }
727
728
729 /**
730 *
731 */
732 private JRCompiler getJavaCompiler()
733 {
734 JRCompiler compiler = null;
735
736 try
737 {
738 JRClassLoader.loadClassForRealName("org.eclipse.jdt.internal.compiler.Compiler");
739 compiler = new JRJdtCompiler(jasperReportsContext);
740 }
741 catch (Exception e)
742 {
743 }
744
745 if (compiler == null)
746 {
747 try
748 {
749 JRClassLoader.loadClassForRealName("com.sun.tools.javac.Main");
750 compiler = new JRJdk13Compiler(jasperReportsContext);
751 }
752 catch (Exception e)
753 {
754 }
755 }
756
757 if (compiler == null)
758 {
759 compiler = new JRJavacCompiler(jasperReportsContext);
760 }
761
762 return compiler;
763 }
764
765
766 /**
767 *
768 */
769 private JRCompiler getCompiler(JasperReport jasperReport) throws JRException
770 {
771 JRCompiler compiler = null;
772
773 String compilerClassName = jasperReport.getCompilerClass();
774
775 Class<? extends JRCompiler> compilerClass = null;
776
777 ClassLoader classLoader = Thread.currentThread().getContextClassLoader();
778 if (classLoader != null)
779 {
780 try
781 {
782 @SuppressWarnings("unchecked")
783 Class<? extends JRCompiler> tmpCompilerClass = (Class<? extends JRCompiler>)classLoader.loadClass(compilerClassName);
784 compilerClass = tmpCompilerClass;
785 }
786 catch(ClassNotFoundException e)
787 {
788 }
789 }
790
791 if (compilerClass == null)
792 {
793 classLoader = JasperCompileManager.class.getClassLoader();
794 try
795 {
796 if (classLoader == null)
797 {
798 @SuppressWarnings("unchecked")
799 Class<? extends JRCompiler> tmpCompilerClass = (Class<? extends JRCompiler>)Class.forName(compilerClassName);
800 compilerClass = tmpCompilerClass;
801 }
802 else
803 {
804 @SuppressWarnings("unchecked")
805 Class<? extends JRCompiler> tmpCompilerClass = (Class<? extends JRCompiler>)classLoader.loadClass(compilerClassName);
806 compilerClass = tmpCompilerClass;
807 }
808 }
809 catch(ClassNotFoundException e)
810 {
811 throw
812 new JRException(
813 EXCEPTION_MESSAGE_KEY_REPORT_COMPILER_CLASS_NOT_FOUND,
814 new Object[] {compilerClassName},
815 e
816 );
817 }
818 }
819
820
821 try
822 {
823 Constructor<? extends JRCompiler> constructor = compilerClass.getConstructor(JasperReportsContext.class);//FIXMECONTEXT check all constructors like that
824 compiler = constructor.newInstance(jasperReportsContext);
825 }
826 catch (Exception e)
827 {
828 throw
829 new JRException(
830 EXCEPTION_MESSAGE_KEY_INSTANTIATE_REPORT_COMPILER_FAILURE,
831 new Object[] {compilerClassName},
832 e);
833 }
834 return compiler;
835 }
836
837
838
839
840 /**
841 *
842 */
843 private JRCompiler getCompiler(JasperDesign jasperDesign) throws JRException
844 {
845 JRCompiler compiler = null;
846
847 String compilerClassName = getCompilerClassProperty();
848 if (compilerClassName == null || compilerClassName.trim().length() == 0)
849 {
850 String language = jasperDesign.getLanguage();
851 compilerClassName = JRPropertiesUtil.getInstance(jasperReportsContext).getProperty(JRCompiler.COMPILER_PREFIX + language);
852 if (compilerClassName == null || compilerClassName.trim().length() == 0)
853 {
854 if (JRReport.LANGUAGE_JAVA.equals(language))
855 {
856 return getJavaCompiler();
857 }
858 else
859 {
860 throw
861 new JRException(
862 EXCEPTION_MESSAGE_KEY_REPORT_COMPILER_NOT_SET,
863 new Object[]{language});
864 }
865 }
866 }
867
868 try
869 {
870 Class<?> clazz = JRClassLoader.loadClassForName(compilerClassName);
871
872 Constructor<?> contextConstructor;
873 try
874 {
875 contextConstructor = clazz.getConstructor(JasperReportsContext.class);
876 }
877 catch (NoSuchMethodException e)
878 {
879 // no context constructor
880 contextConstructor = null;
881 }
882
883 if (contextConstructor == null)
884 {
885 // assuming default constructor
886 compiler = (JRCompiler) clazz.getDeclaredConstructor().newInstance();
887 }
888 else
889 {
890 compiler = (JRCompiler) contextConstructor.newInstance(jasperReportsContext);
891 }
892 }
893 catch (ClassNotFoundException | NoSuchMethodException | InvocationTargetException
894 | IllegalAccessException | InstantiationException e)
895 {
896 throw new JRException(
897 EXCEPTION_MESSAGE_KEY_INSTANTIATE_REPORT_COMPILER_FAILURE,
898 new Object[] {compilerClassName},
899 e);
900 }
901
902 return compiler;
903 }
904
905
906 /**
907 *
908 */
909 @SuppressWarnings("deprecation")
910 private String getCompilerClassProperty()
911 {
912 return JRPropertiesUtil.getInstance(jasperReportsContext).getProperty(JRCompiler.COMPILER_CLASS);
913 }
914 }
915