1 19 20 package org.netbeans.modules.java.source.builder; 21 22 import org.netbeans.modules.java.source.engine.EngineEnvironment; 23 import org.netbeans.modules.java.source.engine.JavaFormatOptions; 24 import org.netbeans.modules.java.source.engine.PropertySheetInfo; 25 import org.netbeans.modules.java.source.engine.JackpotEngine; 26 import org.netbeans.modules.java.source.engine.ApplicationContext; 27 import org.netbeans.modules.java.source.engine.BuildProgress; 28 import org.netbeans.modules.java.source.engine.EmptyScriptException; 29 import org.netbeans.modules.java.source.engine.EngineException; 30 import org.netbeans.modules.java.source.engine.QueryProgress; 31 import org.netbeans.modules.java.source.engine.RecursiveRuleException; 32 import org.netbeans.modules.java.source.engine.RulesParseException; 33 import org.netbeans.api.java.source.transform.UndoList; 34 import org.netbeans.modules.java.source.pretty.VeryPretty; 35 import org.netbeans.api.java.source.query.Query; 36 import org.netbeans.api.java.source.query.ResultTableModel; 37 import org.netbeans.modules.java.source.save.Commit; 38 import org.netbeans.modules.java.source.script.TransformParser; 39 import org.netbeans.api.java.source.transform.ChangeSet; 40 import org.netbeans.api.java.source.transform.Transformer; 41 import org.netbeans.modules.classfile.ClassFile; 42 import org.openide.filesystems.FileObject; 43 import org.openide.filesystems.Repository; 44 import com.sun.tools.javac.api.JavacTaskImpl; 45 import com.sun.tools.javac.main.JavaCompiler; 46 import com.sun.tools.javac.tree.JCTree; 47 import com.sun.tools.javac.util.Context; 48 import com.sun.tools.javac.util.Log; 49 import com.sun.tools.javac.util.Options; 50 import java.io.*; 51 import java.util.StringTokenizer ; 52 import java.util.logging.*; 53 import javax.tools.JavaFileObject; 54 55 58 public class Engine implements JackpotEngine { 59 private EngineEnvironment env; 60 ApplicationContext appContext; 61 private boolean buildFinished; 62 private String jackpotPath; 63 64 static final Logger logger = Logger.getLogger("org.netbeans.modules.java.source"); 65 66 67 public Engine(ApplicationContext appContext, String jackpotPath) { 68 this.appContext = appContext; 69 appContext.setStatusMessage(""); 70 this.jackpotPath = jackpotPath; 71 } 72 73 78 public int initialize(String sourcepath, String classpath, String source) throws Exception { 79 return initialize(sourcepath, classpath, null, source); 80 } 81 82 87 public int initialize(String sourcepath, String classpath, String bootclasspath, String source) throws Exception { 88 return initialize(sourcepath, classpath, bootclasspath, source, null); 89 } 90 91 96 public int initialize(String sourcepath, String classpath, String bootclasspath, String sourceLevel, String encoding) throws Exception { 97 if (buildFinished) 98 throw new AssertionError ("engine already initialized"); 99 JavacTaskImpl task = Builder.createJavacTask(sourcepath, classpath, bootclasspath, sourceLevel, encoding); 100 env = new DefaultEnvironment(task, appContext, sourceLevel); 101 BuildProgress progressBar = appContext.getBuildProgress(); 102 Builder builder = new Builder(task, getPaths(sourcepath), progressBar); 103 int errors = 0; 104 try { 105 errors = builder.build(); 106 } catch (OutOfMemoryError e) { 107 env = null; 108 System.gc(); 109 throw e; 110 } finally { 111 progressBar.dispose(); 112 } 113 buildFinished = true; 114 return errors; 115 } 116 117 120 private String [] getPaths(String path) { 121 StringTokenizer tok = new StringTokenizer (path, File.pathSeparator); 122 String [] paths = new String [tok.countTokens()]; 123 int i = 0; 124 while (tok.hasMoreTokens()) 125 paths[i++] = tok.nextToken(); 126 return paths; 127 } 128 129 public boolean isInitialized() { 130 return buildFinished; 131 } 132 133 public ResultTableModel runCommand(String queryName, String className) throws Exception { 134 return runCommand(queryName, null, className); 135 } 136 137 public ResultTableModel runCommand(String queryName, String transformerName, String className) throws Exception { 138 Query query = null; 139 QueryProgress progressBar = appContext.getQueryProgress(); 140 progressBar.setTotalQueries(1); 141 try { 142 query = createCommand(queryName, transformerName, className); 143 if (appContext.setProperties(query, queryName)) { 144 progressBar.queryStarted(queryName); 145 query.init(); 146 query.attach(env); 147 query.apply(); 148 query.release(); 149 query.destroy(); 150 progressBar.queryFinished(); 151 } 152 return query.getResult(); 153 } catch (EmptyScriptException e) { 154 throw e; 155 } catch (RulesParseException rpe) { 156 throw rpe; 157 } catch (ThreadDeath td) { 158 return query != null ? query.getResult() : null; } catch (Throwable t) { 160 throw new EngineException("Error executing operator", t); 161 } finally { 162 progressBar.dispose(); 163 } 164 } 165 166 public ResultTableModel runCommands(String querySetName, Query[] queries) throws Exception { 167 MultiTransformer multi = null; 168 QueryProgress progressBar = appContext.getQueryProgress(); 169 try { 170 multi = new MultiTransformer(querySetName, queries, progressBar); 171 multi.init(); 172 multi.attach(env); 173 multi.apply(); 174 ResultTableModel rtm = multi.getResult(); 175 multi.release(); 176 return rtm; 177 } catch (EmptyScriptException e) { 178 throw e; 179 } catch (RulesParseException rpe) { 180 throw rpe; 181 } catch (ThreadDeath td) { 182 return multi != null ? multi.getResult() : null; } catch (Throwable t) { 184 throw new EngineException("Error executing operator", t); 185 } finally { 186 multi.destroy(); 187 progressBar.dispose(); 188 } 189 } 190 191 public Query createCommand(String queryName, String transformerName, String className) throws Exception { 192 Class c = createQueryClass(className); 193 Object obj = c.newInstance(); 194 if (!(obj instanceof Query)) 195 throw new EngineException("I don't know how to handle " + c); 196 Query query = (Query)obj; 197 query.setQueryDescription(queryName); 198 if (query instanceof Transformer && transformerName != null) 199 ((Transformer)query).setRefactoringDescription(transformerName); 200 return query; 201 } 202 203 public Transformer createScript(String queryName, String transformerName, String path) throws Exception { 204 if (path.startsWith("file:")) 205 path = path.substring(5); 206 final InputStream is; 207 final long lastmod; 208 FileObject fo = Repository.getDefault().getDefaultFileSystem().findResource(path); 209 if (fo != null) { 210 is = fo.getInputStream(); 211 lastmod = fo.lastModified().getTime(); 212 } else { 213 File f = new File(path); 214 is = new FileInputStream(f); lastmod = f.lastModified(); 216 } 217 Reader in = new InputStreamReader(is); 218 Class c = createScriptClass(path, queryName, transformerName, in, lastmod); 219 Object obj = c.newInstance(); 220 if (!(obj instanceof Transformer)) 221 throw new EngineException("I don't know how to handle " + c); 222 return (Transformer)obj; 223 } 224 225 228 public ResultTableModel runScript(String queryName, String transformName, String path) throws Exception { 229 QueryProgress progressBar = appContext.getQueryProgress(); 230 progressBar.setTotalQueries(1); 231 try { 232 Transformer query = createScript(queryName, transformName, path); 233 if (appContext.setProperties(query, queryName)) { 234 progressBar.queryStarted(queryName); 235 query.init(); 236 query.attach(env); 237 query.apply(); 238 query.release(); 239 query.destroy(); 240 progressBar.queryFinished(); 241 } 242 return query.getResult(); 243 } catch (RecursiveRuleException e) { 244 throw e; 245 } catch (EmptyScriptException e) { 246 throw e; 247 } catch (RulesParseException rpe) { 248 throw rpe; 249 } catch (Throwable t) { 250 throw new EngineException("Error executing operator", t); 251 } finally { 252 progressBar.dispose(); 253 } 254 } 255 256 private Class createScriptClass(String path, String queryName, String transformDesc, Reader in, long lastmod) throws Exception { 257 TransformParser tp = new TransformParser(path, queryName, transformDesc, in, lastmod, jackpotPath); 258 tp.parseRules(); 259 if (!tp.hasRules()) 260 throw new EmptyScriptException(queryName); 261 if (tp.hasErrors()) 262 throw new RulesParseException(tp.getErrors()); 263 Class ret; 264 Throwable t0 = null; 265 try { 266 ret = tp.codeRules(); 267 } catch(Throwable t) { 268 t0 = t; 269 ret = null; 270 } 271 if (tp.hasErrors()) 272 throw new RulesParseException("script errors:\n" + tp.getErrors()); 273 else if(t0 != null) 274 throw new EngineException("script compilation failed", t0); 275 return ret; 276 } 277 278 private Class createQueryClass(final String className) throws Exception { 279 ClassLoader loader = new ClassLoader (getClass().getClassLoader()) { 280 public Class findClass(String name) throws ClassNotFoundException { 281 if (name.endsWith(".class")) { 282 try { 283 if (name.startsWith("file://")) 284 name = name.substring(7); 285 else if (name.startsWith("file:")) 286 name = name.substring(5); 287 FileInputStream in = new FileInputStream(name); 288 int len0 = in.available(); 289 byte[] b = new byte[len0]; 290 int len1 = in.read(b); 291 in.close(); 292 if (len1 != len0) 293 throw new ClassNotFoundException (name + ": read failure"); 294 ClassFile cf = new ClassFile(name); 295 return defineClass(cf.getName().getExternalName(), b, 0, b.length); 296 } catch (IOException e) { 297 throw new ClassNotFoundException ("failed loading " + name, e); 298 } 299 } 300 Class c = appContext.getCommandClass(name); 301 return (c == null) ? super.findClass(name) : c; 302 } 303 }; 304 return loader.loadClass(className); 305 } 306 307 public void undo(boolean erase) { 308 if (!buildFinished) 309 throw new AssertionError ("engine not initialized"); 310 UndoList undoList = env.getUndoList(); 311 undoList.undo(); 312 if (erase) 313 undoList.clearRedo(); 314 } 315 316 public void redo() { 317 if (!buildFinished) 318 throw new AssertionError ("engine not initialized"); 319 env.getUndoList().redo(); 320 } 321 322 public boolean canUndo() { 323 return buildFinished ? env.getUndoList().canUndo() : false; 324 } 325 326 public boolean canRedo() { 327 return buildFinished ? env.getUndoList().canRedo() : false; 328 } 329 330 public void applyChanges(final ChangeSet changeSet) { 331 Transformer<Object ,Object > t = new Transformer<Object ,Object >() { 332 @Override 333 public void init() { 334 super.init(); 335 this.changes = changeSet; 336 } 337 }; 338 t.init(); 339 t.attach(env); 340 t.apply(); 341 t.release(); 342 t.destroy(); 343 } 344 345 public boolean needsCommit() { 346 if (!buildFinished) 347 return false; 348 Commit save = new Commit(); 349 return save.isEnabled(env); 350 } 351 352 357 public boolean commit() throws IOException { 358 if (!buildFinished) 359 throw new AssertionError ("engine not initialized"); 360 Commit save = new Commit(); 361 if (!save.isEnabled(env)) 362 return true; 363 save.init(); 364 save.attach(env); 365 save.commit(); 366 save.release(); 367 save.destroy(); 368 return true; 369 } 370 371 public void close() { 372 if (env != null) { 373 UndoList undoList = env.getUndoList(); 374 undoList.reset(); 375 } 376 env = null; 377 appContext = null; 378 jackpotPath = null; 379 buildFinished = false; 380 } 381 382 public PropertySheetInfo getPropertySheetInfo(String className) { 383 try { 384 Class cls = Class.forName(className); 385 return PropertySheetInfo.find(cls); 386 } catch (Exception e) { 387 return null; 388 } 389 } 390 391 public JavaFormatOptions getFormatOptions() { 392 return JavaFormatOptions.getDefault(); 393 } 394 395 public String format(JavaFileObject source, JavaFormatOptions formatOptions) throws IOException { 396 Context context = new Context(); 398 Options options = Options.instance(context); 399 options.put("-source", "1.5"); 400 JavaCompiler comp = new JavaCompiler(context); 401 Log.instance(context).useSource(source); 402 JCTree.JCCompilationUnit unit = comp.parse(source); 403 404 VeryPretty formatter = new VeryPretty(context, formatOptions); 406 unit.accept(formatter); 407 return formatter.toString(); 408 } 409 } 410 | Popular Tags |