KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > aspectj > ajde > internal > AspectJBuildManager


1
2 /* -*- Mode: Java; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
3  *
4  * This file is part of the IDE support for the AspectJ(tm)
5  * programming language; see http://aspectj.org
6  *
7  * The contents of this file are subject to the Mozilla Public License
8  * Version 1.1 (the "License"); you may not use this file except in
9  * compliance with the License. You may obtain a copy of the License at
10  * either http://www.mozilla.org/MPL/ or http://aspectj.org/MPL/.
11  *
12  * Software distributed under the License is distributed on an "AS IS" basis,
13  * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
14  * for the specific language governing rights and limitations under the
15  * License.
16  *
17  * The Original Code is AspectJ.
18  *
19  * The Initial Developer of the Original Code is Xerox Corporation. Portions
20  * created by Xerox Corporation are Copyright (C) 1999-2002 Xerox Corporation.
21  * All Rights Reserved.
22  *
23  * Contributor(s):
24  */

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 /**
36  * Responsible for the build process, including compiler invocation, threading, and error
37  * reporting.
38  *
39  * @author Mik Kersten
40  */

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 JavaDoc 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 JavaDoc 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 JavaDoc 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 JavaDoc 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 JavaDoc configFile, String JavaDoc message) {
134         for (Iterator it = compilerListeners.iterator(); it.hasNext(); ) {
135             ((BuildListener)it.next()).compileAborted(configFile, message);
136         }
137     }
138
139     /**
140      * @todo use structured error messages instead
141      */

142     private void displayMessages(CompileResult compileResult) {
143         String JavaDoc[] descriptions = compileResult.getDescriptions();
144         String JavaDoc[] files = compileResult.getfiles();
145         Integer JavaDoc[] lineNumbers = compileResult.getLineNumbers();
146         if (descriptions.length == 0 && compileResult.getResult().trim() != "") {
147             //compilerMessages.addSourcelineTask(compileResult.getResult(), "", 0, 0, TaskListManager.ERROR_MESSAGE);
148
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 JavaDoc 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     /**
193      * @todo clean up this mess.
194      */

195     public class CompilerThread extends Thread JavaDoc {
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                     // handled below
228
}
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 JavaDoc) {
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 JavaDoc 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 JavaDoc 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 JavaDoc nonstandardOptions = buildOptions.getNonStandardOptions();
295         if (nonstandardOptions != null && !nonstandardOptions.trim().equals("")) {
296             StringTokenizer st = new StringTokenizer(nonstandardOptions, " ");
297             while (st.hasMoreTokens()) {
298                 String JavaDoc flag = (String JavaDoc)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 // if (buildOptions.getCharacterEncoding() != null) {
317
// compiler.getOptions().encoding = buildOptions.getCharacterEncoding();
318
// }
319

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 JavaDoc[] files = null;
333         private Integer JavaDoc[] lineNumbers = null;
334         private String JavaDoc[] descriptions = null;
335         private String JavaDoc resultString = "";
336         private boolean resultContainsErrors = false;
337
338         /**
339          * Parses out warning messages, error messages, "file not found" messages, javac "Note:" messages.
340          *
341          * @todo get error message structure directly from compiler
342          */

343         public CompileResult( String JavaDoc 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 JavaDoc line = reader.readLine(); line != null; line = reader.readLine()) {
353                     String JavaDoc originalLine = line;
354                     String JavaDoc description = "";
355                     String JavaDoc file = "";
356                     Integer JavaDoc lineNo = new Integer JavaDoc(0);
357                     int index = line.indexOf( ":", 2 ); // @todo skip the initial drive ":" (fix, Windows only)
358
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 JavaDoc(0);
365                             } else {
366                                 description = line + " (warning)";
367                                 file = "";
368                                 lineNo = new Integer JavaDoc(-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 JavaDoc(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 JavaDoc( 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 JavaDoc e) {
392                         description = "Internal ajc message: " + originalLine;
393                         file = "";
394                         lineNo = new Integer JavaDoc(-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 JavaDoc[fileV.size()];
407             lineNumbers = new Integer JavaDoc[lineV.size()];
408             descriptions = new String JavaDoc[descV.size()];
409             fileV.copyInto(files);
410             lineV.copyInto(lineNumbers);
411             descV.copyInto(descriptions);
412         }
413
414         public String JavaDoc toString()
415         {
416             return resultString;
417         }
418
419         public String JavaDoc[] getfiles()
420         {
421             return files;
422         }
423
424         public Integer JavaDoc[] getLineNumbers()
425         {
426             return lineNumbers;
427         }
428
429         public String JavaDoc[] getDescriptions()
430         {
431             return descriptions;
432         }
433
434         public String JavaDoc getResult()
435         {
436             return resultString;
437         }
438
439         public boolean containsErrors() {
440             return resultContainsErrors;
441         }
442     }
443 }
444
445 class ConfigFileDoesNotExistException extends Exception JavaDoc {
446     public ConfigFileDoesNotExistException(String JavaDoc filePath) {
447         super(filePath);
448     }
449 }
Popular Tags