]> source.dussan.org Git - aspectj.git/commitdiff
Fix for Bugzilla Bug 40192
authoraclement <aclement>
Thu, 18 Mar 2004 13:00:01 +0000 (13:00 +0000)
committeraclement <aclement>
Thu, 18 Mar 2004 13:00:01 +0000 (13:00 +0000)
   build cancel during weaving

17 files changed:
ajde/src/org/aspectj/ajde/internal/BuildNotifierAdapter.java
ajde/testdata/BuildCancelling/A1.aj [new file with mode: 0644]
ajde/testdata/BuildCancelling/A2.aj [new file with mode: 0644]
ajde/testdata/BuildCancelling/A3.aj [new file with mode: 0644]
ajde/testdata/BuildCancelling/A4.aj [new file with mode: 0644]
ajde/testdata/BuildCancelling/Cl1.java [new file with mode: 0644]
ajde/testdata/BuildCancelling/Cl2.java [new file with mode: 0644]
ajde/testdata/BuildCancelling/Cl3.java [new file with mode: 0644]
ajde/testdata/BuildCancelling/EvenMoreCode.lst [new file with mode: 0644]
ajde/testdata/BuildCancelling/HW.java [new file with mode: 0644]
ajde/testdata/BuildCancelling/LoadsaCode.lst [new file with mode: 0644]
ajde/testsrc/org/aspectj/ajde/AjdeTests.java
ajde/testsrc/org/aspectj/ajde/BuildCancellingTest.java [new file with mode: 0644]
bridge/src/org/aspectj/bridge/IProgressListener.java
org.aspectj.ajdt.core/src/org/aspectj/ajdt/internal/compiler/AjCompilerAdapter.java
org.aspectj.ajdt.core/src/org/aspectj/ajdt/internal/compiler/WeaverAdapter.java
org.aspectj.ajdt.core/src/org/aspectj/ajdt/internal/core/builder/AjBuildManager.java

index e1288e293c6b8bd732af4b4fff7b9547e54249bc..37a25f404c065364141729a37b8b5a7d1b63b933 100644 (file)
@@ -16,7 +16,6 @@ package org.aspectj.ajde.internal;
 import org.aspectj.ajde.Ajde;
 import org.aspectj.ajde.BuildProgressMonitor;
 import org.aspectj.ajdt.internal.core.builder.AjBuildManager;
-import org.aspectj.bridge.AbortException;
 import org.aspectj.bridge.IProgressListener;
 
 public class BuildNotifierAdapter implements IProgressListener {
@@ -50,4 +49,12 @@ public class BuildNotifierAdapter implements IProgressListener {
                progressMonitor.setProgressText(text);
        }
 
+       public void setCancelledRequested(boolean cancelRequested) {
+               this.cancelRequested = cancelRequested;
+       }
+
+       public boolean isCancelledRequested() {
+               return cancelRequested;
+       }
+
 }
diff --git a/ajde/testdata/BuildCancelling/A1.aj b/ajde/testdata/BuildCancelling/A1.aj
new file mode 100644 (file)
index 0000000..1245cff
--- /dev/null
@@ -0,0 +1,9 @@
+\r
+public aspect A1 {\r
+\r
+  pointcut m1(): execution(* main(..));\r
+  \r
+  before(): m1() {\r
+    System.err.println("Before main runs");\r
+  }\r
+}
\ No newline at end of file
diff --git a/ajde/testdata/BuildCancelling/A2.aj b/ajde/testdata/BuildCancelling/A2.aj
new file mode 100644 (file)
index 0000000..4a2ee81
--- /dev/null
@@ -0,0 +1,9 @@
+\r
+public aspect A2 {\r
+\r
+  pointcut m1(): execution(* main(..));\r
+  \r
+  after(): m1() {\r
+    System.err.println("After main runs");\r
+  }\r
+}\r
diff --git a/ajde/testdata/BuildCancelling/A3.aj b/ajde/testdata/BuildCancelling/A3.aj
new file mode 100644 (file)
index 0000000..d9f7a68
--- /dev/null
@@ -0,0 +1,9 @@
+\r
+public aspect A3 {\r
+\r
+  pointcut m1(): call(* *print*(..));\r
+  \r
+  before(): m1() {\r
+    System.err.println("Calling print");\r
+  }\r
+}
\ No newline at end of file
diff --git a/ajde/testdata/BuildCancelling/A4.aj b/ajde/testdata/BuildCancelling/A4.aj
new file mode 100644 (file)
index 0000000..5c475d4
--- /dev/null
@@ -0,0 +1,9 @@
+\r
+public aspect A4 {\r
+\r
+  pointcut m1(): call(* *print*(..));\r
+  \r
+  after(): m1() {\r
+    System.err.println("After call to print");\r
+  }\r
+}
\ No newline at end of file
diff --git a/ajde/testdata/BuildCancelling/Cl1.java b/ajde/testdata/BuildCancelling/Cl1.java
new file mode 100644 (file)
index 0000000..7652142
--- /dev/null
@@ -0,0 +1,4 @@
+public class Cl1 {
+       public static void main(String[] args) {
+       }
+}
\ No newline at end of file
diff --git a/ajde/testdata/BuildCancelling/Cl2.java b/ajde/testdata/BuildCancelling/Cl2.java
new file mode 100644 (file)
index 0000000..8ba3e49
--- /dev/null
@@ -0,0 +1,4 @@
+public class Cl2 {
+       public static void main(String[] args) {
+       }
+}
\ No newline at end of file
diff --git a/ajde/testdata/BuildCancelling/Cl3.java b/ajde/testdata/BuildCancelling/Cl3.java
new file mode 100644 (file)
index 0000000..0b3b301
--- /dev/null
@@ -0,0 +1,4 @@
+public class Cl3 {
+       public static void callPrint(String s) {
+       }
+}
\ No newline at end of file
diff --git a/ajde/testdata/BuildCancelling/EvenMoreCode.lst b/ajde/testdata/BuildCancelling/EvenMoreCode.lst
new file mode 100644 (file)
index 0000000..cfd1cee
--- /dev/null
@@ -0,0 +1,10 @@
+A1.aj\r
+Cl1.java\r
+A2.aj\r
+Cl2.java\r
+HW.java\r
+A3.aj\r
+Cl3.java\r
+A4.aj\r
+-verbose\r
+-noExit\r
diff --git a/ajde/testdata/BuildCancelling/HW.java b/ajde/testdata/BuildCancelling/HW.java
new file mode 100644 (file)
index 0000000..3f8aaf8
--- /dev/null
@@ -0,0 +1,13 @@
+
+public class HW {
+       public static void main(String[] args) {
+               callPrint("Hello");
+               callPrint(" ");
+               callPrint("World");
+               callPrint("\n");
+       }
+       
+       public static void callPrint(String s) {
+               System.out.print(s);            
+       }
+}
\ No newline at end of file
diff --git a/ajde/testdata/BuildCancelling/LoadsaCode.lst b/ajde/testdata/BuildCancelling/LoadsaCode.lst
new file mode 100644 (file)
index 0000000..e313f34
--- /dev/null
@@ -0,0 +1,7 @@
+A1.aj\r
+A2.aj\r
+HW.java\r
+A3.aj\r
+A4.aj\r
+-verbose\r
+-noExit\r
index ecd8471ce57ebf55d7714d5cd7e41268374676bd..b66c019edfaaf097fefce205f361730526cf5eff 100644 (file)
@@ -35,6 +35,7 @@ public class AjdeTests extends TestCase {
                suite.addTestSuite(ResourceCopyTestCase.class);
                suite.addTestSuite(ModelPerformanceTest.class);
                suite.addTestSuite(SavedModelConsistencyTest. class);
+               suite.addTestSuite(BuildCancellingTest.class);
                suite.addTestSuite(JarManifestTest.class);
                
         //$JUnit-END$
diff --git a/ajde/testsrc/org/aspectj/ajde/BuildCancellingTest.java b/ajde/testsrc/org/aspectj/ajde/BuildCancellingTest.java
new file mode 100644 (file)
index 0000000..5d07718
--- /dev/null
@@ -0,0 +1,410 @@
+/* *******************************************************************
+ * Copyright (c) 2004 Contributors.
+ * All rights reserved. 
+ * This program and the accompanying materials are made available 
+ * under the terms of the Common Public License v1.0 
+ * which accompanies this distribution and is available at 
+ * http://www.eclipse.org/legal/cpl-v10.html 
+ *  
+ * Contributors: 
+ *    Andy Clement     Initial version
+ * ******************************************************************/
+
+package org.aspectj.ajde;
+
+import java.io.File;
+import java.util.ArrayList;
+import java.util.Iterator;
+import java.util.List;
+
+import org.aspectj.ajde.internal.CompilerAdapter;
+import org.aspectj.util.FileUtil;
+
+/**
+ * It is now possible to cancel the compiler during either the
+ * compilation or weaving phases - this testcase verifies a few
+ * cases, making sure the process stops when expected.  It can
+ * check the disk contents, but it doesn't right now.
+ * 
+ * Two different .lst files are used during these tests: LoadsaCode.lst and 
+ * EvenMoreCode.lst which contain mixes of aspects and classes
+ * 
+ * Here are some things to think about that will help you understand what is 
+ * on the disk when we cancel the compiler.
+ * 
+ * There are 3 important phases worth remembering :
+ * - Compile all the types 
+ * - Weave all the aspects
+ * - Weave all the classes
+ * 
+ * Each of those steps goes through all the types.  This
+ * means during the 'weave all the aspects' step we are 
+ * jumping over classes and during the 'weave all the
+ * classes ' step we are jumping over aspects.  Why is this important?
+ * 
+ *  
+ * We only write bytes out during the 'weave all the classes ' phase and it is even
+ * during that phase that we write out the bytes for aspects.  This means if you cancel
+ * during compilation or during the weaving of aspects - there will be nothing on the 
+ * disk.  If you cancel whilst in the 'weave all the classes ' phase then the disk
+ * will contain anything finished with by the cancellation point.
+ */
+public class BuildCancellingTest extends AjdeTestCase {
+
+       private CompilerAdapter compilerAdapter;
+       public static final String PROJECT_DIR = "BuildCancelling";
+       public static final String binDir = "bin";
+
+       public BuildCancellingTest(String arg0) {
+               super(arg0);
+       }
+
+       // Ensure the output directory is clean
+       protected void setUp() throws Exception {
+               super.setUp(PROJECT_DIR);
+               FileUtil.deleteContents(openFile(binDir));
+       }
+       
+
+       
+       /**
+        * After first compilation message, get it to cancel, there should be one more warning
+        * message about cancelling the compile and their should be nothing on the disk.
+        */
+       public void testCancelFirstCompile() {
+               System.out.println("\n\n\ntestCancelFirstCompile: Building with LoadsaCode.lst");
+               compilerAdapter = new CompilerAdapter();
+               compilerAdapter.showInfoMessages(false);
+               BuildProgMon programmableBPM = new BuildProgMon();
+
+               programmableBPM.cancelOn("compiled:",1); // Force a cancel after the first compile occurs
+
+               compilerAdapter.compile(
+                       (String) openFile("LoadsaCode.lst").getAbsolutePath(),
+                       programmableBPM,
+                       false);
+                       
+               assertTrue("Should have cancelled after first compile?:"+programmableBPM.numCompiledMessages,
+                 programmableBPM.numCompiledMessages==1);
+               
+// Comment out to check the disk contents  
+//             assertTrue("As weaving was cancelled, no files should have been written out, but I found:"+wovenClassesFound(),
+//               wovenClassesFound()==0);
+                 
+               boolean expectedCancelMessageFound = checkFor("Compilation cancelled as requested");
+               if (!expectedCancelMessageFound) dumpTaskData(); // Useful for debugging
+               assertTrue("Failed to get warning message about compilation being cancelled!", expectedCancelMessageFound);
+       }
+       
+       
+       
+       /**
+        * After third compilation message, get it to cancel, there should be one more warning
+        * message about cancelling the compile and their should be nothing on the disk.
+        */
+       public void testCancelThirdCompile() {
+               System.out.println("\n\n\ntestCancelThirdCompile: Building with LoadsaCode.lst");
+               compilerAdapter = new CompilerAdapter();
+               compilerAdapter.showInfoMessages(false);
+               BuildProgMon programmableBPM = new BuildProgMon();
+
+               programmableBPM.cancelOn("compiled:",3); // Force a cancel after the third compile occurs
+
+               compilerAdapter.compile(
+                       (String) openFile("LoadsaCode.lst").getAbsolutePath(),
+                       programmableBPM,
+                       false);
+                       
+               assertTrue("Should have cancelled after third compile?:"+programmableBPM.numCompiledMessages,
+                 programmableBPM.numCompiledMessages==3);
+                 
+//             Comment out to check the disk contents            
+//             assertTrue("As weaving was cancelled, no files should have been written out, but I found:"+wovenClassesFound(),
+//               wovenClassesFound()==0);
+
+               boolean expectedCancelMessageFound = checkFor("Compilation cancelled as requested");
+               if (!expectedCancelMessageFound) dumpTaskData(); // Useful for debugging
+               assertTrue("Failed to get warning message about compilation being cancelled!", expectedCancelMessageFound);
+       }
+
+
+       /**
+        * After first weave aspect message, get it to cancel, there should be one more warning
+        * message about cancelling the weave and their should be nothing on the disk.
+        */
+       public void testCancelFirstAspectWeave() {
+               System.out.println("\n\n\ntestCancelFirstAspectWeave: Building with LoadsaCode.lst");
+               compilerAdapter = new CompilerAdapter();
+               compilerAdapter.showInfoMessages(false);
+               BuildProgMon programmableBPM = new BuildProgMon();
+
+               programmableBPM.cancelOn("woven aspect ",1); // Force a cancel after the first weave aspect occurs
+
+               compilerAdapter.compile((String) openFile("LoadsaCode.lst").getAbsolutePath(),programmableBPM,false);
+                       
+               assertTrue("Should have cancelled after first aspect weave?:"+programmableBPM.numWovenAspectMessages,
+                 programmableBPM.numWovenAspectMessages==1);
+
+//             Comment out to check the disk contents
+//             assertTrue("As weaving was cancelled, no files should have been written out?:"+wovenClassesFound(),
+//               wovenClassesFound()==0);
+
+               boolean expectedCancelMessageFound = checkFor("Weaving cancelled as requested");
+               if (!expectedCancelMessageFound) dumpTaskData(); // Useful for debugging
+               assertTrue("Failed to get warning message about weaving being cancelled!", expectedCancelMessageFound);
+       }
+       
+
+
+       /**
+        * After third weave aspect message, get it to cancel, there should be one more warning
+        * message about cancelling the weave and their should be nothing on the disk.
+        */     
+       public void testCancelThirdAspectWeave() {
+               System.out.println("\n\n\ntestCancelThirdAspectWeave: Building with LoadsaCode.lst");
+               compilerAdapter = new CompilerAdapter();
+               compilerAdapter.showInfoMessages(false);
+               
+               BuildProgMon programmableBPM = new BuildProgMon();
+               // Force a cancel after the third weave occurs.
+               // This should leave two class files on disk - I think?
+               programmableBPM.cancelOn("woven aspect ",3); 
+                       
+               compilerAdapter.compile(
+                       (String) openFile("LoadsaCode.lst").getAbsolutePath(),
+                       programmableBPM,
+                       false);
+               
+               assertTrue("Should have cancelled after third weave?:"+programmableBPM.numWovenAspectMessages,
+                 programmableBPM.numWovenAspectMessages==3);
+                 
+//             Comment out to check disk contents
+//             assertTrue("As weaving was cancelled, no files should have been written out?:"+wovenClassesFound(),
+//               wovenClassesFound()==0);
+                 
+               boolean expectedCancelMessageFound = checkFor("Weaving cancelled as requested");
+               if (!expectedCancelMessageFound) dumpTaskData(); // Useful for debugging
+               assertTrue("Failed to get warning message about weaving being cancelled!", expectedCancelMessageFound);
+
+       }
+       
+       /**
+        * After first weave class message, get it to cancel, there should be one more
+        * warning message about cancelling the weave and their should be nothing on the
+        * disk.
+        * 
+        * EvenMoreCode.lst contains:
+        * A1.aj
+        * Cl1.java
+        * A2.aj
+        * Cl2.java
+        * HW.java
+        * A3.aj
+        * Cl3.java
+        * A4.aj
+        * 
+        */
+       public void testCancelFirstClassWeave() {
+               System.out.println("testCancelFirstClassWeave: Building with EvenMoreCode.lst");
+               compilerAdapter = new CompilerAdapter();
+               compilerAdapter.showInfoMessages(false);
+               BuildProgMon programmableBPM = new BuildProgMon();
+
+               programmableBPM.cancelOn("woven class",1); 
+       
+               compilerAdapter.compile(
+                       (String) openFile("EvenMoreCode.lst").getAbsolutePath(),
+                       programmableBPM,
+                       false);
+       
+//             Should just be A1 on the disk - uncomment this line to verify that!
+//             assertTrue("Incorrect disk contents found",diskContents("A1"));
+
+               assertTrue("Should have cancelled after first class weave?:"+programmableBPM.numWovenClassMessages,
+                 programmableBPM.numWovenClassMessages==1);
+                 
+               boolean expectedCancelMessageFound = checkFor("Weaving cancelled as requested");
+               if (!expectedCancelMessageFound) dumpTaskData(); // Useful for debugging
+               assertTrue("Failed to get warning message about weaving being cancelled!", expectedCancelMessageFound);
+       }
+       
+       
+       /**
+        * After first weave aspect message, get it to cancel, there should be one more
+        * warning message about cancelling the weave and their should be nothing on the
+        * disk.
+        * 
+        * EvenMoreCode.lst contains:
+        * A1.aj
+        * Cl1.java
+        * A2.aj
+        * Cl2.java
+        * HW.java
+        * A3.aj
+        * Cl3.java
+        * A4.aj
+        * 
+        */
+       public void testCancelSecondClassWeave() {
+               System.out.println("testCancelSecondClassWeave: Building with EvenMoreCode.lst");
+               compilerAdapter = new CompilerAdapter();
+               compilerAdapter.showInfoMessages(false);
+               BuildProgMon programmableBPM = new BuildProgMon();
+
+               programmableBPM.cancelOn("woven class",2); 
+       
+               compilerAdapter.compile(
+                       (String) openFile("EvenMoreCode.lst").getAbsolutePath(),
+                       programmableBPM,
+                       false);
+       
+//             Uncomment this line to verify disk contents
+//             assertTrue("Incorrect disk contents found",diskContents("A1 Cl1 A2"));
+
+               assertTrue("Should have cancelled after first class weave?:"+programmableBPM.numWovenClassMessages,
+                 programmableBPM.numWovenClassMessages==2);
+                 
+               boolean expectedCancelMessageFound = checkFor("Weaving cancelled as requested");
+               if (!expectedCancelMessageFound) dumpTaskData(); // Useful for debugging
+               assertTrue("Failed to get warning message about weaving being cancelled!", expectedCancelMessageFound);
+
+       }
+       
+       
+       // ----
+       // Helper classes and methods
+       
+
+       private class BuildProgMon implements BuildProgressMonitor {
+               
+        public int numWovenClassMessages = 0;
+        public int numWovenAspectMessages = 0;
+        public int numCompiledMessages = 0;
+        
+               private String programmableString;
+               private int count;
+               private List messagesReceived = new ArrayList();
+               private int currentVal;
+        
+               public void start(String configFile) {
+                       currentVal = 0;
+               }
+
+               public void cancelOn(String string,int count) {
+                       programmableString = string;
+                       this.count = count;
+               }
+
+               public void setProgressText(String text) {
+                       String newText = text+" [Percentage="+currentVal+"%]";
+                       messagesReceived.add(newText);
+                       if (text.startsWith("woven aspect ")) numWovenAspectMessages++;
+                       if (text.startsWith("woven class ")) numWovenClassMessages++;
+                       if (text.startsWith("compiled:")) numCompiledMessages++;
+                       if (programmableString != null
+                               && text.indexOf(programmableString) != -1) {
+                               count--;
+                               if (count==0) {
+                                       System.out.println("Just got message '"+newText+"' - asking build to cancel");
+                                       compilerAdapter.requestCompileExit();
+                                       programmableString = null;
+                               }
+                       }
+               }
+               
+               public boolean containsMessage(String prefix,String distinguishingMarks) {
+                       for (Iterator iter = messagesReceived.iterator(); iter.hasNext();) {
+                               String element = (String) iter.next();
+                               if (element.startsWith(prefix) &&
+                                   element.indexOf(distinguishingMarks)!=-1) return true;
+                       }
+                       return false;
+               }
+               
+               public void dumpMessages() {
+                       System.out.println("ProgressMonitorMessages");
+                       for (Iterator iter = messagesReceived.iterator(); iter.hasNext();) {
+                               String element = (String) iter.next();
+                               System.out.println(element);
+                       }
+               }
+
+               public void setProgressBarVal(int newVal) {
+                       this.currentVal = newVal;
+               }
+
+               public void incrementProgressBarVal() {
+                       System.err.println("ipbv");
+               }
+
+               public void setProgressBarMax(int maxVal) {
+                       System.err.println("spbm"+maxVal);
+               }
+
+               public int getProgressBarMax() {
+                       return 100; // Causes setProgressBarVal() to be fed what are effectively percentages
+               }
+
+               public void finish() {
+               }
+
+       }
+       
+       private boolean diskContents(String shouldExist) {
+               String[] fullList = new String[] { "A1","A2","A3","A4","Cl1","Cl2","Cl3","HW"};
+               boolean isOK = true;
+               for (int i = 0; i < fullList.length; i++) {
+                       String file = fullList[i];
+                       if (shouldExist.indexOf(file)!=-1) {
+                               // There should be a class file called this
+                               if (!openFile("bin/"+file+".class").exists()) {
+                                       isOK=false; 
+                                       System.out.println("Couldn't find this expected file: "+file+".class");
+                               }
+                       } else {
+                               // There should NOT be a class file called this
+                               if (openFile("bin/"+file+".class").exists()) {
+                                       isOK=false;
+                                       System.out.println("Found this file when not expected: "+file+".class");
+                               }
+                       }
+               }
+               return isOK;
+       }
+       
+       private int wovenClassesFound() {
+               int found = 0;
+               File fA1 = openFile("bin/A1.class");
+               File fA2 = openFile("bin/A2.class");
+               File fA3 = openFile("bin/A3.class");
+               File fA4 = openFile("bin/A4.class");
+               File fHW = openFile("bin/HW.class");
+
+               found+=(fA1.exists()?1:0);
+               found+=(fA2.exists()?1:0);
+               found+=(fA3.exists()?1:0);
+               found+=(fA4.exists()?1:0);
+               found+=(fHW.exists()?1:0);
+               return found;
+       }
+       
+
+       private boolean checkFor(String what) {
+               List ll = ideManager.getCompilationSourceLineTasks();
+               for (Iterator iter = ll.iterator(); iter.hasNext();) {
+                       Object element = (Object) iter.next();
+                       if (element.toString().indexOf(what) != -1)
+                               return true;
+               }
+               return false;
+       }
+       
+       private void dumpTaskData() {
+               List ll = ideManager.getCompilationSourceLineTasks();
+               for (Iterator iter = ll.iterator(); iter.hasNext();) {
+                       Object element = (Object) iter.next();
+                       System.out.println("RecordedMessage>"+element);
+               }
+       }
+
+}
index 1686c64b05d89e610666f9dbb17113354d00fade..59d5f33662c546eef962d52d1ace9a7899d73d3b 100644 (file)
@@ -26,4 +26,15 @@ public interface IProgressListener {
         * @param percentDone how much work is completed so far
         */
        public void setProgress(double percentDone);
+       
+    /**
+     * @param cancelRequested true if the caller wants the current compilation to stop asap
+     */
+       public void setCancelledRequested(boolean cancelRequested);
+       
+       /**
+        * @return true if the consumer of the progress info would like the compileation to stop
+        */
+       public boolean isCancelledRequested();
+       
 }
index d679d12b910f2ce704e89508e7de6db1f9f822c6..a6eacc40ae45c49a2f344484b5590f458f6aa455 100644 (file)
@@ -21,6 +21,7 @@ import java.util.Map;
 import org.aspectj.ajdt.internal.compiler.lookup.EclipseFactory;
 import org.aspectj.bridge.IMessage;
 import org.aspectj.bridge.IMessageHandler;
+import org.aspectj.bridge.IProgressListener;
 import org.aspectj.weaver.bcel.BcelWeaver;
 import org.aspectj.weaver.bcel.BcelWorld;
 import org.eclipse.jdt.internal.compiler.CompilationResult;
@@ -44,6 +45,7 @@ public class AjCompilerAdapter implements ICompilerAdapter {
        private boolean reportedErrors;
        private boolean isXNoWeave;
        private IIntermediateResultsRequestor intermediateResultsRequestor;
+       private IProgressListener progressListener;
        private IOutputClassFileNameProvider outputFileNameProvider;
        private WeaverMessageHandler weaverMessageHandler;
        private List /* InterimCompilationResult */ binarySources = new ArrayList();
@@ -73,6 +75,7 @@ public class AjCompilerAdapter implements ICompilerAdapter {
                                                         BcelWeaver weaver,
                                                         EclipseFactory eFactory,
                                                         IIntermediateResultsRequestor intRequestor,
+                                                        IProgressListener progressListener,
                                                         IOutputClassFileNameProvider outputFileNameProvider,
                                                         Map binarySourceEntries, /* fileName |-> List<UnwovenClassFile> */
                                                         Collection /* InterimCompilationResult */ resultSetForFullWeave,
@@ -81,6 +84,7 @@ public class AjCompilerAdapter implements ICompilerAdapter {
                this.isBatchCompile = isBatchCompile;
                this.weaver = weaver;
                this.intermediateResultsRequestor = intRequestor;
+               this.progressListener = progressListener;
                this.outputFileNameProvider = outputFileNameProvider;
                this.isXNoWeave = isXNoWeave;
                this.resultSetForFullWeave = resultSetForFullWeave;
@@ -130,6 +134,7 @@ public class AjCompilerAdapter implements ICompilerAdapter {
                } else {
                        resultsPendingWeave.add(intRes);
                }
+               
        }
        
        public void beforeResolving(CompilationUnitDeclaration unit, ICompilationUnit sourceUnit, boolean verifyMethods, boolean analyzeCode, boolean generateCode) {
@@ -212,7 +217,7 @@ public class AjCompilerAdapter implements ICompilerAdapter {
                        addAllKnownClassesToWeaveList();
                }
 
-               weaver.weave(new WeaverAdapter(this,weaverMessageHandler));
+               weaver.weave(new WeaverAdapter(this,weaverMessageHandler,progressListener));
        }
        
        private void addAllKnownClassesToWeaveList() {
index 6eead0082355d1f554dcf8353f56acaf2ceaf92d..345b928ad44948ef9c7b709937b856abb35e5154 100644 (file)
@@ -14,9 +14,12 @@ import java.util.Enumeration;
 import java.util.Hashtable;
 import java.util.Iterator;
 
+import org.aspectj.bridge.IProgressListener;
 import org.aspectj.weaver.IClassFileProvider;
 import org.aspectj.weaver.IWeaveRequestor;
 import org.aspectj.weaver.bcel.UnwovenClassFile;
+import org.eclipse.core.runtime.OperationCanceledException;
+import org.eclipse.jdt.internal.compiler.problem.AbortCompilation;
 
 /**
  * @author colyer
@@ -32,13 +35,24 @@ public class WeaverAdapter implements IClassFileProvider, IWeaveRequestor, Itera
        private InterimCompilationResult nowProcessing;
        private InterimCompilationResult lastReturnedResult;
        private WeaverMessageHandler weaverMessageHandler;
+       private IProgressListener progressListener;
        private boolean finalPhase = false;
+       private int localIteratorCounter;
        
+       // Fields related to progress monitoring
+       private int progressMaxTypes;
+       private String progressPhasePrefix;
+       private double fromPercent;
+       private double toPercent = 100.0;
+       private int progressCompletionCount;
+
        
        public WeaverAdapter(AjCompilerAdapter forCompiler,
-                                                WeaverMessageHandler weaverMessageHandler) { 
-               this.compilerAdapter = forCompiler; 
+                                                WeaverMessageHandler weaverMessageHandler,
+                                                IProgressListener progressListener) { 
+               this.compilerAdapter = forCompiler;
                this.weaverMessageHandler = weaverMessageHandler;
+               this.progressListener = progressListener;
        }
        
        /* (non-Javadoc)
@@ -46,6 +60,7 @@ public class WeaverAdapter implements IClassFileProvider, IWeaveRequestor, Itera
         */
        public Iterator getClassFileIterator() {
                classFileIndex = 0;
+               localIteratorCounter = 0;
                nowProcessing = null;
                lastReturnedResult = null;
                resultIterator = compilerAdapter.resultsPendingWeave.iterator();
@@ -98,8 +113,10 @@ public class WeaverAdapter implements IClassFileProvider, IWeaveRequestor, Itera
                                finishedWith(lastReturnedResult);
                        }
                }
+               localIteratorCounter++;
                lastReturnedResult = nowProcessing;
                weaverMessageHandler.setCurrentResult(nowProcessing.result());
+               // weaverMessageHandler.handleMessage(new Message("weaving " + nowProcessing.fileName(),IMessage.INFO, null, null));
                return nowProcessing.unwovenClassFiles()[classFileIndex++];
        }
        /* (non-Javadoc)
@@ -108,22 +125,50 @@ public class WeaverAdapter implements IClassFileProvider, IWeaveRequestor, Itera
        public void remove() {
                throw new UnsupportedOperationException();
        }
-       
+
        
        // IWeaveRequestor
        // =====================================================================================
-       
+
        // weave phases as indicated by bcelWeaver...
-       public void processingReweavableState() {}
-       public void addingTypeMungers() {}
-       public void weavingAspects() {}
-       public void weavingClasses() {finalPhase = true;}
+       public void processingReweavableState() {
+               
+               // progress reporting logic
+               fromPercent = 50.0; // Assume weaving takes 50% of the progress bar...
+           recordProgress("processing reweavable state");
+       }
+       
+       public void addingTypeMungers() {
+               
+               // progress reporting logic
+               // At this point we have completed one iteration through all the classes/aspects 
+               // we'll be dealing with, so let us remember this max value for localIteratorCounter
+               // (for accurate progress reporting)
+               recordProgress("adding type mungers");
+               progressMaxTypes = localIteratorCounter;
+       }
+       
+       public void weavingAspects() {
+               
+               // progress reporting logic
+               progressPhasePrefix="woven aspect ";
+               progressCompletionCount=0; // Start counting from *now*
+       }
+       
+       public void weavingClasses() {
+               finalPhase = true;
+               
+               // progress reporting logic
+               progressPhasePrefix="woven class ";
+       }
        
        public void weaveCompleted() {
                if ((lastReturnedResult != null) && (!lastReturnedResult.result().hasBeenAccepted)) {
                        finishedWith(lastReturnedResult);
                }
        }
+       
+
 
        /* (non-Javadoc)
         * @see org.aspectj.weaver.IWeaveRequestor#acceptResult(org.aspectj.weaver.bcel.UnwovenClassFile)
@@ -135,6 +180,20 @@ public class WeaverAdapter implements IClassFileProvider, IWeaveRequestor, Itera
                AjClassFile ajcf = new AjClassFile(className.toCharArray(),
                                                                                   result.getBytes());
                lastReturnedResult.result().record(ajcf.fileName(),ajcf);
+               
+               if (progressListener != null) {
+                       progressCompletionCount++;
+                       
+                       // Smoothly take progress from 'fromPercent' to 'toPercent'
+                       recordProgress(
+                         fromPercent
+                         +((progressCompletionCount/(double)progressMaxTypes)*(toPercent-fromPercent)),
+                         progressPhasePrefix+result.getClassName()+" (from "+nowProcessing.fileName()+")");
+
+                       if (progressListener.isCancelledRequested()) {
+                     throw new AbortCompilation(true,new OperationCanceledException("Weaving cancelled as requested"));
+                       }
+               }
        }
 
        // helpers...
@@ -160,4 +219,17 @@ public class WeaverAdapter implements IClassFileProvider, IWeaveRequestor, Itera
                        table.remove(victim);
                }
        }
+       
+       private void recordProgress(String message) {
+               if (progressListener!=null) {
+                       progressListener.setText(message);
+               }
+       }
+       
+       private void recordProgress(double percentage,String message) {
+               if (progressListener!=null) {
+                       progressListener.setProgress(percentage/100);
+                       progressListener.setText(message);
+               }
+       }
 }
\ No newline at end of file
index f49ea9e3c1aa16dea285d209f00272f6ccf5f4dd..dc1eef8f5f0faebd52f68e89bcdc42b7a10e3f24 100644 (file)
@@ -31,6 +31,7 @@ import org.aspectj.bridge.*;
 import org.aspectj.util.FileUtil;
 import org.aspectj.weaver.World;
 import org.aspectj.weaver.bcel.*;
+import org.eclipse.core.runtime.OperationCanceledException;
 import org.eclipse.jdt.core.compiler.*;
 import org.eclipse.jdt.internal.compiler.*;
 import org.eclipse.jdt.internal.compiler.batch.*;
@@ -38,6 +39,7 @@ import org.eclipse.jdt.internal.compiler.batch.FileSystem;
 import org.eclipse.jdt.internal.compiler.env.*;
 import org.eclipse.jdt.internal.compiler.impl.CompilerOptions;
 import org.eclipse.jdt.internal.compiler.parser.Parser;
+import org.eclipse.jdt.internal.compiler.problem.AbortCompilation;
 import org.eclipse.jdt.internal.compiler.problem.DefaultProblemFactory;
 //import org.eclipse.jdt.internal.compiler.util.HashtableOfObject;
 
@@ -158,7 +160,7 @@ public class AjBuildManager implements IOutputClassFileNameProvider,ICompilerAda
                 for (int i = 0; (i < 5) && !files.isEmpty(); i++) {
                     // System.err.println("XXXX inc: " + files);
                     performCompilation(files);
-                    if (handler.hasErrors()) {
+                    if (handler.hasErrors() || (progressListener!=null && progressListener.isCancelledRequested())) {
                         return false;
                     } 
                     files = state.getFilesToCompile(false);
@@ -572,8 +574,11 @@ public class AjBuildManager implements IOutputClassFileNameProvider,ICompilerAda
 
                options.produceReferenceInfo(true); //TODO turn off when not needed
                
-               compiler.compile(getCompilationUnits(filenames, encodings));
-               
+               try {
+                       compiler.compile(getCompilationUnits(filenames, encodings));
+               } catch (OperationCanceledException oce) {
+                       handler.handleMessage(new Message("build cancelled:"+oce.getMessage(),IMessage.WARNING,null,null));
+               }
                // cleanup
                environment.cleanup();
                environment = null;
@@ -592,6 +597,11 @@ public class AjBuildManager implements IOutputClassFileNameProvider,ICompilerAda
                                        progressListener.setText("compiled: " + result.fileName());
                                }
                                state.noteResult(result);
+                               
+                               if (progressListener!=null && progressListener.isCancelledRequested()) { 
+                                       throw new AbortCompilation(true,
+                                         new OperationCanceledException("Compilation cancelled as requested"));
+                               }
                        }
                };
        }
@@ -853,7 +863,9 @@ public class AjBuildManager implements IOutputClassFileNameProvider,ICompilerAda
                
                return new AjCompilerAdapter(forCompiler,batchCompile,bcelWorld,bcelWeaver,
                                                factory,
-                                               getInterimResultRequestor(),this,
+                                               getInterimResultRequestor(),
+                                               progressListener,
+                                               this,
                                                state.binarySourceFiles,
                                                state.resultsFromFile.values(),
                                                buildConfig.isNoWeave());