KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > com > caucho > java > EclipseCompiler


1 /*
2  * Copyright (c) 1998-2006 Caucho Technology -- all rights reserved
3  *
4  * This file is part of Resin(R) Open Source
5  *
6  * Each copy or derived work must preserve the copyright notice and this
7  * notice unmodified.
8  *
9  * Resin Open Source is free software; you can redistribute it and/or modify
10  * it under the terms of the GNU General Public License as published by
11  * the Free Software Foundation; either version 2 of the License, or
12  * (at your option) any later version.
13  *
14  * Resin Open Source is distributed in the hope that it will be useful,
15  * but WITHOUT ANY WARRANTY; without even the implied warranty of
16  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE, or any warranty
17  * of NON-INFRINGEMENT. See the GNU General Public License for more
18  * details.
19  *
20  * You should have received a copy of the GNU General Public License
21  * along with Resin Open Source; if not, write to the
22  *
23  * Free Software Foundation, Inc.
24  * 59 Temple Place, Suite 330
25  * Boston, MA 02111-1307 USA
26  *
27  * @author Scott Ferguson
28  */

29
30 package com.caucho.java;
31
32 import com.caucho.loader.EnvironmentClassLoader;
33 import com.caucho.util.CharBuffer;
34 import com.caucho.vfs.Encoding;
35 import com.caucho.vfs.IOExceptionWrapper;
36 import com.caucho.vfs.MemoryStream;
37 import com.caucho.vfs.Path;
38 import com.caucho.vfs.ReadStream;
39 import com.caucho.vfs.WriteStream;
40
41 import java.io.IOException JavaDoc;
42 import java.io.InputStream JavaDoc;
43 import java.io.PrintWriter JavaDoc;
44 import java.lang.reflect.Constructor JavaDoc;
45 import java.lang.reflect.InvocationTargetException JavaDoc;
46 import java.lang.reflect.Method JavaDoc;
47 import java.util.ArrayList JavaDoc;
48 import java.util.logging.Level JavaDoc;
49
50 /**
51  * Compiles Java source, returning the loaded class.
52  */

53 public class EclipseCompiler extends AbstractJavaCompiler {
54   private static boolean _hasCompiler; // already tested for compiler
55

56   private static final String JavaDoc COMPILER
57     = "org.eclipse.jdt.internal.compiler.batch.Main";
58   
59   Process JavaDoc _process;
60   String JavaDoc _userPrefix;
61   
62   boolean _isDead;
63   
64   public EclipseCompiler(JavaCompiler compiler)
65   {
66     super(compiler);
67   }
68
69   protected void compileInt(String JavaDoc []path, LineMap lineMap)
70     throws IOException JavaDoc, JavaCompileException
71   {
72     if (! _hasCompiler) {
73       try {
74         Class.forName(COMPILER, false,
75               Thread.currentThread().getContextClassLoader());
76
77         _hasCompiler = true;
78       } catch (Exception JavaDoc e) {
79         e.printStackTrace();
80         throw new JavaCompileException(L.l("Resin can't load org.eclipse.jdt.core.JDTCompilerAdapter. Usually this means that the JDK tools.jar is missing from the classpath, possibly because of using a JRE instead of the JDK. You can either add tools.jar to the classpath or change the compiler to an external one with <java compiler='javac'/> or jikes.\n\n{0}", String.valueOf(e)));
81       }
82     }
83
84     executeInt(path, lineMap);
85   }
86
87   /**
88    * Compiles the names files.
89    */

90   private void executeInt(String JavaDoc []path, LineMap lineMap)
91     throws JavaCompileException, IOException JavaDoc
92   {
93     MemoryStream tempStream = new MemoryStream();
94     WriteStream error = new WriteStream(tempStream);
95
96     try {
97       // String parent = javaPath.getParent().getNativePath();
98

99       ArrayList JavaDoc<String JavaDoc> argList = new ArrayList JavaDoc<String JavaDoc>();
100       /* This isn't needed since srcDirName is in the classpath
101       if ("1.2".compareTo(System.getProperty("java.version")) <= 0) {
102         argList.add("-sourcepath");
103         argList.add(srcDirName);
104       }
105       */

106       argList.add("-d");
107       argList.add(_compiler.getClassDirName());
108       if (_compiler.getEncoding() != null) {
109         String JavaDoc encoding = Encoding.getJavaName(_compiler.getEncoding());
110         if (encoding != null && ! encoding.equals("ISO8859_1")) {
111           argList.add("-encoding");
112           argList.add(_compiler.getEncoding());
113         }
114       }
115       argList.add("-classpath");
116       argList.add(_compiler.getClassPath());
117       ArrayList JavaDoc<String JavaDoc> args = _compiler.getArgs();
118       if (args != null)
119     argList.addAll(args);
120
121       for (int i = 0; i < path.length; i++) {
122     Path javaPath = _compiler.getSourceDir().lookup(path[i]);
123     argList.add(javaPath.getNativePath());
124       }
125
126       if (log.isLoggable(Level.FINE)) {
127         CharBuffer msg = CharBuffer.allocate();
128     msg.append("javac(int)");
129     for (int i = 0; i < argList.size(); i++) {
130       msg.append(" ");
131       msg.append(argList.get(i));
132     }
133         log.fine(msg.close());
134       }
135
136       String JavaDoc []argArray = argList.toArray(new String JavaDoc[argList.size()]);
137
138       int status = -1;
139       
140       Thread JavaDoc thread = Thread.currentThread();
141       ClassLoader JavaDoc oldLoader = thread.getContextClassLoader();
142       try {
143     EnvironmentClassLoader env;
144     env = new EnvironmentClassLoader(ClassLoader.getSystemClassLoader());
145         thread.setContextClassLoader(env);
146
147         try {
148           Class JavaDoc cl = Class.forName(COMPILER, false, env);
149       Constructor JavaDoc xtor = cl.getConstructor(new Class JavaDoc[] { PrintWriter JavaDoc.class, PrintWriter JavaDoc.class, boolean.class });
150       
151       Object JavaDoc value = xtor.newInstance(error.getPrintWriter(), error.getPrintWriter(), Boolean.FALSE);
152
153       Method JavaDoc compile = cl.getMethod("compile", new Class JavaDoc[] { String JavaDoc[].class });
154
155       Object JavaDoc result = compile.invoke(value, new Object JavaDoc[] { argArray });
156
157       status = Boolean.TRUE.equals(result) ? 0 : -1;
158         } catch (ClassNotFoundException JavaDoc e) {
159           throw new JavaCompileException(L.l("Can't find internal Java compiler. Either configure an external compiler with <javac> or use a JDK which contains a Java compiler."));
160         } catch (NoSuchMethodException JavaDoc e) {
161           throw new JavaCompileException(e);
162         } catch (InstantiationException JavaDoc e) {
163           throw new JavaCompileException(e);
164         } catch (IllegalAccessException JavaDoc e) {
165           throw new JavaCompileException(e);
166         } catch (InvocationTargetException JavaDoc e) {
167           throw new IOExceptionWrapper(e);
168         }
169       
170     error.close();
171     tempStream.close();
172       } finally {
173         thread.setContextClassLoader(oldLoader);
174       }
175
176       ReadStream read = tempStream.openRead();
177       JavacErrorParser parser = new JavacErrorParser();
178
179       String JavaDoc errors = parser.parseErrors((InputStream JavaDoc) read, lineMap);
180       read.close();
181
182       if (errors != null)
183     errors = errors.trim();
184
185       if (log.isLoggable(Level.FINE)) {
186     read = tempStream.openRead();
187     CharBuffer cb = new CharBuffer();
188     int ch;
189     while ((ch = read.read()) >= 0) {
190       cb.append((char) ch);
191     }
192     read.close();
193
194     log.fine(cb.toString());
195       }
196       /* XXX: why should warnings be sent as warning?
197       else if (status == 0 && errors != null && ! errors.equals("")) {
198     final String msg = errors;
199     
200     new com.caucho.loader.ClassLoaderContext(_compiler.getClassLoader()) {
201       public void run()
202       {
203         log.warning(msg);
204       }
205     };
206       }
207       */

208
209       if (status != 0)
210     throw new JavaCompileException(errors);
211     } finally {
212       tempStream.destroy();
213     }
214   }
215 }
216
Popular Tags