1
17 package gate.util.compilers;
18
19 import java.io.*;
20 import java.util.*;
21
22 import org.eclipse.jdt.core.compiler.IProblem;
23 import org.eclipse.jdt.internal.compiler.ClassFile;
24 import org.eclipse.jdt.internal.compiler.CompilationResult;
25 import org.eclipse.jdt.internal.compiler.Compiler;
26 import org.eclipse.jdt.internal.compiler.DefaultErrorHandlingPolicies;
27 import org.eclipse.jdt.internal.compiler.ICompilerRequestor;
28 import org.eclipse.jdt.internal.compiler.IErrorHandlingPolicy;
29 import org.eclipse.jdt.internal.compiler.IProblemFactory;
30 import org.eclipse.jdt.internal.compiler.classfmt.ClassFileReader;
31 import org.eclipse.jdt.internal.compiler.env.ICompilationUnit;
32 import org.eclipse.jdt.internal.compiler.env.INameEnvironment;
33 import org.eclipse.jdt.internal.compiler.env.NameEnvironmentAnswer;
34 import org.eclipse.jdt.internal.compiler.impl.CompilerOptions;
35 import org.eclipse.jdt.internal.compiler.problem.DefaultProblemFactory;
36
37 import gate.util.*;
38 import gate.Gate;
39 import gate.GateConstants;
40 import gate.creole.ExecutionException;
41
42
54 public class Eclipse extends gate.util.Javac {
55
56
65 public void compile(final Map sources) throws GateException {
66 if(classLoader == null) classLoader = Gate.getClassLoader();
67
68 final Map problems = new HashMap();
70
71 class CompilationUnit implements ICompilationUnit {
75 String className;
76
77 CompilationUnit(String className) {
78 this.className = className;
79 }
80
81 public char[] getFileName() {
82 return className.toCharArray();
83 }
84
85 public char[] getContents() {
86 return ((String)sources.get(className)).toCharArray();
87 }
88
89
93 public char[] getMainTypeName() {
94 int dot = className.lastIndexOf('.');
95 if (dot > 0) {
96 return className.substring(dot + 1).toCharArray();
97 }
98 return className.toCharArray();
99 }
100
101
106 public char[][] getPackageName() {
107 StringTokenizer izer =
108 new StringTokenizer(className, ".");
109 char[][] result = new char[izer.countTokens()-1][];
110 for (int i = 0; i < result.length; i++) {
111 String tok = izer.nextToken();
112 result[i] = tok.toCharArray();
113 }
114 return result;
115 }
116 }
117
118 final INameEnvironment env = new INameEnvironment() {
124
125
130 public NameEnvironmentAnswer findType(char[][] compoundTypeName) {
131 String result = "";
132 String sep = "";
133 for (int i = 0; i < compoundTypeName.length; i++) {
134 result += sep;
135 result += new String(compoundTypeName[i]);
136 sep = ".";
137 }
138 return findType(result);
139 }
140
141
146 public NameEnvironmentAnswer findType(char[] typeName,
147 char[][] packageName) {
148 String result = "";
149 String sep = "";
150 for (int i = 0; i < packageName.length; i++) {
151 result += sep;
152 result += new String(packageName[i]);
153 sep = ".";
154 }
155 result += sep;
156 result += new String(typeName);
157 return findType(result);
158 }
159
160
163 private NameEnvironmentAnswer findType(String className) {
164 try {
165 if (sources.containsKey(className)) {
166 ICompilationUnit compilationUnit = new CompilationUnit(className);
169 return new NameEnvironmentAnswer(compilationUnit);
170 }
171
172 String resourceName = className.replace('.', '/') + ".class";
174 InputStream is = classLoader.getResourceAsStream(resourceName);
175 if (is != null) {
176 byte[] classBytes;
177 byte[] buf = new byte[8192];
178 ByteArrayOutputStream baos =
179 new ByteArrayOutputStream(buf.length);
180 int count;
181 while ((count = is.read(buf, 0, buf.length)) > 0) {
182 baos.write(buf, 0, count);
183 }
184 baos.flush();
185 classBytes = baos.toByteArray();
186 char[] fileName = className.toCharArray();
187 ClassFileReader classFileReader =
188 new ClassFileReader(classBytes, fileName,
189 true);
190 return new NameEnvironmentAnswer(classFileReader);
191 }
192 }
193 catch (IOException exc) {
194 System.err.println("Compilation error");
195 exc.printStackTrace();
196 }
197 catch (org.eclipse.jdt.internal.compiler
198 .classfmt.ClassFormatException exc) {
199 System.err.println("Compilation error");
200 exc.printStackTrace();
201 }
202 return null;
206 }
207
208
211 private boolean isPackage(String result) {
212 if (sources.containsKey(result)) {
213 return false;
214 }
215 Class theClass = null;
217 try{
218 theClass = classLoader.loadClass(result);
219 }catch(Throwable e){};
220 return theClass == null;
221 }
222
223
227 public boolean isPackage(char[][] parentPackageName,
228 char[] packageName) {
229 String result = "";
230 String sep = "";
231 if (parentPackageName != null) {
232 for (int i = 0; i < parentPackageName.length; i++) {
233 result += sep;
234 String str = new String(parentPackageName[i]);
235 result += str;
236 sep = ".";
237 }
238 }
239 String str = new String(packageName);
240 if (Character.isUpperCase(str.charAt(0))) {
241 if (!isPackage(result)) {
242 return false;
243 }
244 }
245 result += sep;
246 result += str;
247 return isPackage(result);
248 }
249
250 public void cleanup() {
251 }
252
253 };
254
255 final IErrorHandlingPolicy policy =
257 DefaultErrorHandlingPolicies.proceedWithAllProblems();
258
259 final Map settings = new HashMap();
260 settings.put(CompilerOptions.OPTION_LineNumberAttribute,
261 CompilerOptions.GENERATE);
262 settings.put(CompilerOptions.OPTION_SourceFileAttribute,
263 CompilerOptions.GENERATE);
264 settings.put(CompilerOptions.OPTION_ReportDeprecation,
265 CompilerOptions.IGNORE);
266 settings.put(CompilerOptions.OPTION_ReportUnusedImport,
269 CompilerOptions.IGNORE);
270
271 final IProblemFactory problemFactory =
272 new DefaultProblemFactory(Locale.getDefault());
273
274 final ICompilerRequestor requestor = new ICompilerRequestor() {
276 public void acceptResult(CompilationResult result) {
277 boolean errors = false;
278 if (result.hasProblems()) {
279 IProblem[] problems = result.getProblems();
280 for (int i = 0; i < problems.length; i++) {
281 IProblem problem = problems[i];
283 if (problem.isError()) {
284 errors = true;
285 }
286 addProblem(problem);
287 }
288 }
289 if (!errors) {
292 ClassFile[] classFiles = result.getClassFiles();
293 for (int i = 0; i < classFiles.length; i++) {
294 ClassFile classFile = classFiles[i];
295 char[][] compoundName = classFile.getCompoundName();
296 String className = "";
297 String sep = "";
298 for (int j = 0; j < compoundName.length; j++) {
299 className += sep;
300 className += new String(compoundName[j]);
301 sep = ".";
302 }
303 byte[] bytes = classFile.getBytes();
304 classLoader.defineGateClass(className, bytes,
305 0, bytes.length);
306 }
307 }
308 }
309
310 private void addProblem(IProblem problem) {
311 String name = new String(problem.getOriginatingFileName());
312 List problemsForName = (List)problems.get(name);
313 if(problemsForName == null) {
314 problemsForName = new ArrayList();
315 problems.put(name, problemsForName);
316 }
317 problemsForName.add(problem);
318 }
319 };
320
321 ICompilationUnit[] compilationUnits = new ICompilationUnit[sources.size()];
323 int i = 0;
324 Iterator sourcesIt = sources.keySet().iterator();
325 while(sourcesIt.hasNext()) {
326 compilationUnits[i++] =
327 new CompilationUnit((String)sourcesIt.next());
328 }
329
330 Compiler compiler = new Compiler(env,
332 policy,
333 settings,
334 requestor,
335 problemFactory);
336
337 compiler.compile(compilationUnits);
339
340 if(!problems.isEmpty()) {
341 Iterator problemsIt = problems.entrySet().iterator();
342 while(problemsIt.hasNext()) {
343 Map.Entry prob = (Map.Entry)problemsIt.next();
344 String name = (String)prob.getKey();
345 List probsForName = (List)prob.getValue();
346 Iterator probsForNameIt = probsForName.iterator();
347 while(probsForNameIt.hasNext()) {
348 IProblem problem = (IProblem)probsForNameIt.next();
349 if(problem.isError()) {
350 Err.pr("Error: ");
351 }
352 else if(problem.isWarning()) {
353 Err.pr("Warning: ");
354 }
355 Err.prln(problem.getMessage()
356 + " at line "
357 + problem.getSourceLineNumber() + " in " + name);
358 }
359 Err.prln("\nThe offending input was:\n");
361 Err.prln(Strings.addLineNumbers((String)sources.get(name)));
362 }
363 throw new GateException(
364 "There were problems; see error log for details!");
365 }
366 }
367
368 private static GateClassLoader classLoader;
369 }
370