1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21 package org.efaps.update.schema.program.jasperreport;
22
23 import groovy.lang.GroovyClassLoader;
24 import groovyjarjarasm.asm.ClassVisitor;
25 import groovyjarjarasm.asm.ClassWriter;
26
27 import java.io.ByteArrayInputStream;
28 import java.io.File;
29 import java.io.Serializable;
30 import java.io.UnsupportedEncodingException;
31 import java.util.HashMap;
32 import java.util.Map;
33
34 import net.sf.jasperreports.compilers.JRGroovyCompiler;
35 import net.sf.jasperreports.engine.DefaultJasperReportsContext;
36 import net.sf.jasperreports.engine.JRException;
37 import net.sf.jasperreports.engine.JasperReportsContext;
38 import net.sf.jasperreports.engine.design.JRCompilationUnit;
39
40 import org.codehaus.groovy.ast.ClassNode;
41 import org.codehaus.groovy.control.CompilationFailedException;
42 import org.codehaus.groovy.control.CompilationUnit;
43 import org.codehaus.groovy.control.CompilerConfiguration;
44 import org.codehaus.groovy.control.Phases;
45 import org.efaps.admin.program.esjp.EFapsClassLoader;
46
47
48
49
50
51
52
53
54
55 public class JasperGroovyCompiler
56 extends JRGroovyCompiler
57 {
58
59
60
61
62 public JasperGroovyCompiler()
63 {
64 this(DefaultJasperReportsContext.getInstance());
65 }
66
67
68
69
70 public JasperGroovyCompiler(final JasperReportsContext _jasperReportsContext)
71 {
72 super(_jasperReportsContext);
73 }
74
75
76
77
78
79
80
81
82
83
84
85 @Override
86 protected String compileUnits(final JRCompilationUnit[] _units,
87 final String _classpath,
88 final File _tempDirFile)
89 throws JRException
90 {
91 final CompilerConfiguration config = new CompilerConfiguration();
92 config.setClasspath(_classpath);
93 config.setVerbose(true);
94 final GroovyClassLoader loader = new GroovyClassLoader(EFapsClassLoader.getInstance(), config, true);
95 final CompilationUnit unit = new CompilationUnit(loader);
96
97 for (int i = 0; i < _units.length; i++) {
98 try {
99 unit.addSource("calculator_" + _units[i].getName(), new ByteArrayInputStream(_units[i].getSourceCode()
100 .getBytes("UTF-8")));
101 } catch (final UnsupportedEncodingException e) {
102 throw new JRException("Cannot add Source", e);
103 }
104 }
105
106 final ClassCollector collector = new ClassCollector();
107 unit.setClassgenCallback(collector);
108 try {
109 unit.compile(Phases.CLASS_GENERATION);
110 } catch (final CompilationFailedException e) {
111 throw new JRException("Errors were encountered when compiling report expressions class file:\n"
112 + e.toString());
113 }
114
115 if (collector.classes.size() < _units.length) {
116 throw new JRException("Too few groovy class were generated.");
117 } else if (collector.classCount > _units.length) {
118 throw new JRException("Too many groovy classes were generated.\n"
119 + "Please make sure that you don't use Groovy features such as closures "
120 + "that are not supported by this report compiler.\n");
121 }
122
123 for (int i = 0; i < _units.length; i++) {
124 _units[i].setCompileData((Serializable) collector.classes.get(_units[i].getName()));
125 }
126
127 return null;
128 }
129
130
131
132
133
134 private static class ClassCollector extends CompilationUnit.ClassgenCallback
135 {
136
137
138
139 private final Map<String, Object> classes = new HashMap<String, Object>();
140
141
142
143
144 private int classCount;
145
146
147
148
149
150
151
152
153 @Override
154 public void call(final ClassVisitor _writer,
155 final ClassNode _node)
156 {
157 this.classCount++;
158 final String name = _node.getName();
159 if (!this.classes.containsKey(name)) {
160 final byte[] bytes = ((ClassWriter) _writer).toByteArray();
161 this.classes.put(name, bytes);
162 }
163 }
164 }
165 }