1 16 17 package org.apache.axis.components.compiler; 18 19 import org.apache.axis.components.logger.LogFactory; 20 import org.apache.axis.utils.ClassUtils; 21 import org.apache.axis.utils.Messages; 22 import org.apache.commons.logging.Log; 23 24 import java.io.BufferedReader ; 25 import java.io.ByteArrayInputStream ; 26 import java.io.ByteArrayOutputStream ; 27 import java.io.File ; 28 import java.io.IOException ; 29 import java.io.OutputStream ; 30 import java.io.OutputStreamWriter ; 31 import java.io.PrintWriter ; 32 import java.lang.reflect.Constructor ; 33 import java.lang.reflect.Method ; 34 import java.util.ArrayList ; 35 import java.util.List ; 36 import java.util.NoSuchElementException ; 37 import java.util.StringTokenizer ; 38 import java.net.URL ; 39 import java.net.MalformedURLException ; 40 import java.net.URLClassLoader ; 41 42 49 50 public class Javac extends AbstractCompiler 51 { 52 protected static Log log = 53 LogFactory.getLog(Javac.class.getName()); 54 55 public static final String CLASSIC_CLASS = "sun.tools.javac.Main"; 56 public static final String MODERN_CLASS = "com.sun.tools.javac.main.Main"; 57 58 private boolean modern = false; 59 60 public Javac() { 61 ClassLoader cl = getClassLoader(); 62 try { 63 ClassUtils.forName(MODERN_CLASS, true, cl); 64 modern = true; 65 } catch (ClassNotFoundException e) { 66 log.debug(Messages.getMessage("noModernCompiler")); 67 try { 68 ClassUtils.forName(CLASSIC_CLASS, true, cl); 69 modern = false; 70 } catch (Exception ex) { 71 log.error(Messages.getMessage("noCompiler00"), ex); 72 throw new RuntimeException (Messages.getMessage("noCompiler00")); 73 } 74 } 75 log.debug(Messages.getMessage("compilerClass", 76 (modern ? MODERN_CLASS : CLASSIC_CLASS))); 77 } 78 79 private ClassLoader getClassLoader() { 80 ClassLoader cl = Thread.currentThread().getContextClassLoader(); 82 83 URL toolsURL = null; 84 String tools = System.getProperty("java.home"); 85 if (tools != null) { 86 File f = new File (tools + "/../lib/tools.jar"); 87 if (f.exists()) { 88 try { 89 toolsURL = f.toURL(); 90 cl = new URLClassLoader (new URL []{toolsURL}, cl); 91 } catch (MalformedURLException e) { 92 } 93 } 94 } 95 96 return cl; 97 } 98 99 104 public boolean compile() throws IOException { 105 ByteArrayOutputStream err = new ByteArrayOutputStream (); 106 boolean result = false; 107 108 try { 109 Class c = ClassUtils.forName(modern ? MODERN_CLASS : CLASSIC_CLASS, 111 true, 112 getClassLoader()); 113 114 Constructor cons; 115 Object compiler; 116 if (modern) { 117 PrintWriter pw = new PrintWriter (new OutputStreamWriter (err)); 118 cons = 119 c.getConstructor(new Class [] { String .class, 120 PrintWriter .class}); 121 122 compiler = cons.newInstance(new Object [] { "javac", pw }); 123 } 124 else { 125 cons = 126 c.getConstructor(new Class [] { OutputStream .class, 127 String .class }); 128 compiler = cons.newInstance(new Object [] { err, "javac" }); 129 130 } 131 132 Method compile = c.getMethod("compile", 134 new Class [] { String [].class }); 135 136 if (modern) { 137 int compilationResult = 138 ((Integer )compile.invoke(compiler, new Object [] 139 { 140 toStringArray(fillArguments 141 (new ArrayList ()))})).intValue(); 142 143 result = (compilationResult == 0); 144 log.debug("Compilation Returned: " 145 + Integer.toString(compilationResult)); 146 } 147 else { 148 Boolean ok = 149 (Boolean )compile.invoke(compiler, new Object [] 150 {toStringArray(fillArguments(new ArrayList ()))}); 151 152 result = ok.booleanValue(); 153 } 154 } catch (Exception cnfe){ 155 log.error(Messages.getMessage("noCompiler00"), cnfe); 156 throw new RuntimeException (Messages.getMessage("noCompiler00")); 157 } 158 159 this.errors = new ByteArrayInputStream (err.toByteArray()); 160 return result; 161 } 162 163 171 protected List parseStream(BufferedReader input) throws IOException { 172 if (modern) { 173 return parseModernStream(input); 174 } else { 175 return parseClassicStream(input); 176 } 177 } 178 179 187 protected List parseModernStream(BufferedReader input) throws IOException { 188 List errors = new ArrayList (); 189 String line = null; 190 StringBuffer buffer = null; 191 192 while (true) { 193 buffer = new StringBuffer (); 196 do { 198 if ((line = input.readLine()) == null) 199 { 200 if (buffer.length() > 0) { 201 errors.add(new CompilerError("\n" + buffer.toString())); 203 } 204 return errors; 205 } 206 log.debug(line); 207 buffer.append(line); 208 buffer.append('\n'); 209 } while (!line.endsWith("^")); 210 211 errors.add(parseModernError(buffer.toString())); 213 } 214 } 215 216 222 private CompilerError parseModernError(String error) { 223 StringTokenizer tokens = new StringTokenizer (error, ":"); 224 try { 225 String file = tokens.nextToken(); 226 if (file.length() == 1) file = new StringBuffer (file).append(":").append(tokens.nextToken()).toString(); 227 int line = Integer.parseInt(tokens.nextToken()); 228 229 String message = tokens.nextToken("\n").substring(1); 230 String context = tokens.nextToken("\n"); 231 String pointer = tokens.nextToken("\n"); 232 int startcolumn = pointer.indexOf("^"); 233 int endcolumn = context.indexOf(" ", startcolumn); 234 if (endcolumn == -1) endcolumn = context.length(); 235 return new CompilerError(file, false, line, startcolumn, line, endcolumn, message); 236 } catch(NoSuchElementException nse) { 237 return new CompilerError(Messages.getMessage("noMoreTokens", error)); 238 } catch(Exception nse) { 239 return new CompilerError(Messages.getMessage("cantParse", error)); 240 } 241 } 242 243 251 protected List parseClassicStream(BufferedReader input) throws IOException { 252 List errors = null; 253 String line = null; 254 StringBuffer buffer = null; 255 256 while (true) { 257 buffer = new StringBuffer (); 260 for (int i = 0; i < 3 ; i++) { 262 if ((line = input.readLine()) == null) return errors; 263 log.debug(line); 264 buffer.append(line); 265 buffer.append('\n'); 266 } 267 268 if (errors == null) errors = new ArrayList (); 270 271 errors.add(parseClassicError(buffer.toString())); 273 } 274 } 275 276 282 private CompilerError parseClassicError(String error) { 283 StringTokenizer tokens = new StringTokenizer (error, ":"); 284 try { 285 String file = tokens.nextToken(); 286 if (file.length() == 1) { 287 file = new StringBuffer (file).append(":"). 288 append(tokens.nextToken()).toString(); 289 } 290 int line = Integer.parseInt(tokens.nextToken()); 291 292 String last = tokens.nextToken(); 293 while (tokens.hasMoreElements()) { 295 last += tokens.nextToken(); 296 } 297 tokens = new StringTokenizer (last.trim(), "\n"); 298 String message = tokens.nextToken(); 299 String context = tokens.nextToken(); 300 String pointer = tokens.nextToken(); 301 int startcolumn = pointer.indexOf("^"); 302 int endcolumn = context.indexOf(" ", startcolumn); 303 if (endcolumn == -1) endcolumn = context.length(); 304 305 return new CompilerError(srcDir + File.separator + file, true, 306 line, startcolumn, line, endcolumn, message); 307 } catch(NoSuchElementException nse) { 308 return new CompilerError(Messages.getMessage("noMoreTokens", 309 error)); 310 } catch(Exception nse) { 311 return new CompilerError(Messages.getMessage("cantParse", error)); 312 } 313 } 314 315 public String toString() { 316 return Messages.getMessage("sunJavac"); 317 } 318 } 319 | Popular Tags |