1 2 25 26 package org.aspectj.ajde.internal; 27 28 import java.io.*; 29 import java.util.*; 30 import org.aspectj.compiler.base.*; 31 import org.aspectj.util.ConfigParser; 32 import org.aspectj.ajde.*; 33 import org.aspectj.asm.*; 34 35 41 public class AspectJBuildManager implements BuildManager { 42 43 private AjdeCompiler currCompiler = null; 44 private TaskListManager compilerMessages = null; 45 private BuildProgressMonitor progressMonitor = null; 46 private BuildOptionsAdapter buildOptions = null; 47 private ArrayList compilerListeners = new ArrayList(); 48 private String configFile = ""; 49 private int lastCompileTime = 50; 50 private boolean buildStrucutreOnly = false; 51 52 public AspectJBuildManager( 53 TaskListManager compilerMessages, 54 BuildProgressMonitor progressMonitor, 55 BuildOptionsAdapter buildOptions) { 56 this.compilerMessages = compilerMessages; 57 this.progressMonitor = progressMonitor; 58 this.buildOptions = buildOptions; 59 } 60 61 public void build() { 62 if (Ajde.getDefault().getConfigurationManager().getActiveConfigFile() == null) { 63 Ajde.getDefault().getErrorHandler().handleWarning("Nothing to compile, please add a \".lst\" file."); 64 return; 65 } else { 66 build(Ajde.getDefault().getConfigurationManager().getActiveConfigFile()); 67 } 68 } 69 70 public void buildStructure() { 71 buildStrucutreOnly = true; 72 build(); 73 } 74 75 public void build(String configFile) { 76 buildStrucutreOnly = false; 77 this.buildOptions = buildOptions; 78 if (configFile == null) { 79 Ajde.getDefault().getErrorHandler().handleWarning("Please add a configuration file to compile."); 80 } else { 81 this.configFile = configFile; 82 CompilerThread compilerThread = new CompilerThread(); 83 compilerThread.start(); 84 } 85 } 86 87 public void abortBuild() { 88 if (currCompiler != null) { 89 currCompiler.requestCompileExit(); 90 } 91 } 92 93 public AjdeCompiler getCurrCompiler() { 94 return currCompiler; 95 } 96 97 public boolean isStructureDirty() { 98 if (currCompiler != null) { 99 return currCompiler.structureDirty; 100 } else { 101 return false; 102 } 103 } 104 105 public void setStructureDirty(boolean structureDirty) { 106 if (currCompiler != null) { 107 currCompiler.structureDirty = structureDirty; 108 } 109 } 110 111 public void addListener(BuildListener compilerListener) { 112 compilerListeners.add(compilerListener); 113 } 114 115 public void removeListener(BuildListener compilerListener) { 116 compilerListeners.remove(compilerListener); 117 } 118 119 private void notifyCompileFinished(String configFile, int buildTime, boolean succeeded, boolean warnings) { 120 Ajde.getDefault().logEvent("build finished, succeeded: " + succeeded); 121 for (Iterator it = compilerListeners.iterator(); it.hasNext(); ) { 122 ((BuildListener)it.next()).compileFinished(configFile, buildTime, succeeded, warnings); 123 } 124 } 125 126 private void notifyCompileStarted(String configFile) { 127 Ajde.getDefault().logEvent("build started: " + configFile); 128 for (Iterator it = compilerListeners.iterator(); it.hasNext(); ) { 129 ((BuildListener)it.next()).compileStarted(configFile); 130 } 131 } 132 133 private void notifyCompileAborted(String configFile, String message) { 134 for (Iterator it = compilerListeners.iterator(); it.hasNext(); ) { 135 ((BuildListener)it.next()).compileAborted(configFile, message); 136 } 137 } 138 139 142 private void displayMessages(CompileResult compileResult) { 143 String [] descriptions = compileResult.getDescriptions(); 144 String [] files = compileResult.getfiles(); 145 Integer [] lineNumbers = compileResult.getLineNumbers(); 146 if (descriptions.length == 0 && compileResult.getResult().trim() != "") { 147 compilerMessages.addSourcelineTask( 149 compileResult.getResult(), 150 new SourceLocation("", 0, 0), 151 StructureMessage.Kind.ERROR); 152 return; 153 } 154 155 for ( int i = 0; i < descriptions.length && 156 i < files.length && 157 i < lineNumbers.length; i++ ) { 158 String message = ""; 159 if (files[i] != "") { 160 message += "\"" + files[i] + "\": "; 161 } 162 if (lineNumbers[i].intValue() != -1 && lineNumbers[i].intValue() != 0) { 163 message += descriptions[i] + ", at line: " + lineNumbers[i]; 164 } else { 165 message += descriptions[i]; 166 } 167 168 if (message.startsWith("Nothing to compile.")) { 169 message = "Nothing to compile, please select the project, package(s), or class(es) to compile."; 170 } 171 172 173 StructureMessage.Kind kind = StructureMessage.Kind.ERROR; 174 if (descriptions[i].endsWith("(warning)")) kind = StructureMessage.Kind.WARNING; 175 176 compilerMessages.addSourcelineTask( 177 message, 178 new SourceLocation(files[i], lineNumbers[i].intValue(), 0), 179 kind); 180 181 StructureNode node = Ajde.getDefault().getStructureModelManager().getStructureModel().findNodeForSourceLine( 182 files[i], 183 lineNumbers[i].intValue() 184 ); 185 186 if (node != null) { 187 node.setMessage(new StructureMessage(message, kind)); 188 } 189 } 190 } 191 192 195 public class CompilerThread extends Thread { 196 197 public void run() { 198 boolean succeeded = true; 199 boolean warnings = false; 200 try { 201 long timeStart = System.currentTimeMillis(); 202 notifyCompileStarted(configFile); 203 progressMonitor.start(configFile); 204 compilerMessages.clearTasks(); 205 AjdeCompiler compiler = new AjdeCompiler( 206 Ajde.getDefault().getStructureModelManager(), 207 progressMonitor); 208 setCompilerOptions(compiler); 209 210 Ajde.getDefault().logEvent("building with options: " 211 + getFormattedOptionsString(buildOptions, Ajde.getDefault().getProjectProperties())); 212 213 compiler.setConfigFile(configFile); 214 if (buildStrucutreOnly) compiler.setDoPostSymbolPasses(false); 215 currCompiler = compiler; 216 217 File config = new File(configFile); 218 if (!config.exists()) { 219 throw new ConfigFileDoesNotExistException(configFile); 220 } 221 ConfigParser configParser = new ConfigParser(); 222 configParser.parseConfigFile(config); 223 224 try { 225 compiler.compile(configParser.getFiles()); 226 } catch (CompilerErrors ce) { 227 } 229 230 if (compiler.getAjdeBuildErrorHandler().getErrorCount() > 0) succeeded = false; 231 if (compiler.getAjdeBuildErrorHandler().getWarningCount() > 0) warnings = true; 232 long timeEnd = System.currentTimeMillis(); 233 lastCompileTime = (int)(timeEnd - timeStart); 234 } catch (ConfigParser.ParseException pe) { 235 Ajde.getDefault().getErrorHandler().handleWarning( 236 "Config file entry invalid, file: " 237 + pe.getFile().getPath() 238 + ", line number: " 239 + pe.getLine()); 240 } catch (ConfigFileDoesNotExistException cfdne) { 241 Ajde.getDefault().getErrorHandler().handleWarning("Config file \"" + configFile + "\" does not exist."); 242 } catch (ExitRequestException ere) { 243 if (ere.getValue() == 0) { 244 notifyCompileAborted(configFile, "Build cancelled by user."); 245 } else { 246 Ajde.getDefault().getErrorHandler().handleWarning("Compile could not complete. See the console for more details. " 247 + "If no console is available re-launch the application from the command line."); 248 } 249 } catch (InternalCompilerError compilerError) { 250 if (compilerError.uncaughtThrowable instanceof OutOfMemoryError ) { 251 Ajde.getDefault().getErrorHandler().handleError("Out of memory. " 252 + "Increase memory by setting the -Xmx parameter that this VM was launched with.\n" 253 + "Note that some AJDE structure persists across compiles." , 254 compilerError.uncaughtThrowable); 255 } else if (compilerError.uncaughtThrowable instanceof MissingRuntimeError) { 256 Ajde.getDefault().getErrorHandler().handleWarning("Compilation aborted because the AspectJ runtime was not found. " 257 + "Please place aspectjrt.jar in the lib/ext directory."); 258 } else if (compilerError.uncaughtThrowable instanceof BadRuntimeError) { 259 Ajde.getDefault().getErrorHandler().handleWarning("Compilation aborted because an out-of-date version of " + 260 "the AspectJ runtime was found. " 261 + "Please place a current version of aspectjrt.jar in the lib/ext directory."); 262 } else { 263 Ajde.getDefault().getErrorHandler().handleError("Compile error.", compilerError.uncaughtThrowable); 264 } 265 } catch (Throwable e) { 266 Ajde.getDefault().getErrorHandler().handleError("Compile error, caught Throwable: " + e.toString(), e); 267 } finally { 268 progressMonitor.finish(); 269 } 270 notifyCompileFinished(configFile, lastCompileTime, succeeded, warnings); 271 } 272 273 private String getFormattedOptionsString(BuildOptionsAdapter buildOptions, ProjectPropertiesAdapter properties) { 274 return "Building with settings: " 275 + "\n-> output path: " + properties.getOutputPath() 276 + "\n-> classpath: " + properties.getClasspath() 277 + "\n-> bootclasspath: " + properties.getBootClasspath() 278 + "\n-> non-standard options: " + buildOptions.getNonStandardOptions() 279 + "\n-> porting mode: " + buildOptions.getPortingMode() 280 + "\n-> source 1.4 mode: " + buildOptions.getSourceOnePointFourMode() 281 + "\n-> strict spec mode: " + buildOptions.getStrictSpecMode() 282 + "\n-> lenient spec mode: " + buildOptions.getLenientSpecMode() 283 + "\n-> use javac mode: " + buildOptions.getUseJavacMode() 284 + "\n-> preprocess mode: " + buildOptions.getPreprocessMode() 285 + "\n-> working dir: " + buildOptions.getWorkingOutputPath(); 286 } 287 } 288 289 public BuildOptionsAdapter getBuildOptions() { 290 return buildOptions; 291 } 292 293 private void setCompilerOptions(AjdeCompiler compiler) { 294 String nonstandardOptions = buildOptions.getNonStandardOptions(); 295 if (nonstandardOptions != null && !nonstandardOptions.trim().equals("")) { 296 StringTokenizer st = new StringTokenizer(nonstandardOptions, " "); 297 while (st.hasMoreTokens()) { 298 String flag = (String )st.nextToken(); 299 compiler.getOptions().set(flag.substring(1, flag.length()), Boolean.TRUE); 300 } 301 } 302 303 if (Ajde.getDefault().getProjectProperties().getOutputPath() != null 304 && !compiler.getOptions().XtargetNearSource) { 305 compiler.getOptions().outputDir = new File(Ajde.getDefault().getProjectProperties().getOutputPath()); 306 } 307 if (Ajde.getDefault().getProjectProperties().getBootClasspath() != null) { 308 compiler.getOptions().bootclasspath = Ajde.getDefault().getProjectProperties().getBootClasspath(); 309 } 310 if (Ajde.getDefault().getProjectProperties().getClasspath() != null) { 311 compiler.getOptions().classpath = Ajde.getDefault().getProjectProperties().getClasspath(); 312 } 313 if (buildOptions.getWorkingOutputPath() != null) { 314 compiler.getOptions().workingDir = new File(buildOptions.getWorkingOutputPath()); 315 } 316 320 compiler.getOptions().lenient = buildOptions.getLenientSpecMode(); 321 compiler.getOptions().strict = buildOptions.getStrictSpecMode(); 322 compiler.getOptions().usejavac = buildOptions.getUseJavacMode(); 323 compiler.getOptions().porting = buildOptions.getPortingMode(); 324 compiler.getOptions().preprocess = buildOptions.getPreprocessMode(); 325 326 if (buildOptions.getSourceOnePointFourMode()) { 327 compiler.getOptions().source = "1.4"; 328 } 329 } 330 331 static class CompileResult { 332 private String [] files = null; 333 private Integer [] lineNumbers = null; 334 private String [] descriptions = null; 335 private String resultString = ""; 336 private boolean resultContainsErrors = false; 337 338 343 public CompileResult( String result ) 344 { 345 resultString = result; 346 347 BufferedReader reader = new BufferedReader( new StringReader( result ) ); 348 Vector fileV = new Vector(); 349 Vector lineV = new Vector(); 350 Vector descV = new Vector(); 351 try { 352 for (String line = reader.readLine(); line != null; line = reader.readLine()) { 353 String originalLine = line; 354 String description = ""; 355 String file = ""; 356 Integer lineNo = new Integer (0); 357 int index = line.indexOf( ":", 2 ); try { 359 if (line.indexOf("Note: ") != -1) { 360 int index1 = line.indexOf(".java"); 361 if (index1 != -1) { 362 description = line.substring(index1+5) + " (warning)"; 363 file = line.substring("Note: ".length(), index1+5); 364 lineNo = new Integer (0); 365 } else { 366 description = line + " (warning)"; 367 file = ""; 368 lineNo = new Integer (-1); 369 } 370 } 371 else if (line.indexOf("file not found: ") != -1) { 372 description = "file not found: "; 373 file = line.substring("file not found: ".length()); 374 lineNo = new Integer (0); 375 } 376 else if (index != -1 && line.indexOf( "java" ) != -1) { 377 file = line.substring( 0, index ); 378 line = line.substring( index+1 ); 379 380 index = line.indexOf( ":" ); 381 lineNo = new Integer ( Integer.parseInt( line.substring( 0, index ) ) ) ; 382 line = line.substring( index+1 ); 383 384 if (!resultContainsErrors) { 385 if (!line.endsWith("(warning)")) { 386 resultContainsErrors = true; 387 } 388 } 389 description = line.substring( line.indexOf( ":" ) + 2 ); 390 } 391 } catch (Exception e) { 392 description = "Internal ajc message: " + originalLine; 393 file = ""; 394 lineNo = new Integer (-1); 395 } 396 if (description.trim() != "") { 397 descV.addElement(description); 398 fileV.addElement(file); 399 lineV.addElement(lineNo); 400 } 401 } 402 } 403 catch ( IOException ioe ) { 404 resultString = "ERROR: could not parse result at line for string: " + result; 405 } 406 files = new String [fileV.size()]; 407 lineNumbers = new Integer [lineV.size()]; 408 descriptions = new String [descV.size()]; 409 fileV.copyInto(files); 410 lineV.copyInto(lineNumbers); 411 descV.copyInto(descriptions); 412 } 413 414 public String toString() 415 { 416 return resultString; 417 } 418 419 public String [] getfiles() 420 { 421 return files; 422 } 423 424 public Integer [] getLineNumbers() 425 { 426 return lineNumbers; 427 } 428 429 public String [] getDescriptions() 430 { 431 return descriptions; 432 } 433 434 public String getResult() 435 { 436 return resultString; 437 } 438 439 public boolean containsErrors() { 440 return resultContainsErrors; 441 } 442 } 443 } 444 445 class ConfigFileDoesNotExistException extends Exception { 446 public ConfigFileDoesNotExistException(String filePath) { 447 super(filePath); 448 } 449 } | Popular Tags |