KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > apache > cocoon > components > language > programming > java > EclipseJavaCompiler


1 /*
2  * Copyright 1999-2004 The Apache Software Foundation.
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  * http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */

16 package org.apache.cocoon.components.language.programming.java;
17
18 import org.apache.avalon.excalibur.pool.Recyclable;
19 import org.apache.cocoon.components.language.programming.CompilerError;
20 import org.apache.cocoon.components.language.programming.LanguageCompiler;
21 import org.apache.cocoon.util.ClassUtils;
22 import org.apache.commons.lang.StringUtils;
23 import org.apache.commons.lang.SystemUtils;
24
25 import org.eclipse.jdt.core.compiler.IProblem;
26 import org.eclipse.jdt.internal.compiler.ClassFile;
27 import org.eclipse.jdt.internal.compiler.CompilationResult;
28 import org.eclipse.jdt.internal.compiler.Compiler;
29 import org.eclipse.jdt.internal.compiler.DefaultErrorHandlingPolicies;
30 import org.eclipse.jdt.internal.compiler.ICompilerRequestor;
31 import org.eclipse.jdt.internal.compiler.IErrorHandlingPolicy;
32 import org.eclipse.jdt.internal.compiler.IProblemFactory;
33 import org.eclipse.jdt.internal.compiler.classfmt.ClassFileReader;
34 import org.eclipse.jdt.internal.compiler.env.ICompilationUnit;
35 import org.eclipse.jdt.internal.compiler.env.INameEnvironment;
36 import org.eclipse.jdt.internal.compiler.env.NameEnvironmentAnswer;
37 import org.eclipse.jdt.internal.compiler.impl.CompilerOptions;
38 import org.eclipse.jdt.internal.compiler.problem.DefaultProblemFactory;
39
40 import java.io.BufferedOutputStream JavaDoc;
41 import java.io.BufferedReader JavaDoc;
42 import java.io.ByteArrayOutputStream JavaDoc;
43 import java.io.File JavaDoc;
44 import java.io.FileOutputStream JavaDoc;
45 import java.io.FileReader JavaDoc;
46 import java.io.IOException JavaDoc;
47 import java.io.InputStream JavaDoc;
48 import java.io.Reader JavaDoc;
49 import java.util.HashMap JavaDoc;
50 import java.util.LinkedList JavaDoc;
51 import java.util.List JavaDoc;
52 import java.util.Locale JavaDoc;
53 import java.util.Map JavaDoc;
54 import java.util.StringTokenizer JavaDoc;
55
56 /**
57  * Eclipse Java Compiler
58  *
59  * @version CVS $Id: EclipseJavaCompiler.java 290264 2005-09-19 21:02:50Z joerg $
60  */

61 public class EclipseJavaCompiler implements LanguageCompiler, Recyclable {
62
63     boolean debug;
64
65     String JavaDoc sourceDir;
66     String JavaDoc sourceFile;
67     String JavaDoc destDir;
68     String JavaDoc sourceEncoding;
69     int compilerComplianceLevel;
70
71     List JavaDoc errors = new LinkedList JavaDoc();
72
73     public EclipseJavaCompiler() {
74         this.debug = true;
75     }
76
77     public void recycle() {
78         sourceFile = null;
79         sourceDir = null;
80         destDir = null;
81         sourceEncoding = null;
82         errors.clear();
83     }
84
85     public void setFile(String JavaDoc file) {
86         // This is the absolute path to the file to be compiled
87
this.sourceFile = file;
88     }
89
90     public void setSource(String JavaDoc srcDir) {
91         // This is the "sourcepath" of the file to be compiled
92
this.sourceDir = srcDir;
93     }
94
95     public void setDestination(String JavaDoc destDir) {
96         // This is the output directory)
97
this.destDir = destDir;
98     }
99
100     public void setEncoding(String JavaDoc encoding) {
101         this.sourceEncoding = encoding;
102     }
103     
104     /**
105      * Set the version of the java source code to be compiled
106      *
107      * @param compilerComplianceLevel The version of the JVM for wich the code was written.
108      * i.e: 130 = Java 1.3, 140 = Java 1.4 and 150 = Java 1.5
109      *
110      * @since 2.1.7
111      */

112     public void setCompilerComplianceLevel(int compilerComplianceLevel) {
113         this.compilerComplianceLevel = compilerComplianceLevel;
114     }
115
116     /**
117      * Eclipse Java compiler ignores class path setting and uses current
118      * Java class loader
119      * @param cp classpath to be ignored
120      */

121     public void setClasspath(String JavaDoc cp) {
122         // Not used
123
}
124
125     private String JavaDoc makeClassName(String JavaDoc fileName) throws IOException JavaDoc {
126         File origFile = new File(fileName);
127         String JavaDoc canonical = null;
128         if (origFile.exists()) {
129             canonical = origFile.getCanonicalPath().replace('\\', '/');
130         }
131         String JavaDoc str = fileName;
132         str = str.replace('\\', '/');
133         if (sourceDir != null) {
134             String JavaDoc prefix =
135                 new File(sourceDir).getCanonicalPath().replace('\\', '/');
136             if (canonical != null) {
137                 if (canonical.startsWith(prefix)) {
138                     String JavaDoc result = canonical.substring(prefix.length() + 1,
139                                                         canonical.length() -5);
140                     result = result.replace('/', '.');
141                     return result;
142                 }
143             } else {
144                 File t = new File(sourceDir, fileName);
145                 if (t.exists()) {
146                     str = t.getCanonicalPath().replace('\\', '/');
147                     String JavaDoc result = str.substring(prefix.length()+1,
148                                                   str.length() - 5).replace('/', '.');
149                     return result;
150                 }
151             }
152         }
153         if (fileName.endsWith(".java")) {
154             fileName = fileName.substring(0, fileName.length() - 5);
155         }
156         return StringUtils.replaceChars(fileName, "\\/", "..");
157     }
158
159     public boolean compile() throws IOException JavaDoc {
160         final String JavaDoc targetClassName = makeClassName(sourceFile);
161         final ClassLoader JavaDoc classLoader = ClassUtils.getClassLoader();
162         String JavaDoc[] fileNames = new String JavaDoc[] {sourceFile};
163         String JavaDoc[] classNames = new String JavaDoc[] {targetClassName};
164         class CompilationUnit implements ICompilationUnit {
165
166             String JavaDoc className;
167             String JavaDoc sourceFile;
168
169             CompilationUnit(String JavaDoc sourceFile, String JavaDoc className) {
170                 this.className = className;
171                 this.sourceFile = sourceFile;
172             }
173
174             public char[] getFileName() {
175                 return className.toCharArray();
176             }
177             
178             public char[] getContents() {
179                 char[] result = null;
180                 FileReader fr = null;
181                 try {
182                     fr = new FileReader(sourceFile);
183                     Reader reader = new BufferedReader JavaDoc(fr);
184                     if (reader != null) {
185                         char[] chars = new char[8192];
186                         StringBuffer JavaDoc buf = new StringBuffer JavaDoc();
187                         int count;
188                         while ((count = reader.read(chars, 0, chars.length)) > 0) {
189                             buf.append(chars, 0, count);
190                         }
191                         result = new char[buf.length()];
192                         buf.getChars(0, result.length, result, 0);
193                     }
194                 } catch (IOException JavaDoc e) {
195                     handleError(className, -1, -1, e.getMessage());
196                 }
197                 return result;
198             }
199             
200             public char[] getMainTypeName() {
201                 int dot = className.lastIndexOf('.');
202                 if (dot > 0) {
203                     return className.substring(dot + 1).toCharArray();
204                 }
205                 return className.toCharArray();
206             }
207             
208             public char[][] getPackageName() {
209                 StringTokenizer JavaDoc izer = new StringTokenizer JavaDoc(className, ".");
210                 char[][] result = new char[izer.countTokens()-1][];
211                 for (int i = 0; i < result.length; i++) {
212                     String JavaDoc tok = izer.nextToken();
213                     result[i] = tok.toCharArray();
214                 }
215                 return result;
216             }
217         }
218
219
220         final INameEnvironment env = new INameEnvironment() {
221
222                 public NameEnvironmentAnswer findType(char[][] compoundTypeName) {
223                     StringBuffer JavaDoc result = new StringBuffer JavaDoc();
224                     for (int i = 0; i < compoundTypeName.length; i++) {
225                         if (i > 0) {
226                             result.append(".");
227                         }
228                         result.append(compoundTypeName[i]);
229                     }
230                     return findType(result.toString());
231                 }
232
233                 public NameEnvironmentAnswer findType(char[] typeName, char[][] packageName) {
234                         StringBuffer JavaDoc result = new StringBuffer JavaDoc();
235                         for (int i = 0; i < packageName.length; i++) {
236                             if (i > 0) {
237                                 result.append(".");
238                             }
239                             result.append(packageName[i]);
240                         }
241                         result.append(".");
242                         result.append(typeName);
243                         return findType(result.toString());
244                 }
245                 
246                 private NameEnvironmentAnswer findType(String JavaDoc className) {
247
248                     try {
249                         if (className.equals(targetClassName)) {
250                             ICompilationUnit compilationUnit =
251                                 new CompilationUnit(sourceFile, className);
252                             return
253                                 new NameEnvironmentAnswer(compilationUnit);
254                         }
255                         String JavaDoc resourceName =
256                             className.replace('.', '/') + ".class";
257                         InputStream JavaDoc is =
258                             classLoader.getResourceAsStream(resourceName);
259                         if (is != null) {
260                             byte[] classBytes;
261                             byte[] buf = new byte[8192];
262                             ByteArrayOutputStream JavaDoc baos =
263                                 new ByteArrayOutputStream JavaDoc(buf.length);
264                             int count;
265                             while ((count = is.read(buf, 0, buf.length)) > 0) {
266                                 baos.write(buf, 0, count);
267                             }
268                             baos.flush();
269                             classBytes = baos.toByteArray();
270                             char[] fileName = className.toCharArray();
271                             ClassFileReader classFileReader =
272                                 new ClassFileReader(classBytes, fileName,
273                                                     true);
274                             return
275                                 new NameEnvironmentAnswer(classFileReader);
276                         }
277                     } catch (IOException JavaDoc exc) {
278                         handleError(className, -1, -1,
279                                     exc.getMessage());
280                     } catch (org.eclipse.jdt.internal.compiler.classfmt.ClassFormatException exc) {
281                         handleError(className, -1, -1,
282                                     exc.getMessage());
283                     }
284                     return null;
285                 }
286
287                 private boolean isPackage(String JavaDoc result) {
288                     if (result.equals(targetClassName)) {
289                         return false;
290                     }
291                     String JavaDoc resourceName = result.replace('.', '/') + ".class";
292                     InputStream JavaDoc is =
293                         classLoader.getResourceAsStream(resourceName);
294                     return is == null;
295                 }
296
297                 public boolean isPackage(char[][] parentPackageName, char[] packageName) {
298                     StringBuffer JavaDoc result = new StringBuffer JavaDoc();
299                     if (parentPackageName != null) {
300                         for (int i = 0; i < parentPackageName.length; i++) {
301                             if (i > 0) {
302                                 result.append(".");
303                             }
304                             result.append(parentPackageName[i]);
305                         }
306                     }
307                     String JavaDoc str = new String JavaDoc(packageName);
308                     if (Character.isUpperCase(str.charAt(0)) && !isPackage(result.toString())) {
309                             return false;
310                     }
311                     result.append(".");
312                     result.append(str);
313                     return isPackage(result.toString());
314                 }
315
316                 public void cleanup() {
317                     // EMPTY
318
}
319             };
320         final IErrorHandlingPolicy policy =
321             DefaultErrorHandlingPolicies.proceedWithAllProblems();
322         final Map JavaDoc settings = new HashMap JavaDoc(9);
323         settings.put(CompilerOptions.OPTION_LineNumberAttribute,
324                      CompilerOptions.GENERATE);
325         settings.put(CompilerOptions.OPTION_SourceFileAttribute,
326                      CompilerOptions.GENERATE);
327         settings.put(CompilerOptions.OPTION_ReportDeprecation,
328                      CompilerOptions.IGNORE);
329         settings.put(CompilerOptions.OPTION_ReportUnusedImport, CompilerOptions.IGNORE);
330         if (sourceEncoding != null) {
331             settings.put(CompilerOptions.OPTION_Encoding, sourceEncoding);
332         }
333         if (debug) {
334             settings.put(CompilerOptions.OPTION_LocalVariableAttribute, CompilerOptions.GENERATE);
335         }
336         // Set the sourceCodeVersion
337
switch (this.compilerComplianceLevel) {
338             case 150:
339                 settings.put(CompilerOptions.OPTION_Source, CompilerOptions.VERSION_1_5);
340                 settings.put(CompilerOptions.OPTION_Compliance, CompilerOptions.VERSION_1_5);
341                 break;
342             case 140:
343                 settings.put(CompilerOptions.OPTION_Source, CompilerOptions.VERSION_1_4);
344                 break;
345             default:
346                 settings.put(CompilerOptions.OPTION_Source, CompilerOptions.VERSION_1_3);
347         }
348         // Set the target platform
349
switch (SystemUtils.JAVA_VERSION_INT) {
350             case 150:
351                 settings.put(CompilerOptions.OPTION_TargetPlatform, CompilerOptions.VERSION_1_5);
352                 break;
353             case 140:
354                 settings.put(CompilerOptions.OPTION_TargetPlatform, CompilerOptions.VERSION_1_4);
355                 break;
356             default:
357                 settings.put(CompilerOptions.OPTION_TargetPlatform, CompilerOptions.VERSION_1_3);
358         }
359         final IProblemFactory problemFactory =
360             new DefaultProblemFactory(Locale.getDefault());
361
362         final ICompilerRequestor requestor = new ICompilerRequestor() {
363                 public void acceptResult(CompilationResult result) {
364                     try {
365                         if (result.hasErrors()) {
366                             IProblem[] errors = result.getErrors();
367                             for (int i = 0; i < errors.length; i++) {
368                                 IProblem error = errors[i];
369                                 String JavaDoc name = new String JavaDoc(errors[i].getOriginatingFileName());
370                                 handleError(name, error.getSourceLineNumber(), -1, error.getMessage());
371                             }
372                         } else {
373                             ClassFile[] classFiles = result.getClassFiles();
374                             for (int i = 0; i < classFiles.length; i++) {
375                                 ClassFile classFile = classFiles[i];
376                                 char[][] compoundName = classFile.getCompoundName();
377                                 StringBuffer JavaDoc className = new StringBuffer JavaDoc();
378                                 for (int j = 0; j < compoundName.length; j++) {
379                                     if (j > 0) {
380                                         className.append(".");
381                                     }
382                                     className.append(compoundName[j]);
383                                 }
384                                 byte[] bytes = classFile.getBytes();
385                                 String JavaDoc outFile = destDir + "/" +
386                                     className.toString().replace('.', '/') + ".class";
387                                 FileOutputStream JavaDoc fout = new FileOutputStream JavaDoc(outFile);
388                                 BufferedOutputStream JavaDoc bos = new BufferedOutputStream JavaDoc(fout);
389                                 bos.write(bytes);
390                                 bos.close();
391                             }
392                         }
393                     } catch (IOException JavaDoc exc) {
394                         exc.printStackTrace();
395                     }
396                 }
397             };
398         ICompilationUnit[] compilationUnits =
399             new ICompilationUnit[classNames.length];
400         for (int i = 0; i < compilationUnits.length; i++) {
401             String JavaDoc className = classNames[i];
402             compilationUnits[i] = new CompilationUnit(fileNames[i], className);
403         }
404         Compiler JavaDoc compiler = new Compiler JavaDoc(env,
405                                          policy,
406                                          settings,
407                                          requestor,
408                                          problemFactory);
409         compiler.compile(compilationUnits);
410         return errors.size() == 0;
411     }
412
413     void handleError(String JavaDoc className, int line, int column, Object JavaDoc errorMessage) {
414         String JavaDoc fileName =
415             className.replace('.', File.separatorChar) + ".java";
416         if (column < 0) column = 0;
417         errors.add(new CompilerError(fileName,
418                                      true,
419                                      line,
420                                      column,
421                                      line,
422                                      column,
423                                      errorMessage.toString()));
424     }
425
426     public List JavaDoc getErrors() throws IOException JavaDoc {
427         return errors;
428     }
429 }
430
Popular Tags