KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > apache > jasper > compiler > JDTCompiler


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

17
18 package org.apache.jasper.compiler;
19
20 import java.io.BufferedOutputStream JavaDoc;
21 import java.io.BufferedReader JavaDoc;
22 import java.io.ByteArrayOutputStream JavaDoc;
23 import java.io.File JavaDoc;
24 import java.io.FileInputStream JavaDoc;
25 import java.io.FileNotFoundException JavaDoc;
26 import java.io.FileOutputStream JavaDoc;
27 import java.io.IOException JavaDoc;
28 import java.io.InputStream JavaDoc;
29 import java.io.InputStreamReader JavaDoc;
30 import java.io.Reader JavaDoc;
31 import java.util.ArrayList JavaDoc;
32 import java.util.HashMap JavaDoc;
33 import java.util.Locale JavaDoc;
34 import java.util.Map JavaDoc;
35 import java.util.StringTokenizer JavaDoc;
36
37 import org.apache.jasper.JasperException;
38 import org.eclipse.jdt.core.compiler.IProblem;
39 import org.eclipse.jdt.internal.compiler.ClassFile;
40 import org.eclipse.jdt.internal.compiler.CompilationResult;
41 import org.eclipse.jdt.internal.compiler.Compiler;
42 import org.eclipse.jdt.internal.compiler.DefaultErrorHandlingPolicies;
43 import org.eclipse.jdt.internal.compiler.ICompilerRequestor;
44 import org.eclipse.jdt.internal.compiler.IErrorHandlingPolicy;
45 import org.eclipse.jdt.internal.compiler.IProblemFactory;
46 import org.eclipse.jdt.internal.compiler.classfmt.ClassFileReader;
47 import org.eclipse.jdt.internal.compiler.env.ICompilationUnit;
48 import org.eclipse.jdt.internal.compiler.env.INameEnvironment;
49 import org.eclipse.jdt.internal.compiler.env.NameEnvironmentAnswer;
50 import org.eclipse.jdt.internal.compiler.impl.CompilerOptions;
51 import org.eclipse.jdt.internal.compiler.problem.DefaultProblemFactory;
52
53 /**
54  * JDT class compiler. This compiler will load source dependencies from the
55  * context classloader, reducing dramatically disk access during
56  * the compilation process.
57  *
58  * @author Cocoon2
59  * @author Remy Maucherat
60  */

61 public class JDTCompiler extends org.apache.jasper.compiler.Compiler {
62
63     
64     /**
65      * Compile the servlet from .java file to .class file
66      */

67     protected void generateClass(String JavaDoc[] smap)
68         throws FileNotFoundException JavaDoc, JasperException, Exception JavaDoc {
69
70         long t1 = 0;
71         if (log.isDebugEnabled()) {
72             t1 = System.currentTimeMillis();
73         }
74         
75         final String JavaDoc sourceFile = ctxt.getServletJavaFileName();
76         final String JavaDoc outputDir = ctxt.getOptions().getScratchDir().getAbsolutePath();
77         String JavaDoc packageName = ctxt.getServletPackageName();
78         final String JavaDoc targetClassName =
79             ((packageName.length() != 0) ? (packageName + ".") : "")
80                     + ctxt.getServletClassName();
81         final ClassLoader JavaDoc classLoader = ctxt.getJspLoader();
82         String JavaDoc[] fileNames = new String JavaDoc[] {sourceFile};
83         String JavaDoc[] classNames = new String JavaDoc[] {targetClassName};
84         final ArrayList JavaDoc problemList = new ArrayList JavaDoc();
85         
86         class CompilationUnit implements ICompilationUnit {
87
88             String JavaDoc className;
89             String JavaDoc sourceFile;
90
91             CompilationUnit(String JavaDoc sourceFile, String JavaDoc className) {
92                 this.className = className;
93                 this.sourceFile = sourceFile;
94             }
95
96             public char[] getFileName() {
97                 return sourceFile.toCharArray();
98             }
99             
100             public char[] getContents() {
101                 char[] result = null;
102                 try {
103                     InputStreamReader JavaDoc isReader =
104                         new InputStreamReader JavaDoc(new FileInputStream JavaDoc(sourceFile),
105                                 ctxt.getOptions().getJavaEncoding());
106                     Reader JavaDoc reader = new BufferedReader JavaDoc(isReader);
107                     if (reader != null) {
108                         char[] chars = new char[8192];
109                         StringBuffer JavaDoc buf = new StringBuffer JavaDoc();
110                         int count;
111                         while ((count = reader.read(chars, 0,
112                                                     chars.length)) > 0) {
113                             buf.append(chars, 0, count);
114                         }
115                         result = new char[buf.length()];
116                         buf.getChars(0, result.length, result, 0);
117                     }
118                 } catch (IOException JavaDoc e) {
119                     log.error("Compilation error", e);
120                 }
121                 return result;
122             }
123             
124             public char[] getMainTypeName() {
125                 int dot = className.lastIndexOf('.');
126                 if (dot > 0) {
127                     return className.substring(dot + 1).toCharArray();
128                 }
129                 return className.toCharArray();
130             }
131             
132             public char[][] getPackageName() {
133                 StringTokenizer JavaDoc izer =
134                     new StringTokenizer JavaDoc(className, ".");
135                 char[][] result = new char[izer.countTokens()-1][];
136                 for (int i = 0; i < result.length; i++) {
137                     String JavaDoc tok = izer.nextToken();
138                     result[i] = tok.toCharArray();
139                 }
140                 return result;
141             }
142         }
143
144         final INameEnvironment env = new INameEnvironment() {
145
146                 public NameEnvironmentAnswer
147                     findType(char[][] compoundTypeName) {
148                     String JavaDoc result = "";
149                     String JavaDoc sep = "";
150                     for (int i = 0; i < compoundTypeName.length; i++) {
151                         result += sep;
152                         result += new String JavaDoc(compoundTypeName[i]);
153                         sep = ".";
154                     }
155                     return findType(result);
156                 }
157
158                 public NameEnvironmentAnswer
159                     findType(char[] typeName,
160                              char[][] packageName) {
161                         String JavaDoc result = "";
162                         String JavaDoc sep = "";
163                         for (int i = 0; i < packageName.length; i++) {
164                             result += sep;
165                             result += new String JavaDoc(packageName[i]);
166                             sep = ".";
167                         }
168                         result += sep;
169                         result += new String JavaDoc(typeName);
170                         return findType(result);
171                 }
172                 
173                 private NameEnvironmentAnswer findType(String JavaDoc className) {
174
175                     InputStream JavaDoc is = null;
176                     try {
177                         if (className.equals(targetClassName)) {
178                             ICompilationUnit compilationUnit =
179                                 new CompilationUnit(sourceFile, className);
180                             return
181                                 new NameEnvironmentAnswer(compilationUnit, null);
182                         }
183                         String JavaDoc resourceName =
184                             className.replace('.', '/') + ".class";
185                         is = classLoader.getResourceAsStream(resourceName);
186                         if (is != null) {
187                             byte[] classBytes;
188                             byte[] buf = new byte[8192];
189                             ByteArrayOutputStream JavaDoc baos =
190                                 new ByteArrayOutputStream JavaDoc(buf.length);
191                             int count;
192                             while ((count = is.read(buf, 0, buf.length)) > 0) {
193                                 baos.write(buf, 0, count);
194                             }
195                             baos.flush();
196                             classBytes = baos.toByteArray();
197                             char[] fileName = className.toCharArray();
198                             ClassFileReader classFileReader =
199                                 new ClassFileReader(classBytes, fileName,
200                                                     true);
201                             return
202                                 new NameEnvironmentAnswer(classFileReader, null);
203                         }
204                     } catch (IOException JavaDoc exc) {
205                         log.error("Compilation error", exc);
206                     } catch (org.eclipse.jdt.internal.compiler.classfmt.ClassFormatException exc) {
207                         log.error("Compilation error", exc);
208                     } finally {
209                         if (is != null) {
210                             try {
211                                 is.close();
212                             } catch (IOException JavaDoc exc) {
213                                 // Ignore
214
}
215                         }
216                     }
217                     return null;
218                 }
219
220                 private boolean isPackage(String JavaDoc result) {
221                     if (result.equals(targetClassName)) {
222                         return false;
223                     }
224                     String JavaDoc resourceName = result.replace('.', '/') + ".class";
225                     InputStream JavaDoc is =
226                         classLoader.getResourceAsStream(resourceName);
227                     return is == null;
228                 }
229
230                 public boolean isPackage(char[][] parentPackageName,
231                                          char[] packageName) {
232                     String JavaDoc result = "";
233                     String JavaDoc sep = "";
234                     if (parentPackageName != null) {
235                         for (int i = 0; i < parentPackageName.length; i++) {
236                             result += sep;
237                             String JavaDoc str = new String JavaDoc(parentPackageName[i]);
238                             result += str;
239                             sep = ".";
240                         }
241                     }
242                     String JavaDoc str = new String JavaDoc(packageName);
243                     if (Character.isUpperCase(str.charAt(0))) {
244                         if (!isPackage(result)) {
245                             return false;
246                         }
247                     }
248                     result += sep;
249                     result += str;
250                     return isPackage(result);
251                 }
252
253                 public void cleanup() {
254                 }
255
256             };
257
258         final IErrorHandlingPolicy policy =
259             DefaultErrorHandlingPolicies.proceedWithAllProblems();
260
261         final Map JavaDoc settings = new HashMap JavaDoc();
262         settings.put(CompilerOptions.OPTION_LineNumberAttribute,
263                      CompilerOptions.GENERATE);
264         settings.put(CompilerOptions.OPTION_SourceFileAttribute,
265                      CompilerOptions.GENERATE);
266         settings.put(CompilerOptions.OPTION_ReportDeprecation,
267                      CompilerOptions.IGNORE);
268         if (ctxt.getOptions().getJavaEncoding() != null) {
269             settings.put(CompilerOptions.OPTION_Encoding,
270                     ctxt.getOptions().getJavaEncoding());
271         }
272         if (ctxt.getOptions().getClassDebugInfo()) {
273             settings.put(CompilerOptions.OPTION_LocalVariableAttribute,
274                          CompilerOptions.GENERATE);
275         }
276
277         // Source JVM
278
if(ctxt.getOptions().getCompilerSourceVM() != null) {
279             String JavaDoc opt = ctxt.getOptions().getCompilerSourceVM();
280             if(opt.equals("1.1")) {
281                 settings.put(CompilerOptions.OPTION_Source,
282                              CompilerOptions.VERSION_1_1);
283             } else if(opt.equals("1.2")) {
284                 settings.put(CompilerOptions.OPTION_Source,
285                              CompilerOptions.VERSION_1_2);
286             } else if(opt.equals("1.3")) {
287                 settings.put(CompilerOptions.OPTION_Source,
288                              CompilerOptions.VERSION_1_3);
289             } else if(opt.equals("1.4")) {
290                 settings.put(CompilerOptions.OPTION_Source,
291                              CompilerOptions.VERSION_1_4);
292             } else if(opt.equals("1.5")) {
293                 settings.put(CompilerOptions.OPTION_Source,
294                              CompilerOptions.VERSION_1_5);
295             } else {
296                 log.warn("Unknown source VM " + opt + " ignored.");
297                 settings.put(CompilerOptions.OPTION_Source,
298                         CompilerOptions.VERSION_1_5);
299             }
300         } else {
301             // Default to 1.5
302
settings.put(CompilerOptions.OPTION_Source,
303                     CompilerOptions.VERSION_1_5);
304         }
305         
306         // Target JVM
307
if(ctxt.getOptions().getCompilerTargetVM() != null) {
308             String JavaDoc opt = ctxt.getOptions().getCompilerTargetVM();
309             if(opt.equals("1.1")) {
310                 settings.put(CompilerOptions.OPTION_TargetPlatform,
311                              CompilerOptions.VERSION_1_1);
312             } else if(opt.equals("1.2")) {
313                 settings.put(CompilerOptions.OPTION_TargetPlatform,
314                              CompilerOptions.VERSION_1_2);
315             } else if(opt.equals("1.3")) {
316                 settings.put(CompilerOptions.OPTION_TargetPlatform,
317                              CompilerOptions.VERSION_1_3);
318             } else if(opt.equals("1.4")) {
319                 settings.put(CompilerOptions.OPTION_TargetPlatform,
320                              CompilerOptions.VERSION_1_4);
321             } else if(opt.equals("1.5")) {
322                 settings.put(CompilerOptions.OPTION_TargetPlatform,
323                              CompilerOptions.VERSION_1_5);
324                 settings.put(CompilerOptions.OPTION_Compliance,
325                         CompilerOptions.VERSION_1_5);
326             } else {
327                 log.warn("Unknown target VM " + opt + " ignored.");
328                 settings.put(CompilerOptions.OPTION_TargetPlatform,
329                         CompilerOptions.VERSION_1_5);
330             }
331         } else {
332             // Default to 1.5
333
settings.put(CompilerOptions.OPTION_TargetPlatform,
334                     CompilerOptions.VERSION_1_5);
335             settings.put(CompilerOptions.OPTION_Compliance,
336                     CompilerOptions.VERSION_1_5);
337         }
338
339         final IProblemFactory problemFactory =
340             new DefaultProblemFactory(Locale.getDefault());
341         
342         final ICompilerRequestor requestor = new ICompilerRequestor() {
343                 public void acceptResult(CompilationResult result) {
344                     try {
345                         if (result.hasProblems()) {
346                             IProblem[] problems = result.getProblems();
347                             for (int i = 0; i < problems.length; i++) {
348                                 IProblem problem = problems[i];
349                                 if (problem.isError()) {
350                                     String JavaDoc name =
351                                         new String JavaDoc(problems[i].getOriginatingFileName());
352                                     try {
353                                         problemList.add(ErrorDispatcher.createJavacError
354                                                 (name, pageNodes, new StringBuffer JavaDoc(problem.getMessage()),
355                                                         problem.getSourceLineNumber()));
356                                     } catch (JasperException e) {
357                                         log.error("Error visiting node", e);
358                                     }
359                                 }
360                             }
361                         }
362                         if (problemList.isEmpty()) {
363                             ClassFile[] classFiles = result.getClassFiles();
364                             for (int i = 0; i < classFiles.length; i++) {
365                                 ClassFile classFile = classFiles[i];
366                                 char[][] compoundName =
367                                     classFile.getCompoundName();
368                                 String JavaDoc className = "";
369                                 String JavaDoc sep = "";
370                                 for (int j = 0;
371                                      j < compoundName.length; j++) {
372                                     className += sep;
373                                     className += new String JavaDoc(compoundName[j]);
374                                     sep = ".";
375                                 }
376                                 byte[] bytes = classFile.getBytes();
377                                 String JavaDoc outFile = outputDir + "/" +
378                                     className.replace('.', '/') + ".class";
379                                 FileOutputStream JavaDoc fout =
380                                     new FileOutputStream JavaDoc(outFile);
381                                 BufferedOutputStream JavaDoc bos =
382                                     new BufferedOutputStream JavaDoc(fout);
383                                 bos.write(bytes);
384                                 bos.close();
385                             }
386                         }
387                     } catch (IOException JavaDoc exc) {
388                         log.error("Compilation error", exc);
389                     }
390                 }
391             };
392
393         ICompilationUnit[] compilationUnits =
394             new ICompilationUnit[classNames.length];
395         for (int i = 0; i < compilationUnits.length; i++) {
396             String JavaDoc className = classNames[i];
397             compilationUnits[i] = new CompilationUnit(fileNames[i], className);
398         }
399         Compiler JavaDoc compiler = new Compiler JavaDoc(env,
400                                          policy,
401                                          settings,
402                                          requestor,
403                                          problemFactory,
404                                          true);
405         compiler.compile(compilationUnits);
406
407         if (!ctxt.keepGenerated()) {
408             File JavaDoc javaFile = new File JavaDoc(ctxt.getServletJavaFileName());
409             javaFile.delete();
410         }
411     
412         if (!problemList.isEmpty()) {
413             JavacErrorDetail[] jeds =
414                 (JavacErrorDetail[]) problemList.toArray(new JavacErrorDetail[0]);
415             errDispatcher.javacError(jeds);
416         }
417         
418         if( log.isDebugEnabled() ) {
419             long t2=System.currentTimeMillis();
420             log.debug("Compiled " + ctxt.getServletJavaFileName() + " "
421                       + (t2-t1) + "ms");
422         }
423
424         if (ctxt.isPrototypeMode()) {
425             return;
426         }
427
428         // JSR45 Support
429
if (! options.isSmapSuppressed()) {
430             SmapUtil.installSmap(smap);
431         }
432         
433     }
434     
435     
436 }
437
Popular Tags