]> source.dussan.org Git - aspectj.git/commitdiff
mavenized bridge module
authorAndy Clement <aclement@pivotal.io>
Wed, 23 Jan 2019 21:02:59 +0000 (13:02 -0800)
committerAndy Clement <aclement@pivotal.io>
Wed, 23 Jan 2019 21:02:59 +0000 (13:02 -0800)
62 files changed:
bridge/.classpath [deleted file]
bridge/.cvsignore [deleted file]
bridge/.isJava5 [deleted file]
bridge/.project [deleted file]
bridge/build.xml [deleted file]
bridge/pom.xml [new file with mode: 0644]
bridge/src/main/java/org/aspectj/bridge/AbortException.java [new file with mode: 0644]
bridge/src/main/java/org/aspectj/bridge/Constants.java [new file with mode: 0644]
bridge/src/main/java/org/aspectj/bridge/CountingMessageHandler.java [new file with mode: 0644]
bridge/src/main/java/org/aspectj/bridge/ICommand.java [new file with mode: 0644]
bridge/src/main/java/org/aspectj/bridge/ILifecycleAware.java [new file with mode: 0644]
bridge/src/main/java/org/aspectj/bridge/IMessage.java [new file with mode: 0644]
bridge/src/main/java/org/aspectj/bridge/IMessageContext.java [new file with mode: 0644]
bridge/src/main/java/org/aspectj/bridge/IMessageHandler.java [new file with mode: 0644]
bridge/src/main/java/org/aspectj/bridge/IMessageHolder.java [new file with mode: 0644]
bridge/src/main/java/org/aspectj/bridge/IProgressListener.java [new file with mode: 0644]
bridge/src/main/java/org/aspectj/bridge/ISourceLocation.java [new file with mode: 0644]
bridge/src/main/java/org/aspectj/bridge/Message.java [new file with mode: 0644]
bridge/src/main/java/org/aspectj/bridge/MessageHandler.java [new file with mode: 0644]
bridge/src/main/java/org/aspectj/bridge/MessageUtil.java [new file with mode: 0644]
bridge/src/main/java/org/aspectj/bridge/MessageWriter.java [new file with mode: 0644]
bridge/src/main/java/org/aspectj/bridge/ReflectionFactory.java [new file with mode: 0644]
bridge/src/main/java/org/aspectj/bridge/SourceLocation.java [new file with mode: 0644]
bridge/src/main/java/org/aspectj/bridge/Version.java [new file with mode: 0644]
bridge/src/main/java/org/aspectj/bridge/WeaveMessage.java [new file with mode: 0644]
bridge/src/main/java/org/aspectj/bridge/context/CompilationAndWeavingContext.java [new file with mode: 0644]
bridge/src/main/java/org/aspectj/bridge/context/ContextFormatter.java [new file with mode: 0644]
bridge/src/main/java/org/aspectj/bridge/context/ContextToken.java [new file with mode: 0644]
bridge/src/main/java/org/aspectj/bridge/context/PinpointingMessageHandler.java [new file with mode: 0644]
bridge/src/org/aspectj/bridge/AbortException.java [deleted file]
bridge/src/org/aspectj/bridge/Constants.java [deleted file]
bridge/src/org/aspectj/bridge/CountingMessageHandler.java [deleted file]
bridge/src/org/aspectj/bridge/ICommand.java [deleted file]
bridge/src/org/aspectj/bridge/ILifecycleAware.java [deleted file]
bridge/src/org/aspectj/bridge/IMessage.java [deleted file]
bridge/src/org/aspectj/bridge/IMessageContext.java [deleted file]
bridge/src/org/aspectj/bridge/IMessageHandler.java [deleted file]
bridge/src/org/aspectj/bridge/IMessageHolder.java [deleted file]
bridge/src/org/aspectj/bridge/IProgressListener.java [deleted file]
bridge/src/org/aspectj/bridge/ISourceLocation.java [deleted file]
bridge/src/org/aspectj/bridge/Message.java [deleted file]
bridge/src/org/aspectj/bridge/MessageHandler.java [deleted file]
bridge/src/org/aspectj/bridge/MessageUtil.java [deleted file]
bridge/src/org/aspectj/bridge/MessageWriter.java [deleted file]
bridge/src/org/aspectj/bridge/ReflectionFactory.java [deleted file]
bridge/src/org/aspectj/bridge/SourceLocation.java [deleted file]
bridge/src/org/aspectj/bridge/Version.java [deleted file]
bridge/src/org/aspectj/bridge/WeaveMessage.java [deleted file]
bridge/src/org/aspectj/bridge/context/CompilationAndWeavingContext.java [deleted file]
bridge/src/org/aspectj/bridge/context/ContextFormatter.java [deleted file]
bridge/src/org/aspectj/bridge/context/ContextToken.java [deleted file]
bridge/src/org/aspectj/bridge/context/PinpointingMessageHandler.java [deleted file]
bridge/src/test/java/org/aspectj/bridge/CountingMessageHandlerTest.java [new file with mode: 0644]
bridge/src/test/java/org/aspectj/bridge/MessageTest.java [new file with mode: 0644]
bridge/src/test/java/org/aspectj/bridge/VersionTest.java [new file with mode: 0644]
bridge/src/test/java/org/aspectj/bridge/context/CompilationAndWeavingContextTest.java [new file with mode: 0644]
bridge/testsrc/org/aspectj/bridge/BridgeModuleTests.java [deleted file]
bridge/testsrc/org/aspectj/bridge/BridgeTests.java [deleted file]
bridge/testsrc/org/aspectj/bridge/CountingMessageHandlerTest.java [deleted file]
bridge/testsrc/org/aspectj/bridge/MessageTest.java [deleted file]
bridge/testsrc/org/aspectj/bridge/VersionTest.java [deleted file]
bridge/testsrc/org/aspectj/bridge/context/CompilationAndWeavingContextTest.java [deleted file]

diff --git a/bridge/.classpath b/bridge/.classpath
deleted file mode 100644 (file)
index 6544d22..0000000
+++ /dev/null
@@ -1,9 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<classpath>
-       <classpathentry kind="src" path="src"/>
-       <classpathentry kind="src" path="testsrc"/>
-       <classpathentry kind="lib" path="/lib/junit/junit.jar" sourcepath="/lib/junit/junit-src.jar"/>
-       <classpathentry kind="src" path="/util"/>
-       <classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER"/>
-       <classpathentry kind="output" path="bin"/>
-</classpath>
diff --git a/bridge/.cvsignore b/bridge/.cvsignore
deleted file mode 100644 (file)
index 8bdf2ac..0000000
+++ /dev/null
@@ -1,5 +0,0 @@
-bin
-ant.properties
-bridge.mf.txt
-
-bintest
diff --git a/bridge/.isJava5 b/bridge/.isJava5
deleted file mode 100644 (file)
index 136d063..0000000
+++ /dev/null
@@ -1 +0,0 @@
-  
\ No newline at end of file
diff --git a/bridge/.project b/bridge/.project
deleted file mode 100644 (file)
index 91c7551..0000000
+++ /dev/null
@@ -1,18 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<projectDescription>
-       <name>bridge</name>
-       <comment></comment>
-       <projects>
-               <project>util</project>
-       </projects>
-       <buildSpec>
-               <buildCommand>
-                       <name>org.eclipse.jdt.core.javabuilder</name>
-                       <arguments>
-                       </arguments>
-               </buildCommand>
-       </buildSpec>
-       <natures>
-               <nature>org.eclipse.jdt.core.javanature</nature>
-       </natures>
-</projectDescription>
diff --git a/bridge/build.xml b/bridge/build.xml
deleted file mode 100644 (file)
index 349b0aa..0000000
+++ /dev/null
@@ -1,6 +0,0 @@
-<?xml version="1.0"?>
-<!-- see ../build/*.html for explanation -->
-<project name="bridge" default="test" basedir=".">
-    <import file="${basedir}/../build/build.xml"/>  
-</project>
-
diff --git a/bridge/pom.xml b/bridge/pom.xml
new file mode 100644 (file)
index 0000000..03ddca0
--- /dev/null
@@ -0,0 +1,25 @@
+<project xmlns="http://maven.apache.org/POM/4.0.0"
+         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+  xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
+  <modelVersion>4.0.0</modelVersion>
+
+  <parent>
+    <groupId>org.aspectj</groupId>
+    <artifactId>aspectj-parent</artifactId>
+    <version>1.9.3.BUILD-SNAPSHOT</version>
+    <relativePath>..</relativePath>
+  </parent>
+
+  <artifactId>bridge</artifactId>
+  <packaging>jar</packaging>
+  <name>bridge</name>
+
+  <dependencies>
+    <dependency>
+      <groupId>org.aspectj</groupId>
+      <artifactId>util</artifactId>
+      <version>${project.version}</version>
+    </dependency>
+  </dependencies>
+
+</project>
diff --git a/bridge/src/main/java/org/aspectj/bridge/AbortException.java b/bridge/src/main/java/org/aspectj/bridge/AbortException.java
new file mode 100644 (file)
index 0000000..acde7cd
--- /dev/null
@@ -0,0 +1,228 @@
+/* *******************************************************************
+ * Copyright (c) 1999-2001 Xerox Corporation, 
+ *               2002 Palo Alto Research Center, Incorporated (PARC).
+ * All rights reserved. 
+ * This program and the accompanying materials are made available 
+ * under the terms of the Eclipse Public License v1.0 
+ * which accompanies this distribution and is available at 
+ * http://www.eclipse.org/legal/epl-v10.html 
+ *  
+ * Contributors: 
+ *     Xerox/PARC     initial implementation 
+ * ******************************************************************/
+
+package org.aspectj.bridge;
+
+import java.io.PrintStream;
+import java.io.PrintWriter;
+import java.util.ArrayList;
+
+/**
+ * Signal that a process was aborted before completion. This may contain a structured IMessage which indicates why the process was
+ * aborted (e.g., the underlying exception). For processes using try/catch to complete a method abruptly but complete the process
+ * normally (e.g., a test failure causes the test to abort but the reporting and testing continues normally), use the static methods
+ * to borrow and return a "porter" to avoid the expense of constructing a stack trace each time. A porter stack trace is invalid,
+ * and it should only be used to convey a message. E.g., to print the stack of the AbortException and any contained message:
+ * 
+ * <pre>
+ * catch (AbortException ae) {
+ *     IMessage m = ae.getMessage();
+ *     if (!ae.isPorter()) ae.printStackTrace(System.err);
+ *     Throwable thrown = ae.getThrown();
+ *     if (null != thrown) thrown.printStackTrace(System.err);
+ * }
+ * </pre>
+ * 
+ * @author PARC
+ * @author Andy Clement
+ */
+public class AbortException extends RuntimeException { // XXX move porters out, handle proxy better
+
+       private static final long serialVersionUID = -7211791639898586417L;
+
+       private boolean isSilent = false;
+
+       /** used when message text is null */
+       public static final String NO_MESSAGE_TEXT = "AbortException (no message)";
+
+       private static final ArrayList<AbortException> porters = new ArrayList<AbortException>();
+
+       /**
+        * Get a porter exception from the pool. Porter exceptions do <b>not</b> have valid stack traces. They are used only to avoid
+        * generating stack traces when using throw/catch to abruptly complete but continue.
+        */
+       public static AbortException borrowPorter(IMessage message) {
+               AbortException result;
+               synchronized (porters) {
+                       if (porters.size() > 0) {
+                               result = porters.get(0);
+                       } else {
+                               result = new AbortException();
+                               result.setIsSilent(false);
+                       }
+               }
+               result.setIMessage(message);
+               result.isPorter = true;
+               return result;
+       }
+
+       /**
+        * Return (or add) a porter exception to the pool.
+        */
+       public static void returnPorter(AbortException porter) {
+               synchronized (porters) {
+                       if (porters.contains(porter)) {
+                               throw new IllegalStateException("already have " + porter);
+                       } else {
+                               porters.add(porter);
+                       }
+               }
+       }
+
+       /** @return NO_MESSAGE_TEXT or message.getMessage() if not null */
+       private static String extractMessage(IMessage message) {
+               if (null == message) {
+                       return NO_MESSAGE_TEXT;
+               } else {
+                       String m = message.getMessage();
+                       if (null == m) {
+                               return NO_MESSAGE_TEXT;
+                       } else {
+                               return m;
+                       }
+               }
+       }
+
+       /** structured message abort */
+       protected IMessage message;
+
+       /** true if this is a porter exception - only used to hold message */
+       protected boolean isPorter;
+
+       /** abort with default String message */
+       public AbortException() {
+               this("ABORT");
+               isSilent = true;
+       }
+
+       /** abort with message */
+       public AbortException(String s) {
+               super(null != s ? s : NO_MESSAGE_TEXT);
+               this.message = null;
+       }
+
+       /** abort with structured message */
+       public AbortException(IMessage message) {
+               super(extractMessage(message));
+               this.message = message;
+       }
+
+       /** @return IMessage structured message, if set */
+       public IMessage getIMessage() {
+               return message;
+       }
+
+       /**
+        * The stack trace of a porter is invalid; it is only used to carry a message (which may itself have a wrapped exception).
+        * 
+        * @return true if this exception is only to carry exception
+        */
+       public boolean isPorter() {
+               return isPorter;
+       }
+
+       /** @return Throwable at bottom of IMessage chain, if any */
+       public Throwable getThrown() {
+               Throwable result = null;
+               IMessage m = getIMessage();
+               if (null != m) {
+                       result = m.getThrown();
+                       if (result instanceof AbortException) {
+                               return ((AbortException) result).getThrown();
+                       }
+               }
+               return result;
+       }
+
+       private void setIMessage(IMessage message) {
+               this.message = message;
+       }
+
+       // ----------- proxy attempts
+       /**
+        * Get message for this AbortException, either associated explicitly as message or implicitly as IMessage message or its thrown
+        * message.
+        * 
+        * @see java.lang.Throwable#getMessage()
+        */
+       public String getMessage() {
+               String message = super.getMessage();
+               if ((null == message) || (NO_MESSAGE_TEXT == message)) {
+                       IMessage m = getIMessage();
+                       if (null != m) {
+                               message = m.getMessage();
+                               if (null == message) {
+                                       Throwable thrown = m.getThrown();
+                                       if (null != thrown) {
+                                               message = thrown.getMessage();
+                                       }
+                               }
+                       }
+                       if (null == message) {
+                               message = NO_MESSAGE_TEXT; // better than nothing
+                       }
+               }
+               return message;
+       }
+
+       /**
+        * @see java.lang.Throwable#printStackTrace()
+        */
+       public void printStackTrace() {
+               printStackTrace(System.out);
+       }
+
+       /**
+        * Print the stack trace of any enclosed thrown or this otherwise.
+        * 
+        * @see java.lang.Throwable#printStackTrace(PrintStream)
+        */
+       public void printStackTrace(PrintStream s) {
+               IMessage m = getIMessage();
+               Throwable thrown = (null == m ? null : m.getThrown());
+               if (!isPorter() || (null == thrown)) {
+                       s.println("Message: " + m);
+                       super.printStackTrace(s);
+               } else {
+                       thrown.printStackTrace(s);
+               }
+       }
+
+       /**
+        * Print the stack trace of any enclosed thrown or this otherwise.
+        * 
+        * @see java.lang.Throwable#printStackTrace(PrintWriter)
+        */
+       public void printStackTrace(PrintWriter s) {
+               IMessage m = getIMessage();
+               Throwable thrown = (null == m ? null : m.getThrown());
+               if (null == thrown) { // Always print
+                       if (isPorter()) {
+                               s.println("(Warning porter AbortException without thrown)");
+                       }
+                       s.println("Message: " + m);
+                       super.printStackTrace(s);
+               } else {
+                       thrown.printStackTrace(s);
+               }
+       }
+
+       public boolean isSilent() {
+               return isSilent;
+       }
+
+       public void setIsSilent(boolean isSilent) {
+               this.isSilent = isSilent;
+       }
+
+}
diff --git a/bridge/src/main/java/org/aspectj/bridge/Constants.java b/bridge/src/main/java/org/aspectj/bridge/Constants.java
new file mode 100644 (file)
index 0000000..31f2396
--- /dev/null
@@ -0,0 +1,22 @@
+/*******************************************************************************
+ * Copyright (c) 2006 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials 
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ * 
+ * Contributors:
+ *     Matthew Webster - initial implementation
+ *******************************************************************************/
+package org.aspectj.bridge;
+
+public class Constants {
+
+       /* Default resource names for user and generate aop.xml file */
+       public final static String AOP_USER_XML = "META-INF/aop.xml";
+    public final static String AOP_AJC_XML = "META-INF/aop-ajc.xml";
+    
+    /* Resource name for OSGi */
+    public final static String AOP_OSGI_XML = "org/aspectj/aop.xml";
+
+}
diff --git a/bridge/src/main/java/org/aspectj/bridge/CountingMessageHandler.java b/bridge/src/main/java/org/aspectj/bridge/CountingMessageHandler.java
new file mode 100644 (file)
index 0000000..4ce5508
--- /dev/null
@@ -0,0 +1,157 @@
+/* *******************************************************************
+ * Copyright (c) 1999-2001 Xerox Corporation, 
+ *               2002 Palo Alto Research Center, Incorporated (PARC).
+ * All rights reserved. 
+ * This program and the accompanying materials are made available 
+ * under the terms of the Eclipse Public License v1.0 
+ * which accompanies this distribution and is available at 
+ * http://www.eclipse.org/legal/epl-v10.html 
+ *  
+ * Contributors: 
+ *     Xerox/PARC     initial implementation 
+ * ******************************************************************/
+
+package org.aspectj.bridge;
+
+import java.util.Enumeration;
+import java.util.Hashtable;
+
+import org.aspectj.util.LangUtil;
+
+/**
+ * Wrap an IMessageHandler to count messages handled. Messages being ignored by the delegate IMessageHandler are not counted.
+ */
+public class CountingMessageHandler implements IMessageHandler {
+
+       public final IMessageHandler delegate;
+       public final CountingMessageHandler proxy;
+       private final Hashtable<IMessage.Kind, IntHolder> counters;
+
+       public static CountingMessageHandler makeCountingMessageHandler(IMessageHandler handler) {
+               if (handler instanceof CountingMessageHandler) {
+                       return (CountingMessageHandler) handler;
+               } else {
+                       return new CountingMessageHandler(handler);
+               }
+       }
+
+       public CountingMessageHandler(IMessageHandler delegate) {
+               LangUtil.throwIaxIfNull(delegate, "delegate");
+               this.delegate = delegate;
+               this.counters = new Hashtable<IMessage.Kind, IntHolder>();
+               proxy = (delegate instanceof CountingMessageHandler ? (CountingMessageHandler) delegate : null);
+       }
+
+       /** @return delegate.handleMessage(IMessage) */
+       public boolean handleMessage(IMessage message) throws AbortException {
+               if (null != proxy) {
+                       return proxy.handleMessage(message);
+               }
+               if (null != message) {
+                       IMessage.Kind kind = message.getKind();
+                       if (!isIgnoring(kind)) {
+                               increment(kind);
+                       }
+               }
+               return delegate.handleMessage(message);
+       }
+
+       /** @return delegate.isIgnoring(IMessage.Kind) */
+       public boolean isIgnoring(IMessage.Kind kind) {
+               return delegate.isIgnoring(kind);
+       }
+
+       /**
+        * Delegate
+        * 
+        * @see org.aspectj.bridge.IMessageHandler#isIgnoring(org.aspectj.bridge.IMessage.Kind)
+        * @param kind
+        */
+       public void dontIgnore(IMessage.Kind kind) {
+               delegate.dontIgnore(kind);
+       }
+
+       /**
+        * Delegate
+        * 
+        * @see org.aspectj.bridge.IMessageHandler#ignore(org.aspectj.bridge.IMessage.Kind)
+        * @param kind
+        */
+       public void ignore(IMessage.Kind kind) {
+               delegate.ignore(kind);
+       }
+
+       /** @return delegate.toString() */
+       public String toString() {
+               return delegate.toString();
+       }
+
+       /**
+        * Return count of messages seen through this interface.
+        * 
+        * @param kind the IMessage.Kind of the messages to count (if null, count all)
+        * @param orGreater if true, then count this kind and any considered greater by the ordering of IMessage.Kind.COMPARATOR
+        * @return number of messages of this kind (optionally or greater)
+        * @see IMessage.Kind.COMPARATOR
+        */
+       public int numMessages(IMessage.Kind kind, boolean orGreater) {
+               if (null != proxy) {
+                       return proxy.numMessages(kind, orGreater);
+               }
+               int result = 0;
+               if (null == kind) {
+                       for (Enumeration<IntHolder> enu = counters.elements(); enu.hasMoreElements();) {
+                               result += (enu.nextElement()).count;
+                       }
+               } else if (!orGreater) {
+                       result = numMessages(kind);
+               } else {
+                       for (IMessage.Kind k : IMessage.KINDS) {
+                               if (kind.isSameOrLessThan(k)) {
+                                       result += numMessages(k);
+                               }
+                       }
+               }
+               return result;
+       }
+
+       /**
+        * @return true if 0 is less than <code>numMessages(IMessage.ERROR, true)</code>
+        */
+       public boolean hasErrors() {
+               return (0 < numMessages(IMessage.ERROR, true));
+       }
+
+       private int numMessages(IMessage.Kind kind) {
+               if (null != proxy) {
+                       return proxy.numMessages(kind);
+               }
+               IntHolder counter = counters.get(kind);
+               return (null == counter ? 0 : counter.count);
+       }
+
+       private void increment(IMessage.Kind kind) {
+               if (null != proxy) {
+                       throw new IllegalStateException("not called when proxying");
+               }
+
+               IntHolder counter = counters.get(kind);
+               if (null == counter) {
+                       counter = new IntHolder();
+                       counters.put(kind, counter);
+               }
+               counter.count++;
+       }
+
+       private static class IntHolder {
+               int count;
+       }
+
+       public void reset() {
+               if (proxy != null) {
+                       proxy.reset();
+               }
+               counters.clear();
+       }
+
+}
diff --git a/bridge/src/main/java/org/aspectj/bridge/ICommand.java b/bridge/src/main/java/org/aspectj/bridge/ICommand.java
new file mode 100644 (file)
index 0000000..b77d58e
--- /dev/null
@@ -0,0 +1,39 @@
+/* *******************************************************************
+ * Copyright (c) 1999-2001 Xerox Corporation, 
+ *               2002 Palo Alto Research Center, Incorporated (PARC).
+ * All rights reserved. 
+ * This program and the accompanying materials are made available 
+ * under the terms of the Eclipse Public License v1.0 
+ * which accompanies this distribution and is available at 
+ * http://www.eclipse.org/legal/epl-v10.html 
+ *  
+ * Contributors: 
+ *     Xerox/PARC     initial implementation 
+ * ******************************************************************/
+
+
+package org.aspectj.bridge;
+
+
+/**
+ * Command wrapper with collecting parameter for messages.
+ */
+public interface ICommand {
+    /**
+     * Run command with the given options.
+     * @param args the String[] options for the command
+     * @param handler the IMessageHandler for all output from
+     * the command
+     * @return true if the command completed successfully
+     */
+    boolean runCommand(String[] args, IMessageHandler handler);
+    
+    /**
+     * Rerun the command.
+     * 
+     * @param handler the IMessageHandler for all output from the command
+     * 
+     * @return true if the command completed successfully
+     */
+       boolean repeatCommand(IMessageHandler handler);   
+}
diff --git a/bridge/src/main/java/org/aspectj/bridge/ILifecycleAware.java b/bridge/src/main/java/org/aspectj/bridge/ILifecycleAware.java
new file mode 100644 (file)
index 0000000..c5ac9b1
--- /dev/null
@@ -0,0 +1,35 @@
+/* *******************************************************************
+ * Copyright (c) 2006 Contributors.
+ * All rights reserved. 
+ * This program and the accompanying materials are made available 
+ * under the terms of the Eclipse Public License v1.0 
+ * which accompanies this distribution and is available at 
+ * http://eclipse.org/legal/epl-v10.html 
+ *  
+ * Contributors: 
+ *   Adrian Colyer                     Initial implementation
+ * ******************************************************************/
+package org.aspectj.bridge;
+
+/**
+ * Interface that can be implemented by MessageHandlers that need to 
+ * perform some additional processing when a build is starting and 
+ * when it has finished.
+ * 
+ * @author Adrian Colyer
+ * @since 1.5.1
+ */
+public interface ILifecycleAware {
+
+       /**
+        * called when a build starts
+        */
+       void buildStarting(boolean isIncremental);
+       
+       /**
+        * called when a batch build finishes
+        *
+        */
+       void buildFinished(boolean wasIncremental);
+       
+}
diff --git a/bridge/src/main/java/org/aspectj/bridge/IMessage.java b/bridge/src/main/java/org/aspectj/bridge/IMessage.java
new file mode 100644 (file)
index 0000000..a32a631
--- /dev/null
@@ -0,0 +1,150 @@
+/* *******************************************************************
+ * Copyright (c) 1999-2001 Xerox Corporation, 
+ *               2002 Palo Alto Research Center, Incorporated (PARC).
+ * All rights reserved. 
+ * This program and the accompanying materials are made available 
+ * under the terms of the Eclipse Public License v1.0 
+ * which accompanies this distribution and is available at 
+ * http://www.eclipse.org/legal/epl-v10.html 
+ *  
+ * Contributors: 
+ *     Xerox/PARC     initial implementation 
+ * ******************************************************************/
+
+package org.aspectj.bridge;
+
+import java.util.Arrays;
+import java.util.Collections;
+import java.util.Comparator;
+import java.util.List;
+
+/**
+ * Wrap message with any associated throwable or source location.
+ */
+public interface IMessage {
+       /** no messages */
+       public static final IMessage[] RA_IMessage = new IMessage[0];
+
+       // int values must sync with KINDS order below
+       public static final Kind WEAVEINFO = new Kind("weaveinfo", 5);
+       public static final Kind INFO = new Kind("info", 10);
+       public static final Kind DEBUG = new Kind("debug", 20);
+       public static final Kind TASKTAG = new Kind("task", 25); // represents a 'TODO' from eclipse - producted by the compiler and
+                                                                                                                               // consumed by AJDT
+       public static final Kind WARNING = new Kind("warning", 30);
+       public static final Kind ERROR = new Kind("error", 40);
+       public static final Kind FAIL = new Kind("fail", 50);
+       public static final Kind ABORT = new Kind("abort", 60);
+       // XXX prefer another Kind to act as selector for "any",
+       // but can't prohibit creating messages with it.
+       // public static final Kind ANY = new Kind("any-selector", 0);
+
+       /**
+        * list of Kind in precedence order. 0 is less than IMessage.Kind.COMPARATOR.compareTo(KINDS.get(i), KINDS.get(i + 1))
+        */
+       public static final List<Kind> KINDS = Collections.unmodifiableList(Arrays.asList(new Kind[] { WEAVEINFO, INFO, DEBUG, TASKTAG,
+                       WARNING, ERROR, FAIL, ABORT }));
+
+       /** @return non-null String with simple message */
+       String getMessage();
+
+       /** @return the kind of this message */
+       Kind getKind();
+
+       /** @return true if this is an error */
+       boolean isError();
+
+       /** @return true if this is a warning */
+       boolean isWarning();
+
+       /** @return true if this is an internal debug message */
+       boolean isDebug();
+
+       /** @return true if this is information for the user */
+       boolean isInfo();
+
+       /** @return true if the process is aborting */
+       boolean isAbort(); // XXX ambiguous
+
+       /** @return true if this is a task tag message */
+       boolean isTaskTag();
+
+       /** @return true if something failed */
+       boolean isFailed();
+
+       /** Caller can verify if this message came about because of a DEOW */
+       boolean getDeclared();
+
+       /** Return the ID of the message where applicable, see IProblem for list of valid IDs */
+       int getID();
+
+       /** Return the start position of the problem (inclusive), or -1 if unknown. */
+       int getSourceStart();
+
+       /** Return the end position of the problem (inclusive), or -1 if unknown. */
+       int getSourceEnd();
+
+       /** @return Throwable associated with this message, or null if none */
+       Throwable getThrown();
+
+       /** @return source location associated with this message, or null if none */
+       ISourceLocation getSourceLocation();
+
+       public static final class Kind implements Comparable<IMessage.Kind> {
+               public static final Comparator<IMessage.Kind> COMPARATOR = new Comparator<IMessage.Kind>() {
+                       public int compare(IMessage.Kind one, IMessage.Kind two) {
+                               if (null == one) {
+                                       return (null == two ? 0 : -1);
+                               } else if (null == two) {
+                                       return 1;
+                               } else if (one == two) {
+                                       return 0;
+                               } else {
+                                       return (one.precedence - two.precedence);
+                               }
+                       }
+               };
+
+               /**
+                * @param kind the Kind floor
+                * @return false if kind is null or this has less precedence than kind, true otherwise.
+                */
+               public boolean isSameOrLessThan(Kind kind) {
+                       return (0 >= COMPARATOR.compare(this, kind));
+               }
+
+               public int compareTo(IMessage.Kind other) {
+                       return COMPARATOR.compare(this, other);
+               }
+
+               private final int precedence;
+               private final String name;
+
+               private Kind(String name, int precedence) {
+                       this.name = name;
+                       this.precedence = precedence;
+               }
+
+               public String toString() {
+                       return name;
+               }
+       }
+
+       /**
+        * @return Detailed information about the message. For example, for declare error/warning messages this returns information
+        *         about the corresponding join point's static part.
+        */
+       public String getDetails();
+
+       /**
+        * @return List of <code>ISourceLocation</code> instances that indicate additional source locations relevent to this message as
+        *         specified by the message creator. The list should not include the primary source location associated with the message
+        *         which can be obtained from <code>getSourceLocation()<code>. 
+        * <p>   
+        * An example of using extra locations would be in a warning message that 
+        * flags all shadow locations that will go unmatched due to a pointcut definition 
+        * being based on a subtype of a defining type.
+        * @see <a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=41952">AspectJ bug 41952</a>
+        */
+       public List<ISourceLocation> getExtraSourceLocations();
+}
diff --git a/bridge/src/main/java/org/aspectj/bridge/IMessageContext.java b/bridge/src/main/java/org/aspectj/bridge/IMessageContext.java
new file mode 100644 (file)
index 0000000..2f5512a
--- /dev/null
@@ -0,0 +1,16 @@
+/*******************************************************************************
+ * Copyright (c) 2006 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials 
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ * 
+ * Contributors:
+ *     Matthew Webster - initial implementation
+ *******************************************************************************/
+package org.aspectj.bridge;
+
+public interface IMessageContext {
+
+       public String getContextId ();
+}
diff --git a/bridge/src/main/java/org/aspectj/bridge/IMessageHandler.java b/bridge/src/main/java/org/aspectj/bridge/IMessageHandler.java
new file mode 100644 (file)
index 0000000..6dcdfea
--- /dev/null
@@ -0,0 +1,89 @@
+/* *******************************************************************
+ * Copyright (c) 1999-2001 Xerox Corporation, 
+ *               2002 Palo Alto Research Center, Incorporated (PARC).
+ * All rights reserved. 
+ * This program and the accompanying materials are made available 
+ * under the terms of the Eclipse Public License v1.0 
+ * which accompanies this distribution and is available at 
+ * http://www.eclipse.org/legal/epl-v10.html 
+ *  
+ * Contributors: 
+ *     Xerox/PARC     initial implementation 
+ * ******************************************************************/
+
+
+package org.aspectj.bridge;
+
+import java.io.PrintWriter;
+
+/**
+ * Handle messages, logging and/or aborting as appropriate.
+ * Implementations define which messages are logged and whether
+ * the handler aborts the process.  
+ * For messages that are costly to construct, clients may query 
+ * {@link #isIgnoring(IMessage.Kind)}
+ * to avoid construction if the message will be ignored.
+ * Clients passing messages to an IMessageHandler should not
+ * interfere with aborts by catching AbortException unless
+ * otherwise required by their logic or the message handler.
+ */
+public interface IMessageHandler {
+       /** print all to System.err and throw AbortException on failure or abort messages */
+       public static final IMessageHandler SYSTEM_ERR =
+               new MessageWriter(new PrintWriter(System.err, true), true);
+
+       /** print all to System.out but do not throw AbortException on failure or abort messages */
+       public static final IMessageHandler SYSTEM_OUT =
+               new MessageWriter(new PrintWriter(System.out, true), false);
+
+       /** Throw exceptions for anything with ERROR or greater severity */
+       public static final IMessageHandler THROW =
+               new IMessageHandler() {
+                       public boolean handleMessage(IMessage message) {
+                               if (message.getKind().compareTo(IMessage.ERROR) >= 0) {
+                                       throw new AbortException(message);
+                               } else {
+                                       return SYSTEM_OUT.handleMessage(message);
+                               }
+                       }
+                       public boolean isIgnoring(IMessage.Kind kind) {
+                               return false;
+                       }
+            public void dontIgnore(IMessage.Kind kind) {
+                
+            }
+                       public void ignore(IMessage.Kind kind) {
+                       }
+               };
+
+       /** 
+        * Handle message, by reporting and/or throwing an AbortException.
+        * @param message the IMessage to handle - never null
+        * @return true if this message was handled by this handler
+        * @throws IllegalArgumentException if message is null
+        * @throws AbortException depending on handler logic.
+        */
+       boolean handleMessage(IMessage message) throws AbortException;
+
+       /**
+        * Signal clients whether this will ignore messages of a given type.
+        * Clients may use this to avoid constructing or sending certain messages.
+        * @return true if this handler is ignoring all messages of this type
+        */
+       boolean isIgnoring(IMessage.Kind kind);
+
+    /**
+     * Allow fine grained configuration after initialization. Minaly used in LTW. Most of the
+     * implementation can have this method be a no-op.
+     *  
+     * @param kind
+     */
+    void dontIgnore(IMessage.Kind kind);
+    
+    /**
+     * Allow fine grained configuration after initialization. 
+     *  
+     * @param kind
+     */
+    void ignore(IMessage.Kind kind);
+}
diff --git a/bridge/src/main/java/org/aspectj/bridge/IMessageHolder.java b/bridge/src/main/java/org/aspectj/bridge/IMessageHolder.java
new file mode 100644 (file)
index 0000000..fdf2a67
--- /dev/null
@@ -0,0 +1,66 @@
+/* *******************************************************************
+ * Copyright (c) 1999-2001 Xerox Corporation, 
+ *               2002 Palo Alto Research Center, Incorporated (PARC).
+ * All rights reserved. 
+ * This program and the accompanying materials are made available 
+ * under the terms of the Eclipse Public License v1.0 
+ * which accompanies this distribution and is available at 
+ * http://www.eclipse.org/legal/epl-v10.html 
+ *  
+ * Contributors: 
+ *     Xerox/PARC     initial implementation 
+ * ******************************************************************/
+
+package org.aspectj.bridge;
+
+import java.util.List;
+
+/**
+ * Hold and query a collection of messages.
+ */
+public interface IMessageHolder extends IMessageHandler { // XXX do not extend - mix instead
+       // XXX go to LT EQ GT GE LE rather than simple orGreater
+       /** value for orGreater parameter */
+       public static final boolean ORGREATER = true;
+
+       /** value for orGreater parameter */
+       public static final boolean EQUAL = false;
+
+       /**
+        * Tell whether this holder has any message of this kind (optionally or greater).
+        * 
+        * @param kind the IMessage.Kind to check for - accept any if null
+        * @param orGreater if true, also any greater than the target kind as determined by IMessage.Kind.COMPARATOR
+        * @return true if this holder has any message of this kind, or if orGreater and any message has a greater kind, as determined
+        *         by IMessage.Kind.COMPARATOR
+        */
+       boolean hasAnyMessage(IMessage.Kind kind, boolean orGreater);
+
+       /**
+        * Count the messages currently held by this holder. Pass null to get all kinds.
+        * 
+        * @param kind the IMessage.Kind expected, or null for all messages
+        * @param orGreater if true, also any greater than the target kind as determined by IMessage.Kind.COMPARATOR
+        * @return number of IMessage held (now) by this holder
+        */
+       int numMessages(IMessage.Kind kind, boolean orGreater);
+
+       /**
+        * Get all messages or those of a specific kind. Pass null to get all kinds.
+        * 
+        * @param kind the IMessage.Kind expected, or null for all messages
+        * @param orGreater if true, also get any greater than the target kind as determined by IMessage.Kind.COMPARATOR
+        * @return IMessage[] of messages of the right kind, or IMessage.NONE
+        */
+       IMessage[] getMessages(IMessage.Kind kind, boolean orGreater);
+
+       /** @return unmodifiable List view of underlying collection of IMessage */
+       List<IMessage> getUnmodifiableListView();
+
+       /**
+        * Clear any messages.
+        * 
+        * @throws UnsupportedOperationException if message list is read-only
+        */
+       void clearMessages() throws UnsupportedOperationException;
+}
diff --git a/bridge/src/main/java/org/aspectj/bridge/IProgressListener.java b/bridge/src/main/java/org/aspectj/bridge/IProgressListener.java
new file mode 100644 (file)
index 0000000..4326f72
--- /dev/null
@@ -0,0 +1,40 @@
+/* *******************************************************************
+ * Copyright (c) 2003 Palo Alto Research Center, Incorporated (PARC).
+ * All rights reserved. 
+ * This program and the accompanying materials are made available 
+ * under the terms of the Eclipse Public License v1.0 
+ * which accompanies this distribution and is available at 
+ * http://www.eclipse.org/legal/epl-v10.html 
+ *  
+ * Contributors: 
+ *     Xerox/PARC     initial implementation 
+ * ******************************************************************/
+
+
+package org.aspectj.bridge;
+
+/**
+  * Used to give progress information typically to IDEs
+  */
+public interface IProgressListener {
+       /**
+        * @param text the current phase of processing
+        */
+       public void setText(String text);
+       
+       /**
+        * @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();
+       
+}
diff --git a/bridge/src/main/java/org/aspectj/bridge/ISourceLocation.java b/bridge/src/main/java/org/aspectj/bridge/ISourceLocation.java
new file mode 100644 (file)
index 0000000..7ad9423
--- /dev/null
@@ -0,0 +1,72 @@
+/* *******************************************************************
+ * Copyright (c) 1999-2001 Xerox Corporation, 
+ *               2002 Palo Alto Research Center, Incorporated (PARC).
+ * All rights reserved. 
+ * This program and the accompanying materials are made available 
+ * under the terms of the Eclipse Public License v1.0 
+ * which accompanies this distribution and is available at 
+ * http://www.eclipse.org/legal/epl-v10.html 
+ *  
+ * Contributors: 
+ *     Xerox/PARC     initial implementation 
+ * ******************************************************************/
+
+package org.aspectj.bridge;
+
+import java.io.File;
+
+/**
+ * Represent source location as a starting line/column and ending line in a source file. Implementations should be immutable. XXX
+ * why?
+ * 
+ * @see org.aspectj.lang.reflect.SourceLocation
+ * @see org.aspectj.compiler.base.parser.SourceInfo
+ * @see org.aspectj.tools.ide.SourceLine
+ * @see org.aspectj.testing.harness.ErrorLine
+ */
+public interface ISourceLocation extends java.io.Serializable {
+       static final int MAX_LINE = Integer.MAX_VALUE / 2;
+       static final int MAX_COLUMN = MAX_LINE;
+
+       /** non-null but empty (nonexisting) File constant */
+       static final File NO_FILE = new File("ISourceLocation.NO_FILE");
+
+       /** signal that column is not known */
+       static final int NO_COLUMN = Integer.MIN_VALUE + 1;
+
+       /** non-null but empty constant source location */
+       static final ISourceLocation EMPTY = new SourceLocation(NO_FILE, 0, 0, 0);
+
+       /**
+        * @return File source or NO_FILE if the implementation requires a non-null result or null otherwise
+        */
+       File getSourceFile();
+
+       /** @return 0..MAX_LINE */
+       int getLine();
+
+       /**
+        * @return int 0..MAX_COLUMN actual column or 0 if column input was ISourceLocation.NO_COLUMN
+        */
+       int getColumn();
+
+       /**
+        * @return offset into file
+        */
+       int getOffset();
+
+       /** @return getLine()..MAX_LINE */
+       int getEndLine();
+
+       /** @return String application-specific context for source */
+       String getContext();
+
+       /**
+        * In the cases where getSourceFile().getName() returns a class file (for example when we have a binary aspect) this should
+        * return the name of the source file (for example BinaryAspect.aj)
+        * 
+        * @return the name of the source file
+        */
+       String getSourceFileName();
+
+}
diff --git a/bridge/src/main/java/org/aspectj/bridge/Message.java b/bridge/src/main/java/org/aspectj/bridge/Message.java
new file mode 100644 (file)
index 0000000..a4f1707
--- /dev/null
@@ -0,0 +1,190 @@
+/* *******************************************************************
+ * Copyright (c) 1999-2001 Xerox Corporation, 
+ *               2002 Palo Alto Research Center, Incorporated (PARC).
+ * All rights reserved. 
+ * This program and the accompanying materials are made available 
+ * under the terms of the Eclipse Public License v1.0 
+ * which accompanies this distribution and is available at 
+ * http://www.eclipse.org/legal/epl-v10.html 
+ *  
+ * Contributors: 
+ *     Xerox/PARC     initial implementation 
+ * ******************************************************************/
+
+package org.aspectj.bridge;
+
+import java.util.Arrays;
+import java.util.Collections;
+import java.util.List;
+
+/**
+ * Implement messages. This implementation is immutable if ISourceLocation is immutable.
+ */
+public class Message implements IMessage {
+       private final String message;
+       private final IMessage.Kind kind;
+       private final Throwable thrown;
+       private final ISourceLocation sourceLocation;
+       private final String details;
+       private final List<ISourceLocation> extraSourceLocations;
+       private final boolean declared; // Is it a DEOW ?
+       private final int id;
+       private final int sourceStart, sourceEnd;
+
+       /**
+        * Create a (compiler) error or warning message
+        * 
+        * @param message the String used as the underlying message
+        * @param location the ISourceLocation, if any, associated with this message
+        * @param isError if true, use IMessage.ERROR; else use IMessage.WARNING
+        */
+       public Message(String message, ISourceLocation location, boolean isError) {
+               this(message, (isError ? IMessage.ERROR : IMessage.WARNING), null, location);
+       }
+
+       public Message(String message, ISourceLocation location, boolean isError, ISourceLocation[] extraSourceLocations) {
+               this(message, "", (isError ? IMessage.ERROR : IMessage.WARNING), location, null,
+                               (extraSourceLocations.length > 0 ? extraSourceLocations : null));
+       }
+
+       /**
+        * Create a message, handling null values for message and kind if thrown is not null.
+        * 
+        * @param message the String used as the underlying message
+        * @param kind the IMessage.Kind of message - not null
+        * @param thrown the Throwable, if any, associated with this message
+        * @param sourceLocation the ISourceLocation, if any, associated with this message
+        * @param details descriptive information about the message
+        * @throws IllegalArgumentException if message is null and thrown is null or has a null message, or if kind is null and thrown
+        *         is null.
+        */
+       public Message(String message, String details, IMessage.Kind kind, ISourceLocation sourceLocation, Throwable thrown,
+                       ISourceLocation[] extraSourceLocations) {
+               this(message, details, kind, sourceLocation, thrown, extraSourceLocations, false, 0, -1, -1);
+       }
+
+       public Message(String message, String details, IMessage.Kind kind, ISourceLocation sLoc, Throwable thrown,
+                       ISourceLocation[] otherLocs, boolean declared, int id, int sourcestart, int sourceend) {
+               this.details = details;
+               this.id = id;
+               this.sourceStart = sourcestart;
+               this.sourceEnd = sourceend;
+               this.message = ((message != null) ? message : ((thrown == null) ? null : thrown.getMessage()));
+               this.kind = kind;
+               this.sourceLocation = sLoc;
+               this.thrown = thrown;
+               if (otherLocs != null) {
+                       this.extraSourceLocations = Collections.unmodifiableList(Arrays.asList(otherLocs));
+               } else {
+                       this.extraSourceLocations = Collections.emptyList();
+               }
+               if (null == this.kind) {
+                       throw new IllegalArgumentException("null kind");
+               }
+               if (null == this.message) {
+                       throw new IllegalArgumentException("null message");
+               }
+               this.declared = declared;
+       }
+
+       /**
+        * Create a message, handling null values for message and kind if thrown is not null.
+        * 
+        * @param message the String used as the underlying message
+        * @param kind the IMessage.Kind of message - not null
+        * @param thrown the Throwable, if any, associated with this message
+        * @param sourceLocation the ISourceLocation, if any, associated with this message
+        * @throws IllegalArgumentException if message is null and thrown is null or has a null message, or if kind is null and thrown
+        *         is null.
+        */
+       public Message(String message, IMessage.Kind kind, Throwable thrown, ISourceLocation sourceLocation) {
+               this(message, "", kind, sourceLocation, thrown, null);
+       }
+
+       /** @return the kind of this message */
+       public IMessage.Kind getKind() {
+               return kind;
+       }
+
+       /** @return true if kind == IMessage.ERROR */
+       public boolean isError() {
+               return kind == IMessage.ERROR;
+       }
+
+       /** @return true if kind == IMessage.WARNING */
+       public boolean isWarning() {
+               return kind == IMessage.WARNING;
+       }
+
+       /** @return true if kind == IMessage.DEBUG */
+       public boolean isDebug() {
+               return kind == IMessage.DEBUG;
+       }
+
+       public boolean isTaskTag() {
+               return kind == IMessage.TASKTAG;
+       }
+
+       /**
+        * @return true if kind == IMessage.INFO
+        */
+       public boolean isInfo() {
+               return kind == IMessage.INFO;
+       }
+
+       /** @return true if kind == IMessage.ABORT */
+       public boolean isAbort() {
+               return kind == IMessage.ABORT;
+       }
+
+       /** Caller can verify if this message came about because of a DEOW */
+       public boolean getDeclared() {
+               return declared;
+       }
+
+       /**
+        * @return true if kind == IMessage.FAIL
+        */
+       public boolean isFailed() {
+               return kind == IMessage.FAIL;
+       }
+
+       /** @return non-null String with simple message */
+       final public String getMessage() {
+               return message;
+       }
+
+       /** @return Throwable associated with this message, or null if none */
+       final public Throwable getThrown() {
+               return thrown;
+       }
+
+       /** @return ISourceLocation associated with this message, or null if none */
+       final public ISourceLocation getSourceLocation() {
+               return sourceLocation;
+       }
+
+       public String toString() {
+               return MessageUtil.renderMessage(this, false);
+       }
+
+       public String getDetails() {
+               return details;
+       }
+
+       public List<ISourceLocation> getExtraSourceLocations() {
+               return extraSourceLocations;
+       }
+
+       public int getID() {
+               return id;
+       }
+
+       public int getSourceStart() {
+               return sourceStart;
+       }
+
+       public int getSourceEnd() {
+               return sourceEnd;
+       }
+}
diff --git a/bridge/src/main/java/org/aspectj/bridge/MessageHandler.java b/bridge/src/main/java/org/aspectj/bridge/MessageHandler.java
new file mode 100644 (file)
index 0000000..6fd8539
--- /dev/null
@@ -0,0 +1,265 @@
+/* *******************************************************************
+ * Copyright (c) 1999-2001 Xerox Corporation, 
+ *               2002 Palo Alto Research Center, Incorporated (PARC).
+ * All rights reserved. 
+ * This program and the accompanying materials are made available 
+ * under the terms of the Eclipse Public License v1.0 
+ * which accompanies this distribution and is available at 
+ * http://www.eclipse.org/legal/epl-v10.html 
+ *  
+ * Contributors: 
+ *     Xerox/PARC     initial implementation 
+ * ******************************************************************/
+
+package org.aspectj.bridge;
+
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.List;
+
+/**
+ * This handler accumulates messages. To control messages accumulated, clients can ignore messages of a given kind, or install a
+ * listener/interceptor. The interceptor handles all messages (even null) first, and can halt further processing/accumlation by
+ * returning true. Clients can obtain messages accumulated using the get... methods. XXX this does not permit messages to be
+ * removed.
+ * 
+ * @author PARC
+ * @author Andy Clement
+ */
+public class MessageHandler implements IMessageHolder {
+
+       /** messages accumulated */
+       protected final ArrayList<IMessage> messages;
+       /** kinds of messages to be ignored */
+       protected final ArrayList<IMessage.Kind> ignoring;
+       /** result of handleMessage(..) for messages not accumulated (ignored) */
+       protected boolean handleMessageResult;
+       /** listener which can halt processing by returning true */
+       protected IMessageHandler interceptor;
+
+       /**
+        * same as MessageHandler(false)
+        */
+       public MessageHandler() {
+               this(false);
+       }
+
+       /**
+        * @param accumulateOnly the result of handleMessage (i.e., if true, then only accumulate messages - stop processing
+        */
+       public MessageHandler(boolean accumulateOnly) {
+               messages = new ArrayList<IMessage>();
+               ignoring = new ArrayList<IMessage.Kind>();
+               init(accumulateOnly);
+               ignore(IMessage.WEAVEINFO); // Off by default, need to explicitly be enabled (see -showWeaveInfo)
+       }
+
+       /**
+        * Initialize this, removing any messages accumulated, kinds being ignored, or interceptor. Assume that this should return false
+        * from handleMessage(..).
+        */
+       public void init() {
+               init(false);
+       }
+
+       /**
+        * Initialize this, removing any messages accumulated, kinds being ignored, or interceptor.
+        * 
+        * @param accumulateOnly boolean value returned from handleMessage after accumulating in list
+        */
+       public void init(boolean accumulateOnly) {
+               handleMessageResult = accumulateOnly;
+               if (0 < messages.size()) {
+                       messages.clear();
+               }
+               if (0 < ignoring.size()) {
+                       boolean ignoringWeaveMessages = isIgnoring(IMessage.WEAVEINFO);
+                       ignoring.clear();
+                       if (ignoringWeaveMessages) {
+                               ignore(IMessage.WEAVEINFO);
+                       }
+               }
+               if (null != interceptor) {
+                       interceptor = null;
+               }
+       }
+
+       /**
+        * Clear the messages without changing other behavior.
+        */
+       public void clearMessages() {
+               if (0 < messages.size()) {
+                       messages.clear();
+               }
+       }
+
+       // ---------------------- IMessageHandler implementation
+       /**
+        * This implementation accumulates message. If an interceptor is installed and returns true (message handled), then processing
+        * halts and the message is not accumulated.
+        * 
+        * @see org.aspectj.bridge.IMessageHandler#handleMessage(IMessage)
+        * @return true on interception or the constructor value otherwise
+        */
+       public boolean handleMessage(IMessage message) {
+               if ((null != interceptor) && (interceptor.handleMessage(message))) {
+                       return true;
+               }
+               if (null == message) {
+                       throw new IllegalArgumentException("null message");
+               }
+               if (!ignoring.contains(message.getKind())) {
+                       messages.add(message);
+               }
+               return handleMessageResult;
+       }
+
+       /**
+        * @return true if this kind has been flagged to be ignored.
+        * @see #ignore(IMessage.Kind)
+        * @see org.aspectj.bridge.IMessageHandler#isIgnoring(Kind)
+        */
+       public boolean isIgnoring(IMessage.Kind kind) {
+               return ((null != kind) && (ignoring.contains(kind)));
+       }
+
+       // ---------------------- end of IMessageHandler implementation
+
+       /**
+        * Set a message kind to be ignored from now on
+        */
+       public void ignore(IMessage.Kind kind) { // XXX sync
+               if ((null != kind) && (!ignoring.contains(kind))) {
+                       ignoring.add(kind);
+               }
+       }
+
+       /**
+        * Remove a message kind from the list of those ignored from now on.
+        */
+       public void dontIgnore(IMessage.Kind kind) {
+               if (null != kind) {
+                       ignoring.remove(kind);
+               }
+       }
+
+       /**
+        * @see org.aspectj.bridge.IMessageHolder#hasAnyMessage(Kind, boolean)
+        */
+       public boolean hasAnyMessage(final IMessage.Kind kind, final boolean orGreater) {
+               if (null == kind) {
+                       return (0 < messages.size());
+               }
+               if (!orGreater) {
+                       for (IMessage m : messages) {
+                               if (kind == m.getKind()) {
+                                       return true;
+                               }
+                       }
+               } else {
+                       for (IMessage m : messages) {
+                               if (kind.isSameOrLessThan(m.getKind())) {
+                                       return true;
+                               }
+                       }
+               }
+               return false;
+       }
+
+       /**
+        * @return number of messages accumulated of a given kind
+        */
+       public int numMessages(IMessage.Kind kind, final boolean orGreater) {
+               if (null == kind) {
+                       return messages.size();
+               }
+               int result = 0;
+               if (!orGreater) {
+                       for (IMessage m : messages) {
+                               if (kind == m.getKind()) {
+                                       result++;
+                               }
+                       }
+               } else {
+                       for (IMessage m : messages) {
+                               if (kind.isSameOrLessThan(m.getKind())) {
+                                       result++;
+                               }
+                       }
+               }
+               return result;
+       }
+
+       /**
+        * @see org.aspectj.bridge.IMessageHolder#getUnmodifiableListView()
+        */
+       public List<IMessage> getUnmodifiableListView() {
+               return Collections.unmodifiableList(messages);
+       }
+
+       /**
+        * Get all messages or those of a specific kind. Pass null to get all kinds.
+        * 
+        * @param kind the IMessage.Kind expected, or null for all messages
+        * @return IMessage[] of messages of the right kind
+        */
+       public IMessage[] getMessages(IMessage.Kind kind, final boolean orGreater) {
+               if (null == kind) {
+                       return messages.toArray(IMessage.RA_IMessage);
+               }
+               ArrayList<IMessage> result = new ArrayList<IMessage>();
+               if (!orGreater) {
+                       for (IMessage m : messages) {
+                               if (kind == m.getKind()) {
+                                       result.add(m);
+                               }
+                       }
+               } else {
+                       for (IMessage m : messages) {
+                               if (kind.isSameOrLessThan(m.getKind())) {
+                                       result.add(m);
+                               }
+                       }
+               }
+               if (0 == result.size()) {
+                       return IMessage.RA_IMessage;
+               }
+               return result.toArray(IMessage.RA_IMessage);
+       }
+
+       /**
+        * @return array of error messages, or IMessage.NONE
+        */
+       public IMessage[] getErrors() {
+               return getMessages(IMessage.ERROR, false);
+       }
+
+       /**
+        * @return array of warning messages, or IMessage.NONE
+        */
+       public IMessage[] getWarnings() {
+               return getMessages(IMessage.WARNING, false);
+       }
+
+       /**
+        * Set the interceptor which gets any message before we process it.
+        * 
+        * @param interceptor the IMessageHandler passed the message. Pass null to remove the old interceptor.
+        */
+       public void setInterceptor(IMessageHandler interceptor) {
+               this.interceptor = interceptor;
+       }
+
+       /**
+        * @return String containing list of messages
+        */
+       public String toString() {
+               if (0 == messages.size()) {
+                       return "MessageHandler: no messages";
+               } else {
+                       return "MessageHandler: " + messages;
+               }
+
+       }
+
+}
diff --git a/bridge/src/main/java/org/aspectj/bridge/MessageUtil.java b/bridge/src/main/java/org/aspectj/bridge/MessageUtil.java
new file mode 100644 (file)
index 0000000..6d85ea6
--- /dev/null
@@ -0,0 +1,1116 @@
+/* *******************************************************************
+ * Copyright (c) 1999-2001 Xerox Corporation, 
+ *               2002 Palo Alto Research Center, Incorporated (PARC).
+ * All rights reserved. 
+ * This program and the accompanying materials are made available 
+ * under the terms of the Eclipse Public License v1.0 
+ * which accompanies this distribution and is available at 
+ * http://www.eclipse.org/legal/epl-v10.html 
+ *  
+ * Contributors: 
+ *     Xerox/PARC     initial implementation 
+ * ******************************************************************/
+
+package org.aspectj.bridge;
+
+import java.io.File;
+import java.io.IOException;
+import java.io.OutputStream;
+import java.io.PrintStream;
+import java.io.PrintWriter;
+import java.io.StringWriter;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.Iterator;
+import java.util.List;
+
+import org.aspectj.bridge.IMessage.Kind;
+import org.aspectj.util.LangUtil;
+
+/**
+ * Convenience API's for constructing, printing, and sending messages.
+ */
+public class MessageUtil {
+
+       // ------ some constant, content-less messages
+       // no variants for "info" or "debug", which should always have content
+       public static final IMessage ABORT_NOTHING_TO_RUN = new Message("aborting - nothing to run", IMessage.ABORT, null, null);
+
+       public static final IMessage FAIL_INCOMPLETE = new Message("run not completed", IMessage.FAIL, null, null);
+
+       public static final IMessage ABORT_NOMESSAGE = new Message("", IMessage.ABORT, null, null);
+
+       public static final IMessage FAIL_NOMESSAGE = new Message("", IMessage.FAIL, null, null);
+
+       public static final IMessage ERROR_NOMESSAGE = new Message("", IMessage.ERROR, null, null);
+
+       public static final IMessage WARNING_NOMESSAGE = new Message("", IMessage.WARNING, null, null);
+
+       /** handle abort message (ignored if handler is null) */
+       public static boolean abort(IMessageHandler handler, String message) {
+               return ((null != handler) && handler.handleMessage(abort(message)));
+       }
+
+       /** create and handle exception message (ignored if handler is null) */
+       public static boolean abort(IMessageHandler handler, String message, Throwable t) {
+               if (handler != null) {
+                       return handler.handleMessage(abort(message, t));
+               }
+               return false;
+       }
+
+       /** create and handle fail message (ignored if handler is null) */
+       public static boolean fail(IMessageHandler handler, String message) {
+               return ((null != handler) && handler.handleMessage(fail(message)));
+       }
+
+       // /** create and handle fail message from reader (ignored if handler is null) */
+       // public static boolean fail(IMessageHandler handler, String message, LineReader reader) {
+       // return ((null != handler)
+       // && handler.handleMessage(fail(message, reader)));
+       // }
+
+       /** create and handle fail message (ignored if handler is null) */
+       public static boolean fail(IMessageHandler handler, String message, Throwable thrown) {
+               return ((null != handler) && handler.handleMessage(fail(message, thrown)));
+       }
+
+       /** create and handle error message (ignored if handler is null) */
+       public static boolean error(IMessageHandler handler, String message) {
+               return ((null != handler) && handler.handleMessage(error(message)));
+       }
+
+       /** create and handle warn message (ignored if handler is null) */
+       public static boolean warn(IMessageHandler handler, String message) {
+               return ((null != handler) && handler.handleMessage(warn(message)));
+       }
+
+       /** create and handle debug message (ignored if handler is null) */
+       public static boolean debug(IMessageHandler handler, String message) {
+               return ((null != handler) && handler.handleMessage(debug(message)));
+       }
+
+       /** create and handle info message (ignored if handler is null) */
+       public static boolean info(IMessageHandler handler, String message) {
+               return ((null != handler) && handler.handleMessage(info(message)));
+       }
+
+       /** @return ABORT_NOMESSAGE if message is empty or IMessage otherwise */
+       //
+       public static IMessage abort(String message) {
+               if (LangUtil.isEmpty(message)) {
+                       return ABORT_NOMESSAGE;
+               } else {
+                       return new Message(message, IMessage.ABORT, null, null);
+               }
+       }
+
+       /**
+        * @return abort IMessage with thrown and message o ABORT_NOMESSAGE if both are empty/null
+        */
+       //
+       public static IMessage abort(String message, Throwable thrown) {
+               if (!LangUtil.isEmpty(message)) {
+                       return new Message(message, IMessage.ABORT, thrown, null);
+               } else if (null == thrown) {
+                       return ABORT_NOMESSAGE;
+               } else {
+                       return new Message(thrown.getMessage(), IMessage.ABORT, thrown, null);
+               }
+       }
+
+       /** @return FAIL_NOMESSAGE if message is empty or IMessage otherwise */
+       public static IMessage fail(String message) {
+               if (LangUtil.isEmpty(message)) {
+                       return FAIL_NOMESSAGE;
+               } else {
+                       return new Message(message, IMessage.FAIL, null, ISourceLocation.EMPTY);
+
+                       // return fail(message, (LineReader) null);
+               }
+       }
+
+       /**
+        * Create fail message. If message is empty but thrown is not, use thrown.getMessage() as the message. If message is empty and
+        * thrown is null, return FAIL_NOMESSAGE.
+        * 
+        * @return FAIL_NOMESSAGE if thrown is null and message is empty or IMessage FAIL with message and thrown otherwise
+        */
+       public static IMessage fail(String message, Throwable thrown) {
+               if (LangUtil.isEmpty(message)) {
+                       if (null == thrown) {
+                               return FAIL_NOMESSAGE;
+                       } else {
+                               return new Message(thrown.getMessage(), IMessage.FAIL, thrown, null);
+                       }
+               } else {
+                       return new Message(message, IMessage.FAIL, thrown, null);
+               }
+       }
+
+       /**
+        * @return IMessage with IMessage.Kind FAIL and message as text and soure location from reader
+        */
+       // public static IMessage fail(String message) {//, LineReader reader) {
+       // ISourceLocation loc = null;
+       // if (null == reader) {
+       // loc = ISourceLocation.EMPTY;
+       // } else {
+       // int line = reader.getLineNumber();
+       // if (0 < line) {
+       // line = 0;
+       // }
+       // loc = new SourceLocation(reader.getFile(), line, line, 0);
+       // }
+       // return new Message(message, IMessage.FAIL, null, ISourceLocation.EMPTY);
+       // }
+
+       /** @return ERROR_NOMESSAGE if message is empty or IMessage otherwise */
+       //
+       public static IMessage error(String message, ISourceLocation location) {
+               if (LangUtil.isEmpty(message)) {
+                       return ERROR_NOMESSAGE;
+               } else {
+                       return new Message(message, IMessage.ERROR, null, location);
+               }
+       }
+
+       /** @return WARNING_NOMESSAGE if message is empty or IMessage otherwise */
+       //
+       public static IMessage warn(String message, ISourceLocation location) {
+               if (LangUtil.isEmpty(message)) {
+                       return WARNING_NOMESSAGE;
+               } else {
+                       return new Message(message, IMessage.WARNING, null, location);
+               }
+       }
+
+       /** @return ERROR_NOMESSAGE if message is empty or IMessage otherwise */
+       //
+       public static IMessage error(String message) {
+               if (LangUtil.isEmpty(message)) {
+                       return ERROR_NOMESSAGE;
+               } else {
+                       return new Message(message, IMessage.ERROR, null, null);
+               }
+       }
+
+       /** @return WARNING_NOMESSAGE if message is empty or IMessage otherwise */
+       //
+       public static IMessage warn(String message) {
+               if (LangUtil.isEmpty(message)) {
+                       return WARNING_NOMESSAGE;
+               } else {
+                       return new Message(message, IMessage.WARNING, null, null);
+               }
+       }
+
+       /** @return IMessage.DEBUG message with message content */
+       public static IMessage debug(String message) {
+               return new Message(message, IMessage.DEBUG, null, null);
+       }
+
+       /** @return IMessage.INFO message with message content */
+       public static IMessage info(String message) {
+               return new Message(message, IMessage.INFO, null, null);
+       }
+
+       // /** @return ISourceLocation with the current File/line of the reader */
+       // public static ISourceLocation makeSourceLocation(LineReader reader) {
+       // LangUtil.throwIaxIfNull(reader, "reader");
+       //
+       // int line = reader.getLineNumber();
+       // if (0 < line) {
+       // line = 0;
+       // }
+       // return new SourceLocation(reader.getFile(), line, line, 0);
+       // }
+
+       // ------------------------ printing messages
+       /**
+        * Print total counts message to the print stream, starting each on a new line
+        * 
+        * @param messageHolder
+        * @param out
+        */
+       public static void printMessageCounts(PrintStream out, IMessageHolder messageHolder) {
+               if ((null == out) || (null == messageHolder)) {
+                       return;
+               }
+               printMessageCounts(out, messageHolder, "");
+       }
+
+       public static void printMessageCounts(PrintStream out, IMessageHolder holder, String prefix) {
+               out.println(prefix + "MessageHolder: " + MessageUtil.renderCounts(holder));
+       }
+
+       /**
+        * Print all message to the print stream, starting each on a new line
+        * 
+        * @param messageHolder
+        * @param out
+        * @see #print(PrintStream, String, IMessageHolder, IMessageRenderer, IMessageHandler)
+        */
+       public static void print(PrintStream out, IMessageHolder messageHolder) {
+               print(out, messageHolder, (String) null, (IMessageRenderer) null, (IMessageHandler) null);
+       }
+
+       /**
+        * Print all message to the print stream, starting each on a new line, with a prefix.
+        * 
+        * @param messageHolder
+        * @param out
+        * @see #print(PrintStream, String, IMessageHolder, IMessageRenderer, IMessageHandler)
+        */
+       public static void print(PrintStream out, IMessageHolder holder, String prefix) {
+               print(out, holder, prefix, (IMessageRenderer) null, (IMessageHandler) null);
+       }
+
+       /**
+        * Print all message to the print stream, starting each on a new line, with a prefix and using a renderer.
+        * 
+        * @param messageHolder
+        * @param out
+        * @param renderer IMessageRender to render result - use MESSAGE_LINE if null
+        * @see #print(PrintStream, String, IMessageHolder, IMessageRenderer, IMessageHandler)
+        */
+       public static void print(PrintStream out, IMessageHolder holder, String prefix, IMessageRenderer renderer) {
+               print(out, holder, prefix, renderer, (IMessageHandler) null);
+       }
+
+       /**
+        * Print all message to the print stream, starting each on a new line, with a prefix and using a renderer. The first line
+        * renders a summary: {prefix}MessageHolder: {summary} Each message line has the following form:
+        * 
+        * <pre>
+        * {prefix}[{kind} {index}]: {rendering}
+        * </pre>
+        * 
+        * (where "{index}" (length 3) is the position within the set of like-kinded messages, ignoring selector omissions. Renderers
+        * are free to render multi-line output.
+        * 
+        * @param out the PrintStream sink - return silently if null
+        * @param messageHolder the IMessageHolder with the messages to print
+        * @param renderer IMessageRender to render result - use MESSAGE_ALL if null
+        * @param selector IMessageHandler to select messages to render - if null, do all non-null
+        */
+       public static void print(PrintStream out, IMessageHolder holder, String prefix, IMessageRenderer renderer,
+                       IMessageHandler selector) {
+               print(out, holder, prefix, renderer, selector, true);
+       }
+
+       public static void print(PrintStream out, IMessageHolder holder, String prefix, IMessageRenderer renderer,
+                       IMessageHandler selector, boolean printSummary) {
+               if ((null == out) || (null == holder)) {
+                       return;
+               }
+               if (null == renderer) {
+                       renderer = MESSAGE_ALL;
+               }
+               if (null == selector) {
+                       selector = PICK_ALL;
+               }
+               if (printSummary) {
+                       out.println(prefix + "MessageHolder: " + MessageUtil.renderCounts(holder));
+               }
+               for (IMessage.Kind kind : IMessage.KINDS) {
+                       if (!selector.isIgnoring(kind)) {
+                               IMessage[] messages = holder.getMessages(kind, IMessageHolder.EQUAL);
+                               for (int i = 0; i < messages.length; i++) {
+                                       if (selector.handleMessage(messages[i])) {
+                                               String label = (null == prefix ? "" : prefix + "[" + kind + " " + LangUtil.toSizedString(i, 3) + "]: ");
+                                               out.println(label + renderer.renderToString(messages[i]));
+                                       }
+                               }
+                       }
+               }
+       }
+
+       public static String toShortString(IMessage message) {
+               if (null == message) {
+                       return "null";
+               }
+               String m = message.getMessage();
+               Throwable t = message.getThrown();
+
+               return (message.getKind() + (null == m ? "" : ": " + m) + (null == t ? "" : ": " + LangUtil.unqualifiedClassName(t)));
+       }
+
+       /** @return int number of message of this kind (optionally or greater) in list */
+       public static int numMessages(List<IMessage> messages, Kind kind, boolean orGreater) {
+               if (LangUtil.isEmpty(messages)) {
+                       return 0;
+               }
+               IMessageHandler selector = makeSelector(kind, orGreater, null);
+               IMessage[] result = visitMessages(messages, selector, true, false);
+               return result.length;
+       }
+
+       /**
+        * Select all messages in holder except those of the same kind (optionally or greater). If kind is null, then all messages are
+        * rejected, so an empty list is returned.
+        * 
+        * @return unmodifiable list of specified IMessage
+        */
+       public static IMessage[] getMessagesExcept(IMessageHolder holder, final IMessage.Kind kind, final boolean orGreater) {
+               if ((null == holder) || (null == kind)) {
+                       return new IMessage[0];
+               }
+
+               IMessageHandler selector = new IMessageHandler() {
+                       public boolean handleMessage(IMessage message) {
+                               IMessage.Kind test = message.getKind();
+                               return (!(orGreater ? kind.isSameOrLessThan(test) : kind == test));
+                       }
+
+                       public boolean isIgnoring(Kind kind) {
+                               return false;
+                       }
+
+                       public void dontIgnore(IMessage.Kind kind) {
+
+                       }
+
+                       public void ignore(Kind kind) {
+                       }
+               };
+               return visitMessages(holder, selector, true, false);
+       }
+
+       /** @return unmodifiable list of IMessage complying with parameters */
+       public static List<IMessage> getMessages(IMessageHolder holder, IMessage.Kind kind, boolean orGreater, String infix) {
+               if (null == holder) {
+                       return Collections.emptyList();
+               }
+               if ((null == kind) && LangUtil.isEmpty(infix)) {
+                       return holder.getUnmodifiableListView();
+               }
+               IMessageHandler selector = makeSelector(kind, orGreater, infix);
+               IMessage[] messages = visitMessages(holder, selector, true, false);
+               if (LangUtil.isEmpty(messages)) {
+                       return Collections.emptyList();
+               }
+               return Collections.unmodifiableList(Arrays.asList(messages));
+       }
+
+       /**
+        * Extract messages of type kind from the input list.
+        * 
+        * @param messages if null, return EMPTY_LIST
+        * @param kind if null, return messages
+        * @see MessageHandler#getMessages(Kind)
+        */
+       public static List<IMessage> getMessages(List<IMessage> messages, IMessage.Kind kind) {
+               if (null == messages) {
+                       return Collections.emptyList();
+               }
+               if (null == kind) {
+                       return messages;
+               }
+               ArrayList<IMessage> result = new ArrayList<IMessage>();
+               for (IMessage message : messages) {
+                       if (kind == message.getKind()) {
+                               result.add(message);
+                       }
+               }
+               if (0 == result.size()) {
+                       return Collections.emptyList();
+               }
+               return result;
+       }
+
+       /**
+        * Map to the kind of messages associated with this string key.
+        * 
+        * @param kind the String representing the kind of message (IMessage.Kind.toString())
+        * @return Kind the associated IMessage.Kind, or null if not found
+        */
+       public static IMessage.Kind getKind(String kind) {
+               if (null != kind) {
+                       kind = kind.toLowerCase();
+                       for (IMessage.Kind k : IMessage.KINDS) {
+                               if (kind.equals(k.toString())) {
+                                       return k;
+                               }
+                       }
+               }
+               return null;
+       }
+
+       /**
+        * Run visitor over the set of messages in holder, optionally accumulating those accepted by the visitor
+        */
+       public static IMessage[] visitMessages(IMessageHolder holder, IMessageHandler visitor, boolean accumulate, boolean abortOnFail) {
+               if (null == holder) {
+                       return IMessage.RA_IMessage;
+               } else {
+                       return visitMessages(holder.getUnmodifiableListView(), visitor, accumulate, abortOnFail);
+               }
+       }
+
+       /**
+        * Run visitor over the set of messages in holder, optionally accumulating those accepted by the visitor
+        */
+       public static IMessage[] visitMessages(IMessage[] messages, IMessageHandler visitor, boolean accumulate, boolean abortOnFail) {
+               if (LangUtil.isEmpty(messages)) {
+                       return IMessage.RA_IMessage;
+               } else {
+                       return visitMessages(Arrays.asList(messages), visitor, accumulate, abortOnFail);
+               }
+       }
+
+       /**
+        * Run visitor over a collection of messages, optionally accumulating those accepted by the visitor
+        * 
+        * @param messages if null or empty, return IMessage.RA_IMessage
+        * @param visitor run visitor.handleMessage(message) on each message - if null and messages not empty, IllegalArgumentException
+        * @param accumulate if true, then return accepted IMessage[]
+        * @param abortOnFail if true and visitor returns false, stop visiting
+        * @return IMessage.RA_IMessage if collection is empty, if not accumulate, or if visitor accepted no IMessage, or IMessage[] of
+        *         accepted messages otherwise
+        * @throws IllegalArgumentException if any in collection are not instanceof IMessage
+        */
+       public static IMessage[] visitMessages(Collection<IMessage> messages, IMessageHandler visitor, final boolean accumulate,
+                       final boolean abortOnFail) {
+               if (LangUtil.isEmpty(messages)) {
+                       return IMessage.RA_IMessage;
+               }
+               LangUtil.throwIaxIfNull(visitor, "visitor");
+               ArrayList<IMessage> result = (accumulate ? new ArrayList<IMessage>() : null);
+               for (IMessage m : messages) {
+                       if (visitor.handleMessage(m)) {
+                               if (accumulate) {
+                                       result.add(m);
+                               }
+                       } else if (abortOnFail) {
+                               break;
+                       }
+               }
+               if (!accumulate || (0 == result.size())) {
+                       return IMessage.RA_IMessage;
+               } else {
+                       return result.toArray(IMessage.RA_IMessage);
+               }
+       }
+
+       /**
+        * Make an IMessageHandler that handles IMessage if they have the right kind (or greater) and contain some infix String.
+        * 
+        * @param kind the IMessage.Kind required of the message
+        * @param orGreater if true, also accept messages with greater kinds, as defined by IMessage.Kind.COMPARATOR
+        * @param infix the String text to require in the message - may be null or empty to accept any message with the specified kind.
+        * @return IMessageHandler selector that works to param specs
+        */
+       public static IMessageHandler makeSelector(IMessage.Kind kind, boolean orGreater, String infix) {
+               if (!orGreater && LangUtil.isEmpty(infix)) {
+                       if (kind == IMessage.ABORT) {
+                               return PICK_ABORT;
+                       } else if (kind == IMessage.DEBUG) {
+                               return PICK_DEBUG;
+                       } else if (kind == IMessage.DEBUG) {
+                               return PICK_DEBUG;
+                       } else if (kind == IMessage.ERROR) {
+                               return PICK_ERROR;
+                       } else if (kind == IMessage.FAIL) {
+                               return PICK_FAIL;
+                       } else if (kind == IMessage.INFO) {
+                               return PICK_INFO;
+                       } else if (kind == IMessage.WARNING) {
+                               return PICK_WARNING;
+                       }
+               }
+               return new KindSelector(kind, orGreater, infix);
+       }
+
+       // ------------------ visitors to select messages
+       public static final IMessageHandler PICK_ALL = new KindSelector((IMessage.Kind) null);
+       public static final IMessageHandler PICK_ABORT = new KindSelector(IMessage.ABORT);
+       public static final IMessageHandler PICK_DEBUG = new KindSelector(IMessage.DEBUG);
+       public static final IMessageHandler PICK_ERROR = new KindSelector(IMessage.ERROR);
+       public static final IMessageHandler PICK_FAIL = new KindSelector(IMessage.FAIL);
+       public static final IMessageHandler PICK_INFO = new KindSelector(IMessage.INFO);
+       public static final IMessageHandler PICK_WARNING = new KindSelector(IMessage.WARNING);
+       public static final IMessageHandler PICK_ABORT_PLUS = new KindSelector(IMessage.ABORT, true);
+       public static final IMessageHandler PICK_DEBUG_PLUS = new KindSelector(IMessage.DEBUG, true);
+       public static final IMessageHandler PICK_ERROR_PLUS = new KindSelector(IMessage.ERROR, true);
+       public static final IMessageHandler PICK_FAIL_PLUS = new KindSelector(IMessage.FAIL, true);
+       public static final IMessageHandler PICK_INFO_PLUS = new KindSelector(IMessage.INFO, true);
+       public static final IMessageHandler PICK_WARNING_PLUS = new KindSelector(IMessage.WARNING, true);
+
+       /** implementation for PICK_... constants */
+       private static class KindSelector implements IMessageHandler {
+               final IMessage.Kind sought;
+               final boolean floor;
+               final String infix;
+
+               KindSelector(IMessage.Kind sought) {
+                       this(sought, false);
+               }
+
+               KindSelector(IMessage.Kind sought, boolean floor) {
+                       this(sought, floor, null);
+               }
+
+               KindSelector(IMessage.Kind sought, boolean floor, String infix) {
+                       this.sought = sought;
+                       this.floor = floor;
+                       this.infix = (LangUtil.isEmpty(infix) ? null : infix);
+               }
+
+               /**
+                * @return false if this message is null, of true if we seek any kind (null) or if this has the exact kind we seek and this
+                *         has any text sought
+                */
+               public boolean handleMessage(IMessage message) {
+                       return ((null != message) && !isIgnoring(message.getKind()) && textIn(message));
+               }
+
+               /** @return true if handleMessage would return false for a message of this kind */
+               public boolean isIgnoring(IMessage.Kind kind) {
+                       if (!floor) {
+                               return ((null != sought) && (sought != kind));
+                       } else if (null == sought) {
+                               return false;
+                       } else {
+                               return (0 < IMessage.Kind.COMPARATOR.compare(sought, kind));
+                       }
+               }
+
+               public void dontIgnore(IMessage.Kind kind) {
+
+               }
+
+               private boolean textIn(IMessage message) {
+                       if (null == infix) {
+                               return true;
+                       }
+                       String text = message.getMessage();
+                       return (text.indexOf(infix) != -1);
+               }
+
+               public void ignore(Kind kind) {
+               }
+       }
+
+       // ------------------ components to render messages
+       /** parameterize rendering behavior for messages */
+       public static interface IMessageRenderer {
+               String renderToString(IMessage message);
+       }
+
+       /** render message more verbosely if it is worse */
+       public static final IMessageRenderer MESSAGE_SCALED = new IMessageRenderer() {
+               public String toString() {
+                       return "MESSAGE_SCALED";
+               }
+
+               public String renderToString(IMessage message) {
+                       if (null == message) {
+                               return "((IMessage) null)";
+                       }
+                       IMessage.Kind kind = message.getKind();
+                       int level = 3;
+                       if ((kind == IMessage.ABORT) || (kind == IMessage.FAIL)) {
+                               level = 1;
+                       } else if ((kind == IMessage.ERROR) || (kind == IMessage.WARNING)) {
+                               level = 2;
+                       } else {
+                               level = 3;
+                       }
+                       String result = null;
+                       switch (level) {
+                       case (1):
+                               result = MESSAGE_TOSTRING.renderToString(message);
+                               break;
+                       case (2):
+                               result = MESSAGE_LINE.renderToString(message);
+                               break;
+                       case (3):
+                               result = MESSAGE_SHORT.renderToString(message);
+                               break;
+                       }
+                       Throwable thrown = message.getThrown();
+                       if (null != thrown) {
+                               if (level == 3) {
+                                       result += "Thrown: \n" + LangUtil.renderExceptionShort(thrown);
+                               } else {
+                                       result += "Thrown: \n" + LangUtil.renderException(thrown);
+                               }
+                       }
+
+                       return result;
+               }
+       };
+
+       /** render message as label, i.e., less than 33 char */
+       public static final IMessageRenderer MESSAGE_LABEL = new IMessageRenderer() {
+               public String toString() {
+                       return "MESSAGE_LABEL";
+               }
+
+               public String renderToString(IMessage message) {
+                       if (null == message) {
+                               return "((IMessage) null)";
+                       }
+                       return renderMessageLine(message, 5, 5, 32);
+               }
+       };
+
+       /** render message as label, i.e., less than 33 char, with no source location */
+       public static final IMessageRenderer MESSAGE_LABEL_NOLOC = new IMessageRenderer() {
+               public String toString() {
+                       return "MESSAGE_LABEL_NOLOC";
+               }
+
+               public String renderToString(IMessage message) {
+                       if (null == message) {
+                               return "((IMessage) null)";
+                       }
+                       return renderMessageLine(message, 10, 0, 32);
+               }
+       };
+
+       /** render message as line, i.e., less than 75 char, no internal line sep */
+       public static final IMessageRenderer MESSAGE_LINE = new IMessageRenderer() {
+               public String toString() {
+                       return "MESSAGE_LINE";
+               }
+
+               public String renderToString(IMessage message) {
+                       if (null == message) {
+                               return "((IMessage) null)";
+                       }
+                       return renderMessageLine(message, 8, 2, 74);
+               }
+       };
+
+       /**
+        * render message as line, i.e., less than 75 char, no internal line sep, trying to trim text as needed to end with a full
+        * source location
+        */
+       public static final IMessageRenderer MESSAGE_LINE_FORCE_LOC = new IMessageRenderer() {
+               public String toString() {
+                       return "MESSAGE_LINE_FORCE_LOC";
+               }
+
+               public String renderToString(IMessage message) {
+                       if (null == message) {
+                               return "((IMessage) null)";
+                       }
+                       return renderMessageLine(message, 2, 40, 74);
+               }
+       };
+
+       /** render message without restriction, up to 10K, including throwable */
+       public static final IMessageRenderer MESSAGE_ALL = new IMessageRenderer() {
+               public String toString() {
+                       return "MESSAGE_ALL";
+               }
+
+               public String renderToString(IMessage message) {
+                       return renderMessage(message);
+               }
+       };
+
+       // /** render message without restriction, up to 10K, including (but eliding) throwable */
+       // public static final IMessageRenderer MESSAGE_ALL_ELIDED= new IMessageRenderer() {
+       // public String toString() { return "MESSAGE_ALL_ELIDED"; }
+       // public String renderToString(IMessage message) {
+       // return renderMessage(message, true);
+       // }
+       // };
+
+       /** render message without restriction, except any Throwable thrown */
+       public static final IMessageRenderer MESSAGE_MOST = new IMessageRenderer() {
+               public String toString() {
+                       return "MESSAGE_MOST";
+               }
+
+               public String renderToString(IMessage message) {
+                       if (null == message) {
+                               return "((IMessage) null)";
+                       }
+                       return renderMessageLine(message, 1, 1, 10000);
+               }
+       };
+
+       /**
+        * render message as wide line, i.e., less than 256 char, no internal line sep, except any Throwable thrown
+        */
+       public static final IMessageRenderer MESSAGE_WIDELINE = new IMessageRenderer() {
+               public String toString() {
+                       return "MESSAGE_WIDELINE";
+               }
+
+               public String renderToString(IMessage message) {
+                       if (null == message) {
+                               return "((IMessage) null)";
+                       }
+                       return renderMessageLine(message, 8, 2, 255); // XXX revert to 256
+               }
+       };
+       /** render message using its toString() or "((IMessage) null)" */
+       public static final IMessageRenderer MESSAGE_TOSTRING = new IMessageRenderer() {
+               public String toString() {
+                       return "MESSAGE_TOSTRING";
+               }
+
+               public String renderToString(IMessage message) {
+                       if (null == message) {
+                               return "((IMessage) null)";
+                       }
+                       return message.toString();
+               }
+       };
+
+       /** render message using toShortString(IMessage)" */
+       public static final IMessageRenderer MESSAGE_SHORT = new IMessageRenderer() {
+               public String toString() {
+                       return "MESSAGE_SHORT";
+               }
+
+               public String renderToString(IMessage message) {
+                       return toShortString(message);
+               }
+       };
+
+       /**
+        * This renders IMessage as String, ignoring empty elements and eliding any thrown stack traces.
+        * 
+        * @return "((IMessage) null)" if null or String rendering otherwise, including everything (esp. throwable stack trace)
+        * @see renderSourceLocation(ISourceLocation loc)
+        */
+       public static String renderMessage(IMessage message) {
+               return renderMessage(message, true);
+       }
+
+       /**
+        * This renders IMessage as String, ignoring empty elements and eliding any thrown.
+        * 
+        * @return "((IMessage) null)" if null or String rendering otherwise, including everything (esp. throwable stack trace)
+        * @see renderSourceLocation(ISourceLocation loc)
+        */
+       public static String renderMessage(IMessage message, boolean elide) {
+               if (null == message) {
+                       return "((IMessage) null)";
+               }
+
+               ISourceLocation loc = message.getSourceLocation();
+               String locString = (null == loc ? "" : " at " + loc);
+
+               String result = message.getKind() + locString + " " + message.getMessage();
+
+               Throwable thrown = message.getThrown();
+               if (thrown != null) {
+                       result += " -- " + LangUtil.renderExceptionShort(thrown);
+                       result += "\n" + LangUtil.renderException(thrown, elide);
+               }
+
+               if (message.getExtraSourceLocations().isEmpty()) {
+                       return result;
+               } else {
+                       return addExtraSourceLocations(message, result);
+               }
+       }
+
+       public static String addExtraSourceLocations(IMessage message, String baseMessage) {
+               StringWriter buf = new StringWriter();
+               PrintWriter writer = new PrintWriter(buf);
+               writer.println(baseMessage);
+               for (Iterator<ISourceLocation> iter = message.getExtraSourceLocations().iterator(); iter.hasNext();) {
+                       ISourceLocation element = iter.next();
+                       if (element != null) {
+                               writer.print("\tsee also: " + element.toString());
+                               if (iter.hasNext()) {
+                                       writer.println();
+                               }
+                       }
+               }
+               try {
+                       buf.close();
+               } catch (IOException ioe) {
+               }
+               return buf.getBuffer().toString();
+       }
+
+       /**
+        * Render ISourceLocation to String, ignoring empty elements (null or ISourceLocation.NO_FILE or ISourceLocation.NO_COLUMN
+        * (though implementations may return 0 from getColumn() when passed NO_COLUMN as input)).
+        * 
+        * @return "((ISourceLocation) null)" if null or String rendering
+        * 
+        *         <pre>
+        * {file:}line{:column}
+        * </pre>
+        * 
+        */
+       public static String renderSourceLocation(ISourceLocation loc) {
+               if (null == loc) {
+                       return "((ISourceLocation) null)";
+               }
+               StringBuffer sb = new StringBuffer();
+
+               File sourceFile = loc.getSourceFile();
+               if (sourceFile != ISourceLocation.NO_FILE) {
+                       sb.append(sourceFile.getPath());
+                       sb.append(":");
+               }
+               int line = loc.getLine();
+               sb.append("" + line);
+
+               int column = loc.getColumn();
+               if (column != ISourceLocation.NO_COLUMN) {
+                       sb.append(":" + column);
+               }
+
+               return sb.toString();
+       }
+
+       /**
+        * Render message in a line. IMessage.Kind is always printed, then any unqualified exception class, then the remainder of text
+        * and location according to their relative scale, all to fit in max characters or less. This does not render thrown except for
+        * the unqualified class name
+        * 
+        * @param max the number of characters - forced to 32..10000
+        * @param textScale relative proportion to spend on message and/or exception message, relative to source location - if 0,
+        *        message is suppressed
+        * @param locScale relative proportion to spend on source location suppressed if 0
+        * @return "((IMessage) null)" or message per spec
+        */
+       public static String renderMessageLine(IMessage message, int textScale, int locScale, int max) {
+
+               if (null == message) {
+                       return "((IMessage) null)";
+               }
+               if (max < 32) {
+                       max = 32;
+               } else if (max > 10000) {
+                       max = 10000;
+               }
+               if (0 > textScale) {
+                       textScale = -textScale;
+               }
+               if (0 > locScale) {
+                       locScale = -locScale;
+               }
+
+               String text = message.getMessage();
+               Throwable thrown = message.getThrown();
+               ISourceLocation sl = message.getSourceLocation();
+               IMessage.Kind kind = message.getKind();
+               StringBuffer result = new StringBuffer();
+               result.append(kind.toString());
+               result.append(": ");
+               if (null != thrown) {
+                       result.append(LangUtil.unqualifiedClassName(thrown) + " ");
+                       if ((null == text) || ("".equals(text))) {
+                               text = thrown.getMessage();
+                       }
+               }
+
+               if (0 == textScale) {
+                       text = "";
+               } else if ((null != text) && (null != thrown)) {
+                       // decide between message and exception text?
+                       String s = thrown.getMessage();
+                       if ((null != s) && (0 < s.length())) {
+                               text += " - " + s;
+                       }
+               }
+               String loc = "";
+               if ((0 != locScale) && (null != sl)) {
+                       File f = sl.getSourceFile();
+                       if (f == ISourceLocation.NO_FILE) {
+                               f = null;
+                       }
+                       if (null != f) {
+                               loc = f.getName();
+                       }
+                       int line = sl.getLine();
+                       int col = sl.getColumn();
+                       int end = sl.getEndLine();
+                       if ((0 == line) && (0 == col) && (0 == end)) {
+                               // ignore numbers if default
+                       } else {
+                               loc += ":" + line + (col == 0 ? "" : ":" + col);
+                               if (line != end) { // XXX consider suppressing nonstandard...
+                                       loc += ":" + end;
+                               }
+                       }
+                       if (!LangUtil.isEmpty(loc)) {
+                               loc = "@[" + loc; // matching "]" added below after clipping
+                       }
+               }
+
+               // now budget between text and loc
+               float totalScale = locScale + textScale;
+               float remainder = max - result.length() - 4;
+               if ((remainder > 0) && (0 < totalScale)) {
+                       int textSize = (int) (remainder * textScale / totalScale);
+                       int locSize = (int) (remainder * locScale / totalScale);
+                       // adjust for underutilization
+                       int extra = locSize - loc.length();
+                       if (0 < extra) {
+                               locSize = loc.length();
+                               textSize += extra;
+                       }
+                       extra = textSize - text.length();
+                       if (0 < extra) {
+                               textSize = text.length();
+                               if (locSize < loc.length()) {
+                                       locSize += extra;
+                               }
+                       }
+                       if (locSize > loc.length()) {
+                               locSize = loc.length();
+                       }
+                       if (textSize > text.length()) {
+                               textSize = text.length();
+                       }
+                       if (0 < textSize) {
+                               result.append(text.substring(0, textSize));
+                       }
+                       if (0 < locSize) {
+                               if (0 < textSize) {
+                                       result.append(" ");
+                               }
+                               result.append(loc.substring(0, locSize) + "]");
+                       }
+               }
+               return result.toString();
+       }
+
+       /** @return String of the form "{(# {type}) }.." for message kinds, skipping 0 */
+       public static String renderCounts(IMessageHolder holder) {
+               if (0 == holder.numMessages(null, false)) {
+                       return "(0 messages)";
+               }
+               StringBuffer sb = new StringBuffer();
+               for (IMessage.Kind kind : IMessage.KINDS) {
+                       int num = holder.numMessages(kind, false);
+                       if (0 < num) {
+                               sb.append(" (" + num + " " + kind + ") ");
+                       }
+               }
+               return sb.toString();
+       }
+
+       /**
+        * Factory for handler adapted to PrintStream XXX weak - only handles println(String)
+        * 
+        * @param handler the IMessageHandler sink for the messages generated
+        * @param kind the IMessage.Kind of message to create
+        * @param overage the OuputStream for text not captured by the handler (if null, System.out used)
+        * @throws IllegalArgumentException if kind or handler is null
+        */
+       public static PrintStream handlerPrintStream(final IMessageHandler handler, final IMessage.Kind kind,
+                       final OutputStream overage, final String prefix) {
+               LangUtil.throwIaxIfNull(handler, "handler");
+               LangUtil.throwIaxIfNull(kind, "kind");
+               class HandlerPrintStream extends PrintStream {
+                       HandlerPrintStream() {
+                               super(null == overage ? System.out : overage);
+                       }
+
+                       public void println() {
+                               println("");
+                       }
+
+                       public void println(Object o) {
+                               println(null == o ? "null" : o.toString());
+                       }
+
+                       public void println(String input) {
+                               String textMessage = (null == prefix ? input : prefix + input);
+                               IMessage m = new Message(textMessage, kind, null, null);
+                               handler.handleMessage(m);
+                       }
+               }
+               return new HandlerPrintStream();
+       }
+
+       /** utility class */
+       private MessageUtil() {
+       }
+
+       /**
+        * Handle all messages in the second handler using the first
+        * 
+        * @param handler the IMessageHandler sink for all messages in source
+        * @param holder the IMessageHolder source for all messages to handle
+        * @param fastFail if true, stop on first failure
+        * @return false if any sink.handleMessage(..) failed
+        */
+       public static boolean handleAll(IMessageHandler sink, IMessageHolder source, boolean fastFail) {
+               return handleAll(sink, source, null, true, fastFail);
+       }
+
+       /**
+        * Handle messages in the second handler using the first
+        * 
+        * @param handler the IMessageHandler sink for all messages in source
+        * @param holder the IMessageHolder source for all messages to handle
+        * @param kind the IMessage.Kind to select, if not null
+        * @param orGreater if true, also accept greater kinds
+        * @param fastFail if true, stop on first failure
+        * @return false if any sink.handleMessage(..) failed
+        */
+       public static boolean handleAll(IMessageHandler sink, IMessageHolder source, IMessage.Kind kind, boolean orGreater,
+                       boolean fastFail) {
+               LangUtil.throwIaxIfNull(sink, "sink");
+               LangUtil.throwIaxIfNull(source, "source");
+               return handleAll(sink, source.getMessages(kind, orGreater), fastFail);
+       }
+
+       /**
+        * Handle messages in the second handler using the first if they are NOT of this kind (optionally, or greater). If you pass null
+        * as the kind, then all messages are ignored and this returns true.
+        * 
+        * @param handler the IMessageHandler sink for all messages in source
+        * @param holder the IMessageHolder source for all messages to handle
+        * @param kind the IMessage.Kind to reject, if not null
+        * @param orGreater if true, also reject greater kinds
+        * @param fastFail if true, stop on first failure
+        * @return false if any sink.handleMessage(..) failed
+        */
+       public static boolean handleAllExcept(IMessageHandler sink, IMessageHolder source, IMessage.Kind kind, boolean orGreater,
+                       boolean fastFail) {
+               LangUtil.throwIaxIfNull(sink, "sink");
+               LangUtil.throwIaxIfNull(source, "source");
+               if (null == kind) {
+                       return true;
+               }
+               IMessage[] messages = getMessagesExcept(source, kind, orGreater);
+               return handleAll(sink, messages, fastFail);
+       }
+
+       /**
+        * Handle messages in the sink.
+        * 
+        * @param handler the IMessageHandler sink for all messages in source
+        * @param sources the IMessage[] messages to handle
+        * @param fastFail if true, stop on first failure
+        * @return false if any sink.handleMessage(..) failed
+        * @throws IllegalArgumentException if sink is null
+        */
+       public static boolean handleAll(IMessageHandler sink, IMessage[] sources, boolean fastFail) {
+               LangUtil.throwIaxIfNull(sink, "sink");
+               if (LangUtil.isEmpty(sources)) {
+                       return true;
+               }
+               boolean result = true;
+               for (int i = 0; i < sources.length; i++) {
+                       if (!sink.handleMessage(sources[i])) {
+                               if (fastFail) {
+                                       return false;
+                               }
+                               if (result) {
+                                       result = false;
+                               }
+                       }
+               }
+               return result;
+       }
+}
diff --git a/bridge/src/main/java/org/aspectj/bridge/MessageWriter.java b/bridge/src/main/java/org/aspectj/bridge/MessageWriter.java
new file mode 100644 (file)
index 0000000..3fbeb91
--- /dev/null
@@ -0,0 +1,84 @@
+/* *******************************************************************
+ * Copyright (c) 1999-2001 Xerox Corporation, 
+ *               2002 Palo Alto Research Center, Incorporated (PARC).
+ * All rights reserved. 
+ * This program and the accompanying materials are made available 
+ * under the terms of the Eclipse Public License v1.0 
+ * which accompanies this distribution and is available at 
+ * http://www.eclipse.org/legal/epl-v10.html 
+ *  
+ * Contributors: 
+ *     Xerox/PARC     initial implementation 
+ * ******************************************************************/
+
+package org.aspectj.bridge;
+
+import java.io.PrintWriter;
+
+/**
+ * An IMessageHandler implementation that writes all to a PrintWriter.
+ * Clients may set this up to throw AbortException for FAIL or ERROR messages.
+ * Subclasses may control whether messages are printed and how they
+ * are rendered by overriding render(IMessage).
+ */
+public class MessageWriter implements IMessageHandler {
+    
+    protected PrintWriter writer;
+    protected boolean abortOnFailure;
+    public MessageWriter(PrintWriter writer, boolean abortOnFailure) {
+        this.writer = (null != writer ? writer : new PrintWriter(System.out));
+        this.abortOnFailure = abortOnFailure;
+    }
+    
+    /**
+     * Handle message by printing and
+     * (if abortOnFailure) throwing an AbortException if 
+     * the messages is a failure or an abort (but not for errors).
+        * @see org.aspectj.bridge.IMessageHandler#handleMessage(IMessage)
+        */
+       public boolean handleMessage(IMessage message) throws AbortException {
+        if ((null != message) && !isIgnoring(message.getKind())) {
+            String result = render(message);
+            if (null != result) {
+                writer.println(result);
+                writer.flush();
+                if (abortOnFailure
+                    && (message.isFailed() || message.isAbort())) {
+                    throw new AbortException(message);
+                }
+            }
+        }
+               return true;
+       }
+    
+    /**
+        * @see org.aspectj.bridge.IMessageHandler#isIgnoring(org.aspectj.bridge.IMessage.Kind)
+        */
+       public boolean isIgnoring(IMessage.Kind kind) { 
+        // XXX share MessageHandler implementation in superclass
+               return false;
+       }
+
+    /**
+     * No-op
+     * @see org.aspectj.bridge.IMessageHandler#isIgnoring(org.aspectj.bridge.IMessage.Kind)
+     * @param kind
+     */
+    public void dontIgnore(IMessage.Kind kind) {
+        
+    }
+
+    /**
+     * No-op
+     * @see org.aspectj.bridge.IMessageHandler#ignore(org.aspectj.bridge.IMessage.Kind)
+     * @param kind
+     */
+       public void ignore(IMessage.Kind kind) {
+       }
+
+    /** @return null to not print, or message rendering (including newlines) */
+    protected String render(IMessage message) {
+        return message.toString();    
+    }
+
+}
diff --git a/bridge/src/main/java/org/aspectj/bridge/ReflectionFactory.java b/bridge/src/main/java/org/aspectj/bridge/ReflectionFactory.java
new file mode 100644 (file)
index 0000000..8eb65b3
--- /dev/null
@@ -0,0 +1,103 @@
+/* *******************************************************************
+ * Copyright (c) 1999-2001 Xerox Corporation, 
+ *               2002 Palo Alto Research Center, Incorporated (PARC).
+ * All rights reserved. 
+ * This program and the accompanying materials are made available 
+ * under the terms of the Eclipse Public License v1.0 
+ * which accompanies this distribution and is available at 
+ * http://www.eclipse.org/legal/epl-v10.html 
+ *  
+ * Contributors: 
+ *     Xerox/PARC     initial implementation 
+ * ******************************************************************/
+
+package org.aspectj.bridge;
+
+import java.lang.reflect.Constructor;
+import java.util.Arrays;
+
+/**
+ * 
+ */
+public class ReflectionFactory { // XXX lease, pool
+       public static final String OLD_AJC = "bridge.tools.impl.OldAjc";
+       public static final String ECLIPSE = "org.aspectj.ajdt.ajc.AjdtCommand";
+
+       private static final Object[] NONE = new Object[0];
+
+       /**
+        * Produce a compiler as an ICommand.
+        * 
+        * @param cname the fully-qualified class name of the command to create by reflection (assuming a public no-argument
+        *        constructor).
+        * @return ICommand compiler or null
+        */
+       public static ICommand makeCommand(String cname, IMessageHandler errorSink) {
+               return (ICommand) make(ICommand.class, cname, NONE, errorSink);
+       }
+
+       /**
+        * Make an object of type c by reflectively loading the class cname and creating an instance using args (if any), signalling
+        * errors (if any) to any errorSink.
+        */
+       private static Object make(Class<?> c, String cname, Object[] args, IMessageHandler errorSink) {
+               final boolean makeErrors = (null != errorSink);
+               Object result = null;
+               try {
+                       final Class<?> cfn = Class.forName(cname);
+                       String error = null;
+                       if (args == NONE) {
+                               result = cfn.newInstance();
+                       } else {
+                               Class<?>[] types = getTypes(args);
+                               Constructor<?> constructor = cfn.getConstructor(types);
+                               if (null != constructor) {
+                                       result = constructor.newInstance(args);
+                               } else {
+                                       if (makeErrors) {
+                                               error = "no constructor for " + c + " using " + Arrays.asList(types);
+                                       }
+                               }
+                       }
+                       if (null != result) {
+                               if (!c.isAssignableFrom(result.getClass())) {
+                                       if (makeErrors) {
+                                               error = "expecting type " + c + " got " + result.getClass();
+                                       }
+                                       result = null;
+                               }
+                       }
+                       if (null != error) {
+                               IMessage mssg = new Message(error, IMessage.FAIL, null, null);
+                               errorSink.handleMessage(mssg);
+                       }
+               } catch (Throwable t) {
+                       if (makeErrors) {
+                               String mssg = "ReflectionFactory unable to load " + cname + " as " + c.getName();
+                               IMessage m = new Message(mssg, IMessage.FAIL, t, null);
+                               errorSink.handleMessage(m);
+                       }
+               }
+               return result;
+       }
+
+       /**
+        * @return Class[] with types of args or matching null elements
+        */
+       private static Class<?>[] getTypes(Object[] args) {
+               if ((null == args) || (0 < args.length)) {
+                       return new Class[0];
+               } else {
+                       Class<?>[] result = new Class[args.length];
+                       for (int i = 0; i < result.length; i++) {
+                               if (null != args[i]) {
+                                       result[i] = args[i].getClass();
+                               }
+                       }
+                       return result;
+               }
+       }
+
+       private ReflectionFactory() {
+       }
+}
diff --git a/bridge/src/main/java/org/aspectj/bridge/SourceLocation.java b/bridge/src/main/java/org/aspectj/bridge/SourceLocation.java
new file mode 100644 (file)
index 0000000..739dd52
--- /dev/null
@@ -0,0 +1,199 @@
+/* *******************************************************************
+ * Copyright (c) 1999-2001 Xerox Corporation, 
+ *               2002 Palo Alto Research Center, Incorporated (PARC).
+ * All rights reserved. 
+ * This program and the accompanying materials are made available 
+ * under the terms of the Eclipse Public License v1.0 
+ * which accompanies this distribution and is available at 
+ * http://www.eclipse.org/legal/epl-v10.html 
+ *  
+ * Contributors: 
+ *     Xerox/PARC     initial implementation 
+ * ******************************************************************/
+
+package org.aspectj.bridge;
+
+import java.io.File;
+
+import org.aspectj.util.LangUtil;
+
+/**
+ * Immutable source location. This guarantees that the source file is not null and that the numeric values are positive and line <=
+ * endLine.
+ * 
+ * @see org.aspectj.lang.reflect.SourceLocation
+ * @see org.aspectj.compiler.base.parser.SourceInfo
+ * @see org.aspectj.tools.ide.SourceLine
+ * @see org.aspectj.testing.harness.ErrorLine
+ */
+public class SourceLocation implements ISourceLocation {
+
+       private static final long serialVersionUID = -5434765814401009794L;
+
+       private transient int cachedHashcode = -1;
+
+       /** used when SourceLocation is not available */
+       public static final ISourceLocation UNKNOWN = new SourceLocation(ISourceLocation.NO_FILE, 0, 0, 0);
+
+       private final File sourceFile;
+       private final int startLine;
+       private final int column;
+       private final int endLine;
+       private int offset;
+       private final String context;
+       private boolean noColumn;
+       private String sourceFileName;
+
+       /** @throws IllegalArgumentException if the input would not be a valid line */
+       public static final void validLine(int line) {
+               if (line < 0) {
+                       throw new IllegalArgumentException("negative line: " + line);
+               } else if (line > ISourceLocation.MAX_LINE) {
+                       throw new IllegalArgumentException("line too large: " + line);
+               }
+       }
+
+       /** @throws IllegalArgumentException if the input would not be a valid column */
+       public static final void validColumn(int column) {
+               if (column < 0) {
+                       throw new IllegalArgumentException("negative column: " + column);
+               } else if (column > ISourceLocation.MAX_COLUMN) {
+                       throw new IllegalArgumentException("column too large: " + column);
+               }
+       }
+
+       /**
+        * Same as SourceLocation(file, line, line, 0), except that column is not rendered during toString()
+        */
+       public SourceLocation(File file, int line) {
+               this(file, line, line, NO_COLUMN);
+       }
+
+       /** same as SourceLocation(file, line, endLine, ISourceLocation.NO_COLUMN) */
+       public SourceLocation(File file, int line, int endLine) {
+               this(file, line, endLine, ISourceLocation.NO_COLUMN);
+       }
+
+       /**
+        * @param file File of the source; if null, use ISourceLocation.NO_FILE, not null
+        * @param line int starting line of the location - positive number
+        * @param endLine int ending line of the location - <= starting line
+        * @param column int character position of starting location - positive number
+        */
+       public SourceLocation(File file, int line, int endLine, int column) {
+               this(file, line, endLine, column, (String) null);
+       }
+
+       public SourceLocation(File file, int line, int endLine, int column, String context) {
+               if (column == NO_COLUMN) {
+                       column = 0;
+                       noColumn = true;
+               }
+               if (null == file) {
+                       file = ISourceLocation.NO_FILE;
+               }
+               validLine(line);
+               validLine(endLine);
+               LangUtil.throwIaxIfFalse(line <= endLine, line + " > " + endLine);
+               LangUtil.throwIaxIfFalse(column >= 0, "negative column: " + column);
+               this.sourceFile = file;
+               this.startLine = line;
+               this.column = column;
+               this.endLine = endLine;
+               this.context = context;
+       }
+
+       public SourceLocation(File file, int line, int endLine, int column, String context, String sourceFileName) {
+               this(file, line, endLine, column, context);
+               this.sourceFileName = sourceFileName;
+       }
+
+       public File getSourceFile() {
+               return sourceFile;
+       }
+
+       public int getLine() {
+               return startLine;
+       }
+
+       /**
+        * @return int actual column or 0 if not available per constructor treatment of ISourceLocation.NO_COLUMN
+        */
+       public int getColumn() {
+               return column;
+       }
+
+       public int getEndLine() {
+               return endLine;
+       }
+
+       /** @return null String or application-specific context */
+       public String getContext() {
+               return context;
+       }
+
+       /** @return String {context\n}{file:}line{:column} */
+       public String toString() {
+               StringBuffer sb = new StringBuffer();
+               if (null != context) {
+                       sb.append(context);
+                       sb.append(LangUtil.EOL);
+               }
+               if (sourceFile != ISourceLocation.NO_FILE) {
+                       sb.append(sourceFile.getPath());
+               }
+               if (startLine > 0) {
+                       sb.append(":");
+                       sb.append(startLine); // "" + startLine + "-" + endLine);
+               }
+               if (!noColumn) {
+                       sb.append(":" + column);
+               }
+               if (offset >= 0) {
+                       sb.append("::" + offset);
+               }
+               return sb.toString();
+       }
+
+       // XXX Ctors for this type should know about an offset, rather than
+       // it being set through these methods - but there are just too many
+       // ctors at the moment! It needs sorting out.
+       public int getOffset() {
+               return offset;
+       }
+
+       public void setOffset(int i) {
+               cachedHashcode = -1;
+               offset = i;
+       }
+
+       public String getSourceFileName() {
+               return sourceFileName;
+       }
+
+       public boolean equals(Object obj) {
+               if (!(obj instanceof SourceLocation)) {
+                       return false;
+               }
+               SourceLocation o = (SourceLocation) obj;
+               return startLine == o.startLine && column == o.column && endLine == o.endLine && offset == o.offset
+                               && (sourceFile == null ? o.sourceFile == null : sourceFile.equals(o.sourceFile))
+                               && (context == null ? o.context == null : context.equals(o.context)) && noColumn == o.noColumn
+                               && (sourceFileName == null ? o.sourceFileName == null : sourceFileName.equals(o.sourceFileName));
+       }
+
+       public int hashCode() {
+               if (cachedHashcode == -1) {
+                       cachedHashcode = (sourceFile == null ? 0 : sourceFile.hashCode());
+                       cachedHashcode = cachedHashcode * 37 + startLine;
+                       cachedHashcode = cachedHashcode * 37 + column;
+                       cachedHashcode = cachedHashcode * 37 + endLine;
+                       cachedHashcode = cachedHashcode * 37 + offset;
+                       cachedHashcode = cachedHashcode * 37 + (context == null ? 0 : context.hashCode());
+                       cachedHashcode = cachedHashcode * 37 + (noColumn ? 0 : 1);
+                       cachedHashcode = cachedHashcode * 37 + (sourceFileName == null ? 0 : sourceFileName.hashCode());
+               }
+               return cachedHashcode;
+       }
+
+}
diff --git a/bridge/src/main/java/org/aspectj/bridge/Version.java b/bridge/src/main/java/org/aspectj/bridge/Version.java
new file mode 100644 (file)
index 0000000..367efaf
--- /dev/null
@@ -0,0 +1,89 @@
+/* ********************************************************************
+ * Copyright (c) 1998-2001 Xerox Corporation, 
+ *               2002 Palo Alto Research Center, Incorporated (PARC).
+ * All rights reserved. 
+ * This program and the accompanying materials are made available 
+ * under the terms of the Eclipse Public License v1.0 
+ * which accompanies this distribution and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ * 
+ * Contributors:
+ *     Xerox/PARC     initial implementation
+ * *******************************************************************/
+
+package org.aspectj.bridge;
+
+import java.text.ParsePosition;
+import java.text.SimpleDateFormat;
+import java.util.Date;
+
+/** release-specific version information */
+public class Version {
+    
+    // generated from build/lib/BridgeVersion.java
+
+    /** default version value for development version */
+    public static final String DEVELOPMENT = "DEVELOPMENT";
+    // VersionUptodate.java depends on this value
+
+    /** default time value for development version */
+    public static final long NOTIME = 0L;
+    
+    /** set by build script */
+    public static final String text = "DEVELOPMENT";
+    // VersionUptodate.java scans for "static final String text = "
+    
+    /** 
+      * Time text set by build script using SIMPLE_DATE_FORMAT.
+      * (if DEVELOPMENT version, invalid)
+      */
+    public static final String time_text = "Tuesday Jan 15, 2019 at 00:53:54 GMT";
+
+    /** 
+      * time in seconds-since-... format, used by programmatic clients.
+      * (if DEVELOPMENT version, NOTIME)
+      */
+    private static long time = -1; // -1 == uninitialized
+    
+       /** format used by build script to set time_text */
+    public static final String SIMPLE_DATE_FORMAT = "EEEE MMM d, yyyy 'at' HH:mm:ss z";
+    
+    public static long getTime() {
+       if (time==-1) {
+               long foundTime = NOTIME;
+           // if not DEVELOPMENT version, read time text using format used to set time 
+            try {
+                SimpleDateFormat format = new SimpleDateFormat(SIMPLE_DATE_FORMAT);
+                ParsePosition pos = new ParsePosition(0);
+                Date date = format.parse(time_text, pos);
+                if (date!=null) foundTime = date.getTime();
+            } catch (Throwable t) {            
+            }
+            time = foundTime;
+       }
+       return time;
+    }
+
+    /**
+     * Test whether the version is as specified by any first argument.
+     * Emit text to System.err on failure
+     * @param args String[] with first argument equal to Version.text
+     * @see Version#text
+     */
+    public static void main(String[] args) {
+        if ((null != args) && (0 < args.length)) {
+            if (!Version.text.equals(args[0])) {
+                System.err.println("version expected: \"" 
+                                + args[0] 
+                                + "\" actual=\"" 
+                                + Version.text 
+                                + "\"");
+            }
+        }
+    }
+}
+    
+
+
+
+
diff --git a/bridge/src/main/java/org/aspectj/bridge/WeaveMessage.java b/bridge/src/main/java/org/aspectj/bridge/WeaveMessage.java
new file mode 100644 (file)
index 0000000..2c697a8
--- /dev/null
@@ -0,0 +1,117 @@
+/* *******************************************************************
+ * Copyright (c) 2004 IBM Corporation
+ * All rights reserved. 
+ * This program and the accompanying materials are made available 
+ * under the terms of the Eclipse Public License v1.0 
+ * which accompanies this distribution and is available at 
+ * http://www.eclipse.org/legal/epl-v10.html 
+ *  
+ * Contributors: 
+ *    Andy Clement IBM     initial implementation 30-May-2004
+ * ******************************************************************/
+
+package org.aspectj.bridge;
+
+public class WeaveMessage extends Message {
+
+       // Kinds of weaving message we can produce
+
+       public static WeaveMessageKind WEAVEMESSAGE_DECLAREPARENTSIMPLEMENTS = new WeaveMessageKind(1,
+                       "Extending interface set for type '%1' (%2) to include '%3' (%4)");
+
+       public static WeaveMessageKind WEAVEMESSAGE_ITD = new WeaveMessageKind(2, "Type '%1' (%2) has intertyped %3 from '%4' (%5)");
+
+       // %7 is information like "[with runtime test]"
+       public static WeaveMessageKind WEAVEMESSAGE_ADVISES = new WeaveMessageKind(3,
+                       "Join point '%1' in Type '%2' (%3) advised by %4 advice from '%5' (%6)%7");
+
+       public static WeaveMessageKind WEAVEMESSAGE_DECLAREPARENTSEXTENDS = new WeaveMessageKind(4,
+                       "Setting superclass of type '%1' (%2) to '%3' (%4)");
+
+       public static WeaveMessageKind WEAVEMESSAGE_SOFTENS = new WeaveMessageKind(5,
+                       "Softening exceptions in type '%1' (%2) as defined by aspect '%3' (%4)");
+
+       public static WeaveMessageKind WEAVEMESSAGE_ANNOTATES = new WeaveMessageKind(6,
+                       "'%1' (%2) is annotated with %3 %4 annotation from '%5' (%6)");
+
+       public static WeaveMessageKind WEAVEMESSAGE_MIXIN = new WeaveMessageKind(7, "Mixing interface '%1' (%2) into type '%3' (%4)");
+
+       public static WeaveMessageKind WEAVEMESSAGE_REMOVES_ANNOTATION = new WeaveMessageKind(6,
+                       "'%1' (%2) has had %3 %4 annotation removed by '%5' (%6)");
+
+       private String affectedtypename;
+       private String aspectname;
+
+       // private ctor - use the static factory method
+       private WeaveMessage(String message, String affectedtypename, String aspectname) {
+               super(message, IMessage.WEAVEINFO, null, null);
+               this.affectedtypename = affectedtypename;
+               this.aspectname = aspectname;
+       }
+
+       /**
+        * Static helper method for constructing weaving messages.
+        * 
+        * @param kind what kind of message (e.g. declare parents)
+        * @param inserts inserts for the message (inserts are marked %n in the message)
+        * @return new weaving message
+        */
+       public static WeaveMessage constructWeavingMessage(WeaveMessageKind kind, String[] inserts) {
+               StringBuffer str = new StringBuffer(kind.getMessage());
+               int pos = -1;
+               while ((pos = new String(str).indexOf("%")) != -1) {
+                       int n = Character.getNumericValue(str.charAt(pos + 1));
+                       str.replace(pos, pos + 2, inserts[n - 1]);
+               }
+               return new WeaveMessage(str.toString(), null, null);
+       }
+
+       /**
+        * Static helper method for constructing weaving messages.
+        * 
+        * @param kind what kind of message (e.g. declare parents)
+        * @param inserts inserts for the message (inserts are marked %n in the message)
+        * @param affectedtypename the type which is being advised/declaredUpon
+        * @param aspectname the aspect that defined the advice or declares
+        * @return new weaving message
+        */
+       public static WeaveMessage constructWeavingMessage(WeaveMessageKind kind, String[] inserts, String affectedtypename,
+                       String aspectname) {
+               StringBuffer str = new StringBuffer(kind.getMessage());
+               int pos = -1;
+               while ((pos = new String(str).indexOf("%")) != -1) {
+                       int n = Character.getNumericValue(str.charAt(pos + 1));
+                       str.replace(pos, pos + 2, inserts[n - 1]);
+               }
+               return new WeaveMessage(str.toString(), affectedtypename, aspectname);
+       }
+
+       /**
+        * @return Returns the aspectname.
+        */
+       public String getAspectname() {
+               return aspectname;
+       }
+
+       /**
+        * @return Returns the affectedtypename.
+        */
+       public String getAffectedtypename() {
+               return affectedtypename;
+       }
+
+       public static class WeaveMessageKind {
+
+               // private int id;
+               private String message;
+
+               public WeaveMessageKind(int id, String message) {
+                       // this.id = id;
+                       this.message = message;
+               }
+
+               public String getMessage() {
+                       return message;
+               }
+       }
+}
diff --git a/bridge/src/main/java/org/aspectj/bridge/context/CompilationAndWeavingContext.java b/bridge/src/main/java/org/aspectj/bridge/context/CompilationAndWeavingContext.java
new file mode 100644 (file)
index 0000000..28a414a
--- /dev/null
@@ -0,0 +1,260 @@
+/* *******************************************************************
+ * Copyright (c) 2005-2012 Contributors.
+ * All rights reserved. 
+ * This program and the accompanying materials are made available 
+ * under the terms of the Eclipse Public License v1.0 
+ * which accompanies this distribution and is available at 
+ * http://eclipse.org/legal/epl-v10.html 
+ *  
+ * Contributors: 
+ *   Adrian Colyer                     Initial implementation
+ *   Andy Clement                      various fixes
+ *   Trask Stanalker           #373195
+ * ******************************************************************/
+package org.aspectj.bridge.context;
+
+import java.lang.ref.WeakReference;
+import java.util.HashMap;
+import java.util.Map;
+import java.util.Stack;
+
+/**
+ * This class is responsible for tracking progress through the various phases of compilation and weaving. 
+ * When an exception occurs (or a message is issued, if desired), you can ask this class for a 
+ * "stack trace" that gives information about what the compiler was doing at the time. 
+ * The trace will say something like: 
+ * "when matching pointcut xyz when matching shadow sss when weaving type ABC when weaving shadow mungers"
+ */
+public class CompilationAndWeavingContext {
+
+       private static int nextTokenId = 1;
+
+       // unique constants for the different phases that can be registered
+
+       // "FRONT END"
+       public static final int BATCH_BUILD = 0;
+       public static final int INCREMENTAL_BUILD = 1;
+       public static final int PROCESSING_COMPILATION_UNIT = 2;
+       public static final int RESOLVING_COMPILATION_UNIT = 3;
+       public static final int ANALYSING_COMPILATION_UNIT = 4;
+       public static final int GENERATING_UNWOVEN_CODE_FOR_COMPILATION_UNIT = 5;
+       public static final int COMPLETING_TYPE_BINDINGS = 6;
+       public static final int PROCESSING_DECLARE_PARENTS = 7;
+       public static final int CHECK_AND_SET_IMPORTS = 8;
+       public static final int CONNECTING_TYPE_HIERARCHY = 9;
+       public static final int BUILDING_FIELDS_AND_METHODS = 10;
+       public static final int COLLECTING_ITDS_AND_DECLARES = 11;
+       public static final int PROCESSING_DECLARE_ANNOTATIONS = 12;
+       public static final int WEAVING_INTERTYPE_DECLARATIONS = 13;
+       public static final int RESOLVING_POINTCUT_DECLARATIONS = 14;
+       public static final int ADDING_DECLARE_WARNINGS_AND_ERRORS = 15;
+       public static final int VALIDATING_AT_ASPECTJ_ANNOTATIONS = 16;
+       public static final int ACCESS_FOR_INLINE = 17;
+       public static final int ADDING_AT_ASPECTJ_ANNOTATIONS = 18;
+       public static final int FIXING_SUPER_CALLS_IN_ITDS = 19;
+       public static final int FIXING_SUPER_CALLS = 20;
+       public static final int OPTIMIZING_THIS_JOIN_POINT_CALLS = 21;
+
+       // "BACK END"
+
+       public static final int WEAVING = 22;
+       public static final int PROCESSING_REWEAVABLE_STATE = 23;
+       public static final int PROCESSING_TYPE_MUNGERS = 24;
+       public static final int WEAVING_ASPECTS = 25;
+       public static final int WEAVING_CLASSES = 26;
+       public static final int WEAVING_TYPE = 27;
+       public static final int MATCHING_SHADOW = 28;
+       public static final int IMPLEMENTING_ON_SHADOW = 29;
+       public static final int MATCHING_POINTCUT = 30;
+       public static final int MUNGING_WITH = 31;
+       public static final int PROCESSING_ATASPECTJTYPE_MUNGERS_ONLY = 32;
+
+       // phase names
+       public static final String[] PHASE_NAMES = new String[] { "batch building", "incrementally building",
+                       "processing compilation unit", "resolving types defined in compilation unit",
+                       "analysing types defined in compilation unit", "generating unwoven code for type defined in compilation unit",
+                       "completing type bindings", "processing declare parents", "checking and setting imports", "connecting type hierarchy",
+                       "building fields and methods", "collecting itds and declares", "processing declare annotations",
+                       "weaving intertype declarations", "resolving pointcut declarations", "adding declare warning and errors",
+                       "validating @AspectJ annotations", "creating accessors for inlining", "adding @AspectJ annotations",
+                       "fixing super calls in ITDs in interface context", "fixing super calls in ITDs",
+                       "optimizing thisJoinPoint calls",
+
+                       // BACK END
+
+                       "weaving", "processing reweavable state", "processing type mungers", "weaving aspects", "weaving classes",
+                       "weaving type", "matching shadow", "implementing on shadow", "matching pointcut", "type munging with",
+                       "type munging for @AspectJ aspectOf" };
+
+       // context stacks, one per thread
+       private static ThreadLocal<Stack<ContextStackEntry>> contextMap = new ThreadLocal<Stack<ContextStackEntry>>();
+
+       // single thread mode stack
+       private static Stack<ContextStackEntry> contextStack = new Stack<ContextStackEntry>();
+
+       // formatters, by phase id
+       private static Map<Integer, ContextFormatter> formatterMap = new HashMap<Integer, ContextFormatter>();
+
+       private static ContextFormatter defaultFormatter = new DefaultFormatter();
+
+       private static boolean multiThreaded = true;
+
+       /**
+        * this is a static service
+        */
+       private CompilationAndWeavingContext() {
+       }
+
+       public static void reset() {
+               if (!multiThreaded) {
+                       contextMap.remove();
+                       contextStack.clear();
+                       formatterMap.clear();
+                       nextTokenId = 1;
+               } else {
+                       contextMap.remove();
+                       // TODO what about formatterMap?
+                       // TODO what about nextTokenId?
+               }
+       }
+
+       public static void setMultiThreaded(boolean mt) {
+               multiThreaded = mt;
+       }
+
+       public static void registerFormatter(int phaseId, ContextFormatter aFormatter) {
+               formatterMap.put(new Integer(phaseId), aFormatter);
+       }
+
+       /**
+        * Returns a string description of what the compiler/weaver is currently doing
+        */
+       public static String getCurrentContext() {
+               Stack<ContextStackEntry> contextStack = getContextStack();
+               Stack<String> explanationStack = new Stack<String>();
+               for (ContextStackEntry entry : contextStack) {
+                       Object data = entry.getData();
+                       if (data != null) {
+                               explanationStack.push(getFormatter(entry).formatEntry(entry.phaseId, data));
+                       }
+               }
+               StringBuffer sb = new StringBuffer();
+               while (!explanationStack.isEmpty()) {
+                       sb.append("when ");
+                       sb.append(explanationStack.pop().toString());
+                       sb.append("\n");
+               }
+               return sb.toString();
+       }
+
+       public static ContextToken enteringPhase(int phaseId, Object data) {
+               Stack<ContextStackEntry> contextStack = getContextStack();
+               ContextTokenImpl nextToken = nextToken();
+               contextStack.push(new ContextStackEntry(nextToken, phaseId, new WeakReference<Object>(data)));
+               return nextToken;
+       }
+
+       /**
+        * Exit a phase, all stack entries from the one with the given token down will be removed.
+        */
+       public static void leavingPhase(ContextToken aToken) {
+               Stack<ContextStackEntry> contextStack = getContextStack();
+               while (!contextStack.isEmpty()) {
+                       ContextStackEntry entry = contextStack.pop();
+                       if (entry.contextToken == aToken) {
+                               break;
+                       }
+               }
+       }
+
+       /**
+        * Forget about the context for the current thread
+        */
+       public static void resetForThread() {
+               if (!multiThreaded) {
+                       return;
+               }
+               contextMap.remove();
+       }
+
+       private static Stack<ContextStackEntry> getContextStack() {
+               if (!multiThreaded) {
+                       return contextStack;
+               } else {
+                       Stack<ContextStackEntry> contextStack = contextMap.get();
+                       if (contextStack == null) {
+                               contextStack = new Stack<ContextStackEntry>();
+                               contextMap.set(contextStack);
+                       }
+                       return contextStack;
+               }
+       }
+
+       private static ContextTokenImpl nextToken() {
+               return new ContextTokenImpl(nextTokenId++);
+       }
+
+       private static ContextFormatter getFormatter(ContextStackEntry entry) {
+               Integer key = new Integer(entry.phaseId);
+               if (formatterMap.containsKey(key)) {
+                       return formatterMap.get(key);
+               } else {
+                       return defaultFormatter;
+               }
+       }
+
+       private static class ContextTokenImpl implements ContextToken {
+               public int tokenId;
+
+               public ContextTokenImpl(int id) {
+                       this.tokenId = id;
+               }
+       }
+
+       // dumb data structure
+       private static class ContextStackEntry {
+               public ContextTokenImpl contextToken;
+               public int phaseId;
+               private WeakReference<Object> dataRef;
+
+               public ContextStackEntry(ContextTokenImpl ct, int phase, WeakReference<Object> data) {
+                       this.contextToken = ct;
+                       this.phaseId = phase;
+                       this.dataRef = data;
+               }
+
+               public Object getData() {
+                       return dataRef.get();
+               }
+
+               public String toString() {
+                       Object data = getData();
+                       if (data == null) {
+                               return "referenced context entry has gone out of scope";
+                       } else {
+                               return CompilationAndWeavingContext.getFormatter(this).formatEntry(phaseId, data);
+                       }
+               }
+       }
+
+       private static class DefaultFormatter implements ContextFormatter {
+
+               public String formatEntry(int phaseId, Object data) {
+                       StringBuffer sb = new StringBuffer();
+                       sb.append(PHASE_NAMES[phaseId]);
+                       sb.append(" ");
+                       if (data instanceof char[]) {
+                               sb.append(new String((char[]) data));
+                       } else {
+                               try {
+                                       sb.append(data.toString());
+                               } catch (RuntimeException ex) {
+                                       // don't lose vital info because of bad toString
+                                       sb.append("** broken toString in data object **");
+                               }
+                       }
+                       return sb.toString();
+               }
+
+       }
+}
diff --git a/bridge/src/main/java/org/aspectj/bridge/context/ContextFormatter.java b/bridge/src/main/java/org/aspectj/bridge/context/ContextFormatter.java
new file mode 100644 (file)
index 0000000..9f1b591
--- /dev/null
@@ -0,0 +1,21 @@
+/* *******************************************************************
+ * Copyright (c) 2005 Contributors.
+ * All rights reserved. 
+ * This program and the accompanying materials are made available 
+ * under the terms of the Eclipse Public License v1.0 
+ * which accompanies this distribution and is available at 
+ * http://eclipse.org/legal/epl-v10.html 
+ *  
+ * Contributors: 
+ *   Adrian Colyer                     Initial implementation
+ * ******************************************************************/
+package org.aspectj.bridge.context;
+
+/**
+ * @author colyer
+ * Implementors of this interface know how to turn the "Object" data and phase id 
+ * associated with a context stack entry into a meaningful string.
+ */
+public interface ContextFormatter {
+       String formatEntry(int phaseId, Object data);
+}
diff --git a/bridge/src/main/java/org/aspectj/bridge/context/ContextToken.java b/bridge/src/main/java/org/aspectj/bridge/context/ContextToken.java
new file mode 100644 (file)
index 0000000..2415fa7
--- /dev/null
@@ -0,0 +1,20 @@
+/* *******************************************************************
+ * Copyright (c) 2005 Contributors.
+ * All rights reserved. 
+ * This program and the accompanying materials are made available 
+ * under the terms of the Eclipse Public License v1.0 
+ * which accompanies this distribution and is available at 
+ * http://eclipse.org/legal/epl-v10.html 
+ *  
+ * Contributors: 
+ *   Adrian Colyer                     Initial implementation
+ * ******************************************************************/
+package org.aspectj.bridge.context;
+
+/**
+ * When an entry is added to the CompilationAndWeavingContext stack,
+ * a ContextToken is returned. 
+ * When leaving a compilation or weaving phase, this token must be supplied.
+ * The token details are opaque to clients
+ */
+public interface ContextToken {}
diff --git a/bridge/src/main/java/org/aspectj/bridge/context/PinpointingMessageHandler.java b/bridge/src/main/java/org/aspectj/bridge/context/PinpointingMessageHandler.java
new file mode 100644 (file)
index 0000000..c54ff67
--- /dev/null
@@ -0,0 +1,115 @@
+/* *******************************************************************
+ * Copyright (c) 2005 Contributors.
+ * All rights reserved. 
+ * This program and the accompanying materials are made available 
+ * under the terms of the Eclipse Public License v1.0 
+ * which accompanies this distribution and is available at 
+ * http://eclipse.org/legal/epl-v10.html 
+ *  
+ * Contributors: 
+ *   Adrian Colyer                     Initial implementation
+ * ******************************************************************/
+package org.aspectj.bridge.context;
+
+import java.io.PrintWriter;
+import java.io.StringWriter;
+import java.util.List;
+
+import org.aspectj.bridge.AbortException;
+import org.aspectj.bridge.IMessage;
+import org.aspectj.bridge.IMessageHandler;
+import org.aspectj.bridge.ISourceLocation;
+import org.aspectj.bridge.IMessage.Kind;
+
+/**
+ * @author colyer
+ * Facade for an IMessageHandler
+ * Extends message with details of exactly what the compiler / weaver was doing at the 
+ * time. Use the -Xdev:Pinpoint option to turn this facility on.
+ */
+public class PinpointingMessageHandler implements IMessageHandler {
+
+       private IMessageHandler delegate;
+       
+       public PinpointingMessageHandler(IMessageHandler delegate) {
+               this.delegate = delegate;
+       }
+
+       /* (non-Javadoc)
+        * @see org.aspectj.bridge.IMessageHandler#handleMessage(org.aspectj.bridge.IMessage)
+        */
+       public boolean handleMessage(IMessage message) throws AbortException {
+               if (!isIgnoring(message.getKind())) {
+                       MessageIssued ex = new MessageIssued();
+                       ex.fillInStackTrace();
+                       StringWriter sw = new StringWriter();
+                       ex.printStackTrace(new PrintWriter(sw));
+                       StringBuffer sb = new StringBuffer();
+                       sb.append(CompilationAndWeavingContext.getCurrentContext());
+                       sb.append(sw.toString());
+                       IMessage pinpointedMessage = new PinpointedMessage(message,sb.toString());
+                       return delegate.handleMessage(pinpointedMessage);
+               } else {
+                       return delegate.handleMessage(message);
+               }
+       }
+
+       /* (non-Javadoc)
+        * @see org.aspectj.bridge.IMessageHandler#isIgnoring(org.aspectj.bridge.IMessage.Kind)
+        */
+       public boolean isIgnoring(Kind kind) {
+               return delegate.isIgnoring(kind);
+       }
+
+       /* (non-Javadoc)
+        * @see org.aspectj.bridge.IMessageHandler#dontIgnore(org.aspectj.bridge.IMessage.Kind)
+        */
+       public void dontIgnore(Kind kind) {
+               delegate.dontIgnore(kind);
+       }
+
+
+       /* (non-Javadoc)
+        * @see org.aspectj.bridge.IMessageHandler#ignore(org.aspectj.bridge.IMessage.Kind)
+        */
+       public void ignore(Kind kind) {
+               delegate.ignore(kind);
+       }
+       
+       private static class PinpointedMessage implements IMessage {
+
+               private IMessage delegate;
+               private String message;
+               
+               public PinpointedMessage(IMessage delegate, String pinpoint) {
+                       this.delegate = delegate;
+                       this.message = delegate.getMessage() + "\n" + pinpoint;
+               }
+               
+               public String getMessage() { return this.message; }
+               public Kind getKind() { return delegate.getKind();}
+               public boolean isError() { return delegate.isError(); }
+               public boolean isWarning() { return delegate.isWarning();}
+               public boolean isDebug() { return delegate.isDebug();}
+               public boolean isInfo() { return delegate.isInfo();}
+               public boolean isAbort() { return delegate.isAbort();}
+               public boolean isTaskTag() { return delegate.isTaskTag();}
+               public boolean isFailed() { return delegate.isFailed();}
+               public boolean getDeclared() { return delegate.getDeclared(); }
+               public int getID() { return delegate.getID();}
+               public int getSourceStart() { return delegate.getSourceStart();}
+               public int getSourceEnd() { return delegate.getSourceEnd();}
+               public Throwable getThrown() { return delegate.getThrown();}
+               public ISourceLocation getSourceLocation() { return delegate.getSourceLocation();}
+               public String getDetails() { return delegate.getDetails();}
+               public List<ISourceLocation> getExtraSourceLocations() { return delegate.getExtraSourceLocations();}
+       }
+
+       private static class MessageIssued extends RuntimeException {
+               private static final long serialVersionUID = 1L;
+
+               public String getMessage() {
+                       return "message issued...";
+               }
+       }
+}
diff --git a/bridge/src/org/aspectj/bridge/AbortException.java b/bridge/src/org/aspectj/bridge/AbortException.java
deleted file mode 100644 (file)
index acde7cd..0000000
+++ /dev/null
@@ -1,228 +0,0 @@
-/* *******************************************************************
- * Copyright (c) 1999-2001 Xerox Corporation, 
- *               2002 Palo Alto Research Center, Incorporated (PARC).
- * All rights reserved. 
- * This program and the accompanying materials are made available 
- * under the terms of the Eclipse Public License v1.0 
- * which accompanies this distribution and is available at 
- * http://www.eclipse.org/legal/epl-v10.html 
- *  
- * Contributors: 
- *     Xerox/PARC     initial implementation 
- * ******************************************************************/
-
-package org.aspectj.bridge;
-
-import java.io.PrintStream;
-import java.io.PrintWriter;
-import java.util.ArrayList;
-
-/**
- * Signal that a process was aborted before completion. This may contain a structured IMessage which indicates why the process was
- * aborted (e.g., the underlying exception). For processes using try/catch to complete a method abruptly but complete the process
- * normally (e.g., a test failure causes the test to abort but the reporting and testing continues normally), use the static methods
- * to borrow and return a "porter" to avoid the expense of constructing a stack trace each time. A porter stack trace is invalid,
- * and it should only be used to convey a message. E.g., to print the stack of the AbortException and any contained message:
- * 
- * <pre>
- * catch (AbortException ae) {
- *     IMessage m = ae.getMessage();
- *     if (!ae.isPorter()) ae.printStackTrace(System.err);
- *     Throwable thrown = ae.getThrown();
- *     if (null != thrown) thrown.printStackTrace(System.err);
- * }
- * </pre>
- * 
- * @author PARC
- * @author Andy Clement
- */
-public class AbortException extends RuntimeException { // XXX move porters out, handle proxy better
-
-       private static final long serialVersionUID = -7211791639898586417L;
-
-       private boolean isSilent = false;
-
-       /** used when message text is null */
-       public static final String NO_MESSAGE_TEXT = "AbortException (no message)";
-
-       private static final ArrayList<AbortException> porters = new ArrayList<AbortException>();
-
-       /**
-        * Get a porter exception from the pool. Porter exceptions do <b>not</b> have valid stack traces. They are used only to avoid
-        * generating stack traces when using throw/catch to abruptly complete but continue.
-        */
-       public static AbortException borrowPorter(IMessage message) {
-               AbortException result;
-               synchronized (porters) {
-                       if (porters.size() > 0) {
-                               result = porters.get(0);
-                       } else {
-                               result = new AbortException();
-                               result.setIsSilent(false);
-                       }
-               }
-               result.setIMessage(message);
-               result.isPorter = true;
-               return result;
-       }
-
-       /**
-        * Return (or add) a porter exception to the pool.
-        */
-       public static void returnPorter(AbortException porter) {
-               synchronized (porters) {
-                       if (porters.contains(porter)) {
-                               throw new IllegalStateException("already have " + porter);
-                       } else {
-                               porters.add(porter);
-                       }
-               }
-       }
-
-       /** @return NO_MESSAGE_TEXT or message.getMessage() if not null */
-       private static String extractMessage(IMessage message) {
-               if (null == message) {
-                       return NO_MESSAGE_TEXT;
-               } else {
-                       String m = message.getMessage();
-                       if (null == m) {
-                               return NO_MESSAGE_TEXT;
-                       } else {
-                               return m;
-                       }
-               }
-       }
-
-       /** structured message abort */
-       protected IMessage message;
-
-       /** true if this is a porter exception - only used to hold message */
-       protected boolean isPorter;
-
-       /** abort with default String message */
-       public AbortException() {
-               this("ABORT");
-               isSilent = true;
-       }
-
-       /** abort with message */
-       public AbortException(String s) {
-               super(null != s ? s : NO_MESSAGE_TEXT);
-               this.message = null;
-       }
-
-       /** abort with structured message */
-       public AbortException(IMessage message) {
-               super(extractMessage(message));
-               this.message = message;
-       }
-
-       /** @return IMessage structured message, if set */
-       public IMessage getIMessage() {
-               return message;
-       }
-
-       /**
-        * The stack trace of a porter is invalid; it is only used to carry a message (which may itself have a wrapped exception).
-        * 
-        * @return true if this exception is only to carry exception
-        */
-       public boolean isPorter() {
-               return isPorter;
-       }
-
-       /** @return Throwable at bottom of IMessage chain, if any */
-       public Throwable getThrown() {
-               Throwable result = null;
-               IMessage m = getIMessage();
-               if (null != m) {
-                       result = m.getThrown();
-                       if (result instanceof AbortException) {
-                               return ((AbortException) result).getThrown();
-                       }
-               }
-               return result;
-       }
-
-       private void setIMessage(IMessage message) {
-               this.message = message;
-       }
-
-       // ----------- proxy attempts
-       /**
-        * Get message for this AbortException, either associated explicitly as message or implicitly as IMessage message or its thrown
-        * message.
-        * 
-        * @see java.lang.Throwable#getMessage()
-        */
-       public String getMessage() {
-               String message = super.getMessage();
-               if ((null == message) || (NO_MESSAGE_TEXT == message)) {
-                       IMessage m = getIMessage();
-                       if (null != m) {
-                               message = m.getMessage();
-                               if (null == message) {
-                                       Throwable thrown = m.getThrown();
-                                       if (null != thrown) {
-                                               message = thrown.getMessage();
-                                       }
-                               }
-                       }
-                       if (null == message) {
-                               message = NO_MESSAGE_TEXT; // better than nothing
-                       }
-               }
-               return message;
-       }
-
-       /**
-        * @see java.lang.Throwable#printStackTrace()
-        */
-       public void printStackTrace() {
-               printStackTrace(System.out);
-       }
-
-       /**
-        * Print the stack trace of any enclosed thrown or this otherwise.
-        * 
-        * @see java.lang.Throwable#printStackTrace(PrintStream)
-        */
-       public void printStackTrace(PrintStream s) {
-               IMessage m = getIMessage();
-               Throwable thrown = (null == m ? null : m.getThrown());
-               if (!isPorter() || (null == thrown)) {
-                       s.println("Message: " + m);
-                       super.printStackTrace(s);
-               } else {
-                       thrown.printStackTrace(s);
-               }
-       }
-
-       /**
-        * Print the stack trace of any enclosed thrown or this otherwise.
-        * 
-        * @see java.lang.Throwable#printStackTrace(PrintWriter)
-        */
-       public void printStackTrace(PrintWriter s) {
-               IMessage m = getIMessage();
-               Throwable thrown = (null == m ? null : m.getThrown());
-               if (null == thrown) { // Always print
-                       if (isPorter()) {
-                               s.println("(Warning porter AbortException without thrown)");
-                       }
-                       s.println("Message: " + m);
-                       super.printStackTrace(s);
-               } else {
-                       thrown.printStackTrace(s);
-               }
-       }
-
-       public boolean isSilent() {
-               return isSilent;
-       }
-
-       public void setIsSilent(boolean isSilent) {
-               this.isSilent = isSilent;
-       }
-
-}
diff --git a/bridge/src/org/aspectj/bridge/Constants.java b/bridge/src/org/aspectj/bridge/Constants.java
deleted file mode 100644 (file)
index 31f2396..0000000
+++ /dev/null
@@ -1,22 +0,0 @@
-/*******************************************************************************
- * Copyright (c) 2006 IBM Corporation and others.
- * All rights reserved. This program and the accompanying materials 
- * are made available under the terms of the Eclipse Public License v1.0
- * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/epl-v10.html
- * 
- * Contributors:
- *     Matthew Webster - initial implementation
- *******************************************************************************/
-package org.aspectj.bridge;
-
-public class Constants {
-
-       /* Default resource names for user and generate aop.xml file */
-       public final static String AOP_USER_XML = "META-INF/aop.xml";
-    public final static String AOP_AJC_XML = "META-INF/aop-ajc.xml";
-    
-    /* Resource name for OSGi */
-    public final static String AOP_OSGI_XML = "org/aspectj/aop.xml";
-
-}
diff --git a/bridge/src/org/aspectj/bridge/CountingMessageHandler.java b/bridge/src/org/aspectj/bridge/CountingMessageHandler.java
deleted file mode 100644 (file)
index 4ce5508..0000000
+++ /dev/null
@@ -1,157 +0,0 @@
-/* *******************************************************************
- * Copyright (c) 1999-2001 Xerox Corporation, 
- *               2002 Palo Alto Research Center, Incorporated (PARC).
- * All rights reserved. 
- * This program and the accompanying materials are made available 
- * under the terms of the Eclipse Public License v1.0 
- * which accompanies this distribution and is available at 
- * http://www.eclipse.org/legal/epl-v10.html 
- *  
- * Contributors: 
- *     Xerox/PARC     initial implementation 
- * ******************************************************************/
-
-package org.aspectj.bridge;
-
-import java.util.Enumeration;
-import java.util.Hashtable;
-
-import org.aspectj.util.LangUtil;
-
-/**
- * Wrap an IMessageHandler to count messages handled. Messages being ignored by the delegate IMessageHandler are not counted.
- */
-public class CountingMessageHandler implements IMessageHandler {
-
-       public final IMessageHandler delegate;
-       public final CountingMessageHandler proxy;
-       private final Hashtable<IMessage.Kind, IntHolder> counters;
-
-       public static CountingMessageHandler makeCountingMessageHandler(IMessageHandler handler) {
-               if (handler instanceof CountingMessageHandler) {
-                       return (CountingMessageHandler) handler;
-               } else {
-                       return new CountingMessageHandler(handler);
-               }
-       }
-
-       public CountingMessageHandler(IMessageHandler delegate) {
-               LangUtil.throwIaxIfNull(delegate, "delegate");
-               this.delegate = delegate;
-               this.counters = new Hashtable<IMessage.Kind, IntHolder>();
-               proxy = (delegate instanceof CountingMessageHandler ? (CountingMessageHandler) delegate : null);
-       }
-
-       /** @return delegate.handleMessage(IMessage) */
-       public boolean handleMessage(IMessage message) throws AbortException {
-               if (null != proxy) {
-                       return proxy.handleMessage(message);
-               }
-               if (null != message) {
-                       IMessage.Kind kind = message.getKind();
-                       if (!isIgnoring(kind)) {
-                               increment(kind);
-                       }
-               }
-               return delegate.handleMessage(message);
-       }
-
-       /** @return delegate.isIgnoring(IMessage.Kind) */
-       public boolean isIgnoring(IMessage.Kind kind) {
-               return delegate.isIgnoring(kind);
-       }
-
-       /**
-        * Delegate
-        * 
-        * @see org.aspectj.bridge.IMessageHandler#isIgnoring(org.aspectj.bridge.IMessage.Kind)
-        * @param kind
-        */
-       public void dontIgnore(IMessage.Kind kind) {
-               delegate.dontIgnore(kind);
-       }
-
-       /**
-        * Delegate
-        * 
-        * @see org.aspectj.bridge.IMessageHandler#ignore(org.aspectj.bridge.IMessage.Kind)
-        * @param kind
-        */
-       public void ignore(IMessage.Kind kind) {
-               delegate.ignore(kind);
-       }
-
-       /** @return delegate.toString() */
-       public String toString() {
-               return delegate.toString();
-       }
-
-       /**
-        * Return count of messages seen through this interface.
-        * 
-        * @param kind the IMessage.Kind of the messages to count (if null, count all)
-        * @param orGreater if true, then count this kind and any considered greater by the ordering of IMessage.Kind.COMPARATOR
-        * @return number of messages of this kind (optionally or greater)
-        * @see IMessage.Kind.COMPARATOR
-        */
-       public int numMessages(IMessage.Kind kind, boolean orGreater) {
-               if (null != proxy) {
-                       return proxy.numMessages(kind, orGreater);
-               }
-               int result = 0;
-               if (null == kind) {
-                       for (Enumeration<IntHolder> enu = counters.elements(); enu.hasMoreElements();) {
-                               result += (enu.nextElement()).count;
-                       }
-               } else if (!orGreater) {
-                       result = numMessages(kind);
-               } else {
-                       for (IMessage.Kind k : IMessage.KINDS) {
-                               if (kind.isSameOrLessThan(k)) {
-                                       result += numMessages(k);
-                               }
-                       }
-               }
-               return result;
-       }
-
-       /**
-        * @return true if 0 is less than <code>numMessages(IMessage.ERROR, true)</code>
-        */
-       public boolean hasErrors() {
-               return (0 < numMessages(IMessage.ERROR, true));
-       }
-
-       private int numMessages(IMessage.Kind kind) {
-               if (null != proxy) {
-                       return proxy.numMessages(kind);
-               }
-               IntHolder counter = counters.get(kind);
-               return (null == counter ? 0 : counter.count);
-       }
-
-       private void increment(IMessage.Kind kind) {
-               if (null != proxy) {
-                       throw new IllegalStateException("not called when proxying");
-               }
-
-               IntHolder counter = counters.get(kind);
-               if (null == counter) {
-                       counter = new IntHolder();
-                       counters.put(kind, counter);
-               }
-               counter.count++;
-       }
-
-       private static class IntHolder {
-               int count;
-       }
-
-       public void reset() {
-               if (proxy != null) {
-                       proxy.reset();
-               }
-               counters.clear();
-       }
-
-}
diff --git a/bridge/src/org/aspectj/bridge/ICommand.java b/bridge/src/org/aspectj/bridge/ICommand.java
deleted file mode 100644 (file)
index b77d58e..0000000
+++ /dev/null
@@ -1,39 +0,0 @@
-/* *******************************************************************
- * Copyright (c) 1999-2001 Xerox Corporation, 
- *               2002 Palo Alto Research Center, Incorporated (PARC).
- * All rights reserved. 
- * This program and the accompanying materials are made available 
- * under the terms of the Eclipse Public License v1.0 
- * which accompanies this distribution and is available at 
- * http://www.eclipse.org/legal/epl-v10.html 
- *  
- * Contributors: 
- *     Xerox/PARC     initial implementation 
- * ******************************************************************/
-
-
-package org.aspectj.bridge;
-
-
-/**
- * Command wrapper with collecting parameter for messages.
- */
-public interface ICommand {
-    /**
-     * Run command with the given options.
-     * @param args the String[] options for the command
-     * @param handler the IMessageHandler for all output from
-     * the command
-     * @return true if the command completed successfully
-     */
-    boolean runCommand(String[] args, IMessageHandler handler);
-    
-    /**
-     * Rerun the command.
-     * 
-     * @param handler the IMessageHandler for all output from the command
-     * 
-     * @return true if the command completed successfully
-     */
-       boolean repeatCommand(IMessageHandler handler);   
-}
diff --git a/bridge/src/org/aspectj/bridge/ILifecycleAware.java b/bridge/src/org/aspectj/bridge/ILifecycleAware.java
deleted file mode 100644 (file)
index c5ac9b1..0000000
+++ /dev/null
@@ -1,35 +0,0 @@
-/* *******************************************************************
- * Copyright (c) 2006 Contributors.
- * All rights reserved. 
- * This program and the accompanying materials are made available 
- * under the terms of the Eclipse Public License v1.0 
- * which accompanies this distribution and is available at 
- * http://eclipse.org/legal/epl-v10.html 
- *  
- * Contributors: 
- *   Adrian Colyer                     Initial implementation
- * ******************************************************************/
-package org.aspectj.bridge;
-
-/**
- * Interface that can be implemented by MessageHandlers that need to 
- * perform some additional processing when a build is starting and 
- * when it has finished.
- * 
- * @author Adrian Colyer
- * @since 1.5.1
- */
-public interface ILifecycleAware {
-
-       /**
-        * called when a build starts
-        */
-       void buildStarting(boolean isIncremental);
-       
-       /**
-        * called when a batch build finishes
-        *
-        */
-       void buildFinished(boolean wasIncremental);
-       
-}
diff --git a/bridge/src/org/aspectj/bridge/IMessage.java b/bridge/src/org/aspectj/bridge/IMessage.java
deleted file mode 100644 (file)
index a32a631..0000000
+++ /dev/null
@@ -1,150 +0,0 @@
-/* *******************************************************************
- * Copyright (c) 1999-2001 Xerox Corporation, 
- *               2002 Palo Alto Research Center, Incorporated (PARC).
- * All rights reserved. 
- * This program and the accompanying materials are made available 
- * under the terms of the Eclipse Public License v1.0 
- * which accompanies this distribution and is available at 
- * http://www.eclipse.org/legal/epl-v10.html 
- *  
- * Contributors: 
- *     Xerox/PARC     initial implementation 
- * ******************************************************************/
-
-package org.aspectj.bridge;
-
-import java.util.Arrays;
-import java.util.Collections;
-import java.util.Comparator;
-import java.util.List;
-
-/**
- * Wrap message with any associated throwable or source location.
- */
-public interface IMessage {
-       /** no messages */
-       public static final IMessage[] RA_IMessage = new IMessage[0];
-
-       // int values must sync with KINDS order below
-       public static final Kind WEAVEINFO = new Kind("weaveinfo", 5);
-       public static final Kind INFO = new Kind("info", 10);
-       public static final Kind DEBUG = new Kind("debug", 20);
-       public static final Kind TASKTAG = new Kind("task", 25); // represents a 'TODO' from eclipse - producted by the compiler and
-                                                                                                                               // consumed by AJDT
-       public static final Kind WARNING = new Kind("warning", 30);
-       public static final Kind ERROR = new Kind("error", 40);
-       public static final Kind FAIL = new Kind("fail", 50);
-       public static final Kind ABORT = new Kind("abort", 60);
-       // XXX prefer another Kind to act as selector for "any",
-       // but can't prohibit creating messages with it.
-       // public static final Kind ANY = new Kind("any-selector", 0);
-
-       /**
-        * list of Kind in precedence order. 0 is less than IMessage.Kind.COMPARATOR.compareTo(KINDS.get(i), KINDS.get(i + 1))
-        */
-       public static final List<Kind> KINDS = Collections.unmodifiableList(Arrays.asList(new Kind[] { WEAVEINFO, INFO, DEBUG, TASKTAG,
-                       WARNING, ERROR, FAIL, ABORT }));
-
-       /** @return non-null String with simple message */
-       String getMessage();
-
-       /** @return the kind of this message */
-       Kind getKind();
-
-       /** @return true if this is an error */
-       boolean isError();
-
-       /** @return true if this is a warning */
-       boolean isWarning();
-
-       /** @return true if this is an internal debug message */
-       boolean isDebug();
-
-       /** @return true if this is information for the user */
-       boolean isInfo();
-
-       /** @return true if the process is aborting */
-       boolean isAbort(); // XXX ambiguous
-
-       /** @return true if this is a task tag message */
-       boolean isTaskTag();
-
-       /** @return true if something failed */
-       boolean isFailed();
-
-       /** Caller can verify if this message came about because of a DEOW */
-       boolean getDeclared();
-
-       /** Return the ID of the message where applicable, see IProblem for list of valid IDs */
-       int getID();
-
-       /** Return the start position of the problem (inclusive), or -1 if unknown. */
-       int getSourceStart();
-
-       /** Return the end position of the problem (inclusive), or -1 if unknown. */
-       int getSourceEnd();
-
-       /** @return Throwable associated with this message, or null if none */
-       Throwable getThrown();
-
-       /** @return source location associated with this message, or null if none */
-       ISourceLocation getSourceLocation();
-
-       public static final class Kind implements Comparable<IMessage.Kind> {
-               public static final Comparator<IMessage.Kind> COMPARATOR = new Comparator<IMessage.Kind>() {
-                       public int compare(IMessage.Kind one, IMessage.Kind two) {
-                               if (null == one) {
-                                       return (null == two ? 0 : -1);
-                               } else if (null == two) {
-                                       return 1;
-                               } else if (one == two) {
-                                       return 0;
-                               } else {
-                                       return (one.precedence - two.precedence);
-                               }
-                       }
-               };
-
-               /**
-                * @param kind the Kind floor
-                * @return false if kind is null or this has less precedence than kind, true otherwise.
-                */
-               public boolean isSameOrLessThan(Kind kind) {
-                       return (0 >= COMPARATOR.compare(this, kind));
-               }
-
-               public int compareTo(IMessage.Kind other) {
-                       return COMPARATOR.compare(this, other);
-               }
-
-               private final int precedence;
-               private final String name;
-
-               private Kind(String name, int precedence) {
-                       this.name = name;
-                       this.precedence = precedence;
-               }
-
-               public String toString() {
-                       return name;
-               }
-       }
-
-       /**
-        * @return Detailed information about the message. For example, for declare error/warning messages this returns information
-        *         about the corresponding join point's static part.
-        */
-       public String getDetails();
-
-       /**
-        * @return List of <code>ISourceLocation</code> instances that indicate additional source locations relevent to this message as
-        *         specified by the message creator. The list should not include the primary source location associated with the message
-        *         which can be obtained from <code>getSourceLocation()<code>. 
-        * <p>   
-        * An example of using extra locations would be in a warning message that 
-        * flags all shadow locations that will go unmatched due to a pointcut definition 
-        * being based on a subtype of a defining type.
-        * @see <a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=41952">AspectJ bug 41952</a>
-        */
-       public List<ISourceLocation> getExtraSourceLocations();
-}
diff --git a/bridge/src/org/aspectj/bridge/IMessageContext.java b/bridge/src/org/aspectj/bridge/IMessageContext.java
deleted file mode 100644 (file)
index 2f5512a..0000000
+++ /dev/null
@@ -1,16 +0,0 @@
-/*******************************************************************************
- * Copyright (c) 2006 IBM Corporation and others.
- * All rights reserved. This program and the accompanying materials 
- * are made available under the terms of the Eclipse Public License v1.0
- * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/epl-v10.html
- * 
- * Contributors:
- *     Matthew Webster - initial implementation
- *******************************************************************************/
-package org.aspectj.bridge;
-
-public interface IMessageContext {
-
-       public String getContextId ();
-}
diff --git a/bridge/src/org/aspectj/bridge/IMessageHandler.java b/bridge/src/org/aspectj/bridge/IMessageHandler.java
deleted file mode 100644 (file)
index 6dcdfea..0000000
+++ /dev/null
@@ -1,89 +0,0 @@
-/* *******************************************************************
- * Copyright (c) 1999-2001 Xerox Corporation, 
- *               2002 Palo Alto Research Center, Incorporated (PARC).
- * All rights reserved. 
- * This program and the accompanying materials are made available 
- * under the terms of the Eclipse Public License v1.0 
- * which accompanies this distribution and is available at 
- * http://www.eclipse.org/legal/epl-v10.html 
- *  
- * Contributors: 
- *     Xerox/PARC     initial implementation 
- * ******************************************************************/
-
-
-package org.aspectj.bridge;
-
-import java.io.PrintWriter;
-
-/**
- * Handle messages, logging and/or aborting as appropriate.
- * Implementations define which messages are logged and whether
- * the handler aborts the process.  
- * For messages that are costly to construct, clients may query 
- * {@link #isIgnoring(IMessage.Kind)}
- * to avoid construction if the message will be ignored.
- * Clients passing messages to an IMessageHandler should not
- * interfere with aborts by catching AbortException unless
- * otherwise required by their logic or the message handler.
- */
-public interface IMessageHandler {
-       /** print all to System.err and throw AbortException on failure or abort messages */
-       public static final IMessageHandler SYSTEM_ERR =
-               new MessageWriter(new PrintWriter(System.err, true), true);
-
-       /** print all to System.out but do not throw AbortException on failure or abort messages */
-       public static final IMessageHandler SYSTEM_OUT =
-               new MessageWriter(new PrintWriter(System.out, true), false);
-
-       /** Throw exceptions for anything with ERROR or greater severity */
-       public static final IMessageHandler THROW =
-               new IMessageHandler() {
-                       public boolean handleMessage(IMessage message) {
-                               if (message.getKind().compareTo(IMessage.ERROR) >= 0) {
-                                       throw new AbortException(message);
-                               } else {
-                                       return SYSTEM_OUT.handleMessage(message);
-                               }
-                       }
-                       public boolean isIgnoring(IMessage.Kind kind) {
-                               return false;
-                       }
-            public void dontIgnore(IMessage.Kind kind) {
-                
-            }
-                       public void ignore(IMessage.Kind kind) {
-                       }
-               };
-
-       /** 
-        * Handle message, by reporting and/or throwing an AbortException.
-        * @param message the IMessage to handle - never null
-        * @return true if this message was handled by this handler
-        * @throws IllegalArgumentException if message is null
-        * @throws AbortException depending on handler logic.
-        */
-       boolean handleMessage(IMessage message) throws AbortException;
-
-       /**
-        * Signal clients whether this will ignore messages of a given type.
-        * Clients may use this to avoid constructing or sending certain messages.
-        * @return true if this handler is ignoring all messages of this type
-        */
-       boolean isIgnoring(IMessage.Kind kind);
-
-    /**
-     * Allow fine grained configuration after initialization. Minaly used in LTW. Most of the
-     * implementation can have this method be a no-op.
-     *  
-     * @param kind
-     */
-    void dontIgnore(IMessage.Kind kind);
-    
-    /**
-     * Allow fine grained configuration after initialization. 
-     *  
-     * @param kind
-     */
-    void ignore(IMessage.Kind kind);
-}
diff --git a/bridge/src/org/aspectj/bridge/IMessageHolder.java b/bridge/src/org/aspectj/bridge/IMessageHolder.java
deleted file mode 100644 (file)
index fdf2a67..0000000
+++ /dev/null
@@ -1,66 +0,0 @@
-/* *******************************************************************
- * Copyright (c) 1999-2001 Xerox Corporation, 
- *               2002 Palo Alto Research Center, Incorporated (PARC).
- * All rights reserved. 
- * This program and the accompanying materials are made available 
- * under the terms of the Eclipse Public License v1.0 
- * which accompanies this distribution and is available at 
- * http://www.eclipse.org/legal/epl-v10.html 
- *  
- * Contributors: 
- *     Xerox/PARC     initial implementation 
- * ******************************************************************/
-
-package org.aspectj.bridge;
-
-import java.util.List;
-
-/**
- * Hold and query a collection of messages.
- */
-public interface IMessageHolder extends IMessageHandler { // XXX do not extend - mix instead
-       // XXX go to LT EQ GT GE LE rather than simple orGreater
-       /** value for orGreater parameter */
-       public static final boolean ORGREATER = true;
-
-       /** value for orGreater parameter */
-       public static final boolean EQUAL = false;
-
-       /**
-        * Tell whether this holder has any message of this kind (optionally or greater).
-        * 
-        * @param kind the IMessage.Kind to check for - accept any if null
-        * @param orGreater if true, also any greater than the target kind as determined by IMessage.Kind.COMPARATOR
-        * @return true if this holder has any message of this kind, or if orGreater and any message has a greater kind, as determined
-        *         by IMessage.Kind.COMPARATOR
-        */
-       boolean hasAnyMessage(IMessage.Kind kind, boolean orGreater);
-
-       /**
-        * Count the messages currently held by this holder. Pass null to get all kinds.
-        * 
-        * @param kind the IMessage.Kind expected, or null for all messages
-        * @param orGreater if true, also any greater than the target kind as determined by IMessage.Kind.COMPARATOR
-        * @return number of IMessage held (now) by this holder
-        */
-       int numMessages(IMessage.Kind kind, boolean orGreater);
-
-       /**
-        * Get all messages or those of a specific kind. Pass null to get all kinds.
-        * 
-        * @param kind the IMessage.Kind expected, or null for all messages
-        * @param orGreater if true, also get any greater than the target kind as determined by IMessage.Kind.COMPARATOR
-        * @return IMessage[] of messages of the right kind, or IMessage.NONE
-        */
-       IMessage[] getMessages(IMessage.Kind kind, boolean orGreater);
-
-       /** @return unmodifiable List view of underlying collection of IMessage */
-       List<IMessage> getUnmodifiableListView();
-
-       /**
-        * Clear any messages.
-        * 
-        * @throws UnsupportedOperationException if message list is read-only
-        */
-       void clearMessages() throws UnsupportedOperationException;
-}
diff --git a/bridge/src/org/aspectj/bridge/IProgressListener.java b/bridge/src/org/aspectj/bridge/IProgressListener.java
deleted file mode 100644 (file)
index 4326f72..0000000
+++ /dev/null
@@ -1,40 +0,0 @@
-/* *******************************************************************
- * Copyright (c) 2003 Palo Alto Research Center, Incorporated (PARC).
- * All rights reserved. 
- * This program and the accompanying materials are made available 
- * under the terms of the Eclipse Public License v1.0 
- * which accompanies this distribution and is available at 
- * http://www.eclipse.org/legal/epl-v10.html 
- *  
- * Contributors: 
- *     Xerox/PARC     initial implementation 
- * ******************************************************************/
-
-
-package org.aspectj.bridge;
-
-/**
-  * Used to give progress information typically to IDEs
-  */
-public interface IProgressListener {
-       /**
-        * @param text the current phase of processing
-        */
-       public void setText(String text);
-       
-       /**
-        * @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();
-       
-}
diff --git a/bridge/src/org/aspectj/bridge/ISourceLocation.java b/bridge/src/org/aspectj/bridge/ISourceLocation.java
deleted file mode 100644 (file)
index 7ad9423..0000000
+++ /dev/null
@@ -1,72 +0,0 @@
-/* *******************************************************************
- * Copyright (c) 1999-2001 Xerox Corporation, 
- *               2002 Palo Alto Research Center, Incorporated (PARC).
- * All rights reserved. 
- * This program and the accompanying materials are made available 
- * under the terms of the Eclipse Public License v1.0 
- * which accompanies this distribution and is available at 
- * http://www.eclipse.org/legal/epl-v10.html 
- *  
- * Contributors: 
- *     Xerox/PARC     initial implementation 
- * ******************************************************************/
-
-package org.aspectj.bridge;
-
-import java.io.File;
-
-/**
- * Represent source location as a starting line/column and ending line in a source file. Implementations should be immutable. XXX
- * why?
- * 
- * @see org.aspectj.lang.reflect.SourceLocation
- * @see org.aspectj.compiler.base.parser.SourceInfo
- * @see org.aspectj.tools.ide.SourceLine
- * @see org.aspectj.testing.harness.ErrorLine
- */
-public interface ISourceLocation extends java.io.Serializable {
-       static final int MAX_LINE = Integer.MAX_VALUE / 2;
-       static final int MAX_COLUMN = MAX_LINE;
-
-       /** non-null but empty (nonexisting) File constant */
-       static final File NO_FILE = new File("ISourceLocation.NO_FILE");
-
-       /** signal that column is not known */
-       static final int NO_COLUMN = Integer.MIN_VALUE + 1;
-
-       /** non-null but empty constant source location */
-       static final ISourceLocation EMPTY = new SourceLocation(NO_FILE, 0, 0, 0);
-
-       /**
-        * @return File source or NO_FILE if the implementation requires a non-null result or null otherwise
-        */
-       File getSourceFile();
-
-       /** @return 0..MAX_LINE */
-       int getLine();
-
-       /**
-        * @return int 0..MAX_COLUMN actual column or 0 if column input was ISourceLocation.NO_COLUMN
-        */
-       int getColumn();
-
-       /**
-        * @return offset into file
-        */
-       int getOffset();
-
-       /** @return getLine()..MAX_LINE */
-       int getEndLine();
-
-       /** @return String application-specific context for source */
-       String getContext();
-
-       /**
-        * In the cases where getSourceFile().getName() returns a class file (for example when we have a binary aspect) this should
-        * return the name of the source file (for example BinaryAspect.aj)
-        * 
-        * @return the name of the source file
-        */
-       String getSourceFileName();
-
-}
diff --git a/bridge/src/org/aspectj/bridge/Message.java b/bridge/src/org/aspectj/bridge/Message.java
deleted file mode 100644 (file)
index a4f1707..0000000
+++ /dev/null
@@ -1,190 +0,0 @@
-/* *******************************************************************
- * Copyright (c) 1999-2001 Xerox Corporation, 
- *               2002 Palo Alto Research Center, Incorporated (PARC).
- * All rights reserved. 
- * This program and the accompanying materials are made available 
- * under the terms of the Eclipse Public License v1.0 
- * which accompanies this distribution and is available at 
- * http://www.eclipse.org/legal/epl-v10.html 
- *  
- * Contributors: 
- *     Xerox/PARC     initial implementation 
- * ******************************************************************/
-
-package org.aspectj.bridge;
-
-import java.util.Arrays;
-import java.util.Collections;
-import java.util.List;
-
-/**
- * Implement messages. This implementation is immutable if ISourceLocation is immutable.
- */
-public class Message implements IMessage {
-       private final String message;
-       private final IMessage.Kind kind;
-       private final Throwable thrown;
-       private final ISourceLocation sourceLocation;
-       private final String details;
-       private final List<ISourceLocation> extraSourceLocations;
-       private final boolean declared; // Is it a DEOW ?
-       private final int id;
-       private final int sourceStart, sourceEnd;
-
-       /**
-        * Create a (compiler) error or warning message
-        * 
-        * @param message the String used as the underlying message
-        * @param location the ISourceLocation, if any, associated with this message
-        * @param isError if true, use IMessage.ERROR; else use IMessage.WARNING
-        */
-       public Message(String message, ISourceLocation location, boolean isError) {
-               this(message, (isError ? IMessage.ERROR : IMessage.WARNING), null, location);
-       }
-
-       public Message(String message, ISourceLocation location, boolean isError, ISourceLocation[] extraSourceLocations) {
-               this(message, "", (isError ? IMessage.ERROR : IMessage.WARNING), location, null,
-                               (extraSourceLocations.length > 0 ? extraSourceLocations : null));
-       }
-
-       /**
-        * Create a message, handling null values for message and kind if thrown is not null.
-        * 
-        * @param message the String used as the underlying message
-        * @param kind the IMessage.Kind of message - not null
-        * @param thrown the Throwable, if any, associated with this message
-        * @param sourceLocation the ISourceLocation, if any, associated with this message
-        * @param details descriptive information about the message
-        * @throws IllegalArgumentException if message is null and thrown is null or has a null message, or if kind is null and thrown
-        *         is null.
-        */
-       public Message(String message, String details, IMessage.Kind kind, ISourceLocation sourceLocation, Throwable thrown,
-                       ISourceLocation[] extraSourceLocations) {
-               this(message, details, kind, sourceLocation, thrown, extraSourceLocations, false, 0, -1, -1);
-       }
-
-       public Message(String message, String details, IMessage.Kind kind, ISourceLocation sLoc, Throwable thrown,
-                       ISourceLocation[] otherLocs, boolean declared, int id, int sourcestart, int sourceend) {
-               this.details = details;
-               this.id = id;
-               this.sourceStart = sourcestart;
-               this.sourceEnd = sourceend;
-               this.message = ((message != null) ? message : ((thrown == null) ? null : thrown.getMessage()));
-               this.kind = kind;
-               this.sourceLocation = sLoc;
-               this.thrown = thrown;
-               if (otherLocs != null) {
-                       this.extraSourceLocations = Collections.unmodifiableList(Arrays.asList(otherLocs));
-               } else {
-                       this.extraSourceLocations = Collections.emptyList();
-               }
-               if (null == this.kind) {
-                       throw new IllegalArgumentException("null kind");
-               }
-               if (null == this.message) {
-                       throw new IllegalArgumentException("null message");
-               }
-               this.declared = declared;
-       }
-
-       /**
-        * Create a message, handling null values for message and kind if thrown is not null.
-        * 
-        * @param message the String used as the underlying message
-        * @param kind the IMessage.Kind of message - not null
-        * @param thrown the Throwable, if any, associated with this message
-        * @param sourceLocation the ISourceLocation, if any, associated with this message
-        * @throws IllegalArgumentException if message is null and thrown is null or has a null message, or if kind is null and thrown
-        *         is null.
-        */
-       public Message(String message, IMessage.Kind kind, Throwable thrown, ISourceLocation sourceLocation) {
-               this(message, "", kind, sourceLocation, thrown, null);
-       }
-
-       /** @return the kind of this message */
-       public IMessage.Kind getKind() {
-               return kind;
-       }
-
-       /** @return true if kind == IMessage.ERROR */
-       public boolean isError() {
-               return kind == IMessage.ERROR;
-       }
-
-       /** @return true if kind == IMessage.WARNING */
-       public boolean isWarning() {
-               return kind == IMessage.WARNING;
-       }
-
-       /** @return true if kind == IMessage.DEBUG */
-       public boolean isDebug() {
-               return kind == IMessage.DEBUG;
-       }
-
-       public boolean isTaskTag() {
-               return kind == IMessage.TASKTAG;
-       }
-
-       /**
-        * @return true if kind == IMessage.INFO
-        */
-       public boolean isInfo() {
-               return kind == IMessage.INFO;
-       }
-
-       /** @return true if kind == IMessage.ABORT */
-       public boolean isAbort() {
-               return kind == IMessage.ABORT;
-       }
-
-       /** Caller can verify if this message came about because of a DEOW */
-       public boolean getDeclared() {
-               return declared;
-       }
-
-       /**
-        * @return true if kind == IMessage.FAIL
-        */
-       public boolean isFailed() {
-               return kind == IMessage.FAIL;
-       }
-
-       /** @return non-null String with simple message */
-       final public String getMessage() {
-               return message;
-       }
-
-       /** @return Throwable associated with this message, or null if none */
-       final public Throwable getThrown() {
-               return thrown;
-       }
-
-       /** @return ISourceLocation associated with this message, or null if none */
-       final public ISourceLocation getSourceLocation() {
-               return sourceLocation;
-       }
-
-       public String toString() {
-               return MessageUtil.renderMessage(this, false);
-       }
-
-       public String getDetails() {
-               return details;
-       }
-
-       public List<ISourceLocation> getExtraSourceLocations() {
-               return extraSourceLocations;
-       }
-
-       public int getID() {
-               return id;
-       }
-
-       public int getSourceStart() {
-               return sourceStart;
-       }
-
-       public int getSourceEnd() {
-               return sourceEnd;
-       }
-}
diff --git a/bridge/src/org/aspectj/bridge/MessageHandler.java b/bridge/src/org/aspectj/bridge/MessageHandler.java
deleted file mode 100644 (file)
index 6fd8539..0000000
+++ /dev/null
@@ -1,265 +0,0 @@
-/* *******************************************************************
- * Copyright (c) 1999-2001 Xerox Corporation, 
- *               2002 Palo Alto Research Center, Incorporated (PARC).
- * All rights reserved. 
- * This program and the accompanying materials are made available 
- * under the terms of the Eclipse Public License v1.0 
- * which accompanies this distribution and is available at 
- * http://www.eclipse.org/legal/epl-v10.html 
- *  
- * Contributors: 
- *     Xerox/PARC     initial implementation 
- * ******************************************************************/
-
-package org.aspectj.bridge;
-
-import java.util.ArrayList;
-import java.util.Collections;
-import java.util.List;
-
-/**
- * This handler accumulates messages. To control messages accumulated, clients can ignore messages of a given kind, or install a
- * listener/interceptor. The interceptor handles all messages (even null) first, and can halt further processing/accumlation by
- * returning true. Clients can obtain messages accumulated using the get... methods. XXX this does not permit messages to be
- * removed.
- * 
- * @author PARC
- * @author Andy Clement
- */
-public class MessageHandler implements IMessageHolder {
-
-       /** messages accumulated */
-       protected final ArrayList<IMessage> messages;
-       /** kinds of messages to be ignored */
-       protected final ArrayList<IMessage.Kind> ignoring;
-       /** result of handleMessage(..) for messages not accumulated (ignored) */
-       protected boolean handleMessageResult;
-       /** listener which can halt processing by returning true */
-       protected IMessageHandler interceptor;
-
-       /**
-        * same as MessageHandler(false)
-        */
-       public MessageHandler() {
-               this(false);
-       }
-
-       /**
-        * @param accumulateOnly the result of handleMessage (i.e., if true, then only accumulate messages - stop processing
-        */
-       public MessageHandler(boolean accumulateOnly) {
-               messages = new ArrayList<IMessage>();
-               ignoring = new ArrayList<IMessage.Kind>();
-               init(accumulateOnly);
-               ignore(IMessage.WEAVEINFO); // Off by default, need to explicitly be enabled (see -showWeaveInfo)
-       }
-
-       /**
-        * Initialize this, removing any messages accumulated, kinds being ignored, or interceptor. Assume that this should return false
-        * from handleMessage(..).
-        */
-       public void init() {
-               init(false);
-       }
-
-       /**
-        * Initialize this, removing any messages accumulated, kinds being ignored, or interceptor.
-        * 
-        * @param accumulateOnly boolean value returned from handleMessage after accumulating in list
-        */
-       public void init(boolean accumulateOnly) {
-               handleMessageResult = accumulateOnly;
-               if (0 < messages.size()) {
-                       messages.clear();
-               }
-               if (0 < ignoring.size()) {
-                       boolean ignoringWeaveMessages = isIgnoring(IMessage.WEAVEINFO);
-                       ignoring.clear();
-                       if (ignoringWeaveMessages) {
-                               ignore(IMessage.WEAVEINFO);
-                       }
-               }
-               if (null != interceptor) {
-                       interceptor = null;
-               }
-       }
-
-       /**
-        * Clear the messages without changing other behavior.
-        */
-       public void clearMessages() {
-               if (0 < messages.size()) {
-                       messages.clear();
-               }
-       }
-
-       // ---------------------- IMessageHandler implementation
-       /**
-        * This implementation accumulates message. If an interceptor is installed and returns true (message handled), then processing
-        * halts and the message is not accumulated.
-        * 
-        * @see org.aspectj.bridge.IMessageHandler#handleMessage(IMessage)
-        * @return true on interception or the constructor value otherwise
-        */
-       public boolean handleMessage(IMessage message) {
-               if ((null != interceptor) && (interceptor.handleMessage(message))) {
-                       return true;
-               }
-               if (null == message) {
-                       throw new IllegalArgumentException("null message");
-               }
-               if (!ignoring.contains(message.getKind())) {
-                       messages.add(message);
-               }
-               return handleMessageResult;
-       }
-
-       /**
-        * @return true if this kind has been flagged to be ignored.
-        * @see #ignore(IMessage.Kind)
-        * @see org.aspectj.bridge.IMessageHandler#isIgnoring(Kind)
-        */
-       public boolean isIgnoring(IMessage.Kind kind) {
-               return ((null != kind) && (ignoring.contains(kind)));
-       }
-
-       // ---------------------- end of IMessageHandler implementation
-
-       /**
-        * Set a message kind to be ignored from now on
-        */
-       public void ignore(IMessage.Kind kind) { // XXX sync
-               if ((null != kind) && (!ignoring.contains(kind))) {
-                       ignoring.add(kind);
-               }
-       }
-
-       /**
-        * Remove a message kind from the list of those ignored from now on.
-        */
-       public void dontIgnore(IMessage.Kind kind) {
-               if (null != kind) {
-                       ignoring.remove(kind);
-               }
-       }
-
-       /**
-        * @see org.aspectj.bridge.IMessageHolder#hasAnyMessage(Kind, boolean)
-        */
-       public boolean hasAnyMessage(final IMessage.Kind kind, final boolean orGreater) {
-               if (null == kind) {
-                       return (0 < messages.size());
-               }
-               if (!orGreater) {
-                       for (IMessage m : messages) {
-                               if (kind == m.getKind()) {
-                                       return true;
-                               }
-                       }
-               } else {
-                       for (IMessage m : messages) {
-                               if (kind.isSameOrLessThan(m.getKind())) {
-                                       return true;
-                               }
-                       }
-               }
-               return false;
-       }
-
-       /**
-        * @return number of messages accumulated of a given kind
-        */
-       public int numMessages(IMessage.Kind kind, final boolean orGreater) {
-               if (null == kind) {
-                       return messages.size();
-               }
-               int result = 0;
-               if (!orGreater) {
-                       for (IMessage m : messages) {
-                               if (kind == m.getKind()) {
-                                       result++;
-                               }
-                       }
-               } else {
-                       for (IMessage m : messages) {
-                               if (kind.isSameOrLessThan(m.getKind())) {
-                                       result++;
-                               }
-                       }
-               }
-               return result;
-       }
-
-       /**
-        * @see org.aspectj.bridge.IMessageHolder#getUnmodifiableListView()
-        */
-       public List<IMessage> getUnmodifiableListView() {
-               return Collections.unmodifiableList(messages);
-       }
-
-       /**
-        * Get all messages or those of a specific kind. Pass null to get all kinds.
-        * 
-        * @param kind the IMessage.Kind expected, or null for all messages
-        * @return IMessage[] of messages of the right kind
-        */
-       public IMessage[] getMessages(IMessage.Kind kind, final boolean orGreater) {
-               if (null == kind) {
-                       return messages.toArray(IMessage.RA_IMessage);
-               }
-               ArrayList<IMessage> result = new ArrayList<IMessage>();
-               if (!orGreater) {
-                       for (IMessage m : messages) {
-                               if (kind == m.getKind()) {
-                                       result.add(m);
-                               }
-                       }
-               } else {
-                       for (IMessage m : messages) {
-                               if (kind.isSameOrLessThan(m.getKind())) {
-                                       result.add(m);
-                               }
-                       }
-               }
-               if (0 == result.size()) {
-                       return IMessage.RA_IMessage;
-               }
-               return result.toArray(IMessage.RA_IMessage);
-       }
-
-       /**
-        * @return array of error messages, or IMessage.NONE
-        */
-       public IMessage[] getErrors() {
-               return getMessages(IMessage.ERROR, false);
-       }
-
-       /**
-        * @return array of warning messages, or IMessage.NONE
-        */
-       public IMessage[] getWarnings() {
-               return getMessages(IMessage.WARNING, false);
-       }
-
-       /**
-        * Set the interceptor which gets any message before we process it.
-        * 
-        * @param interceptor the IMessageHandler passed the message. Pass null to remove the old interceptor.
-        */
-       public void setInterceptor(IMessageHandler interceptor) {
-               this.interceptor = interceptor;
-       }
-
-       /**
-        * @return String containing list of messages
-        */
-       public String toString() {
-               if (0 == messages.size()) {
-                       return "MessageHandler: no messages";
-               } else {
-                       return "MessageHandler: " + messages;
-               }
-
-       }
-
-}
diff --git a/bridge/src/org/aspectj/bridge/MessageUtil.java b/bridge/src/org/aspectj/bridge/MessageUtil.java
deleted file mode 100644 (file)
index 6d85ea6..0000000
+++ /dev/null
@@ -1,1116 +0,0 @@
-/* *******************************************************************
- * Copyright (c) 1999-2001 Xerox Corporation, 
- *               2002 Palo Alto Research Center, Incorporated (PARC).
- * All rights reserved. 
- * This program and the accompanying materials are made available 
- * under the terms of the Eclipse Public License v1.0 
- * which accompanies this distribution and is available at 
- * http://www.eclipse.org/legal/epl-v10.html 
- *  
- * Contributors: 
- *     Xerox/PARC     initial implementation 
- * ******************************************************************/
-
-package org.aspectj.bridge;
-
-import java.io.File;
-import java.io.IOException;
-import java.io.OutputStream;
-import java.io.PrintStream;
-import java.io.PrintWriter;
-import java.io.StringWriter;
-import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.Collection;
-import java.util.Collections;
-import java.util.Iterator;
-import java.util.List;
-
-import org.aspectj.bridge.IMessage.Kind;
-import org.aspectj.util.LangUtil;
-
-/**
- * Convenience API's for constructing, printing, and sending messages.
- */
-public class MessageUtil {
-
-       // ------ some constant, content-less messages
-       // no variants for "info" or "debug", which should always have content
-       public static final IMessage ABORT_NOTHING_TO_RUN = new Message("aborting - nothing to run", IMessage.ABORT, null, null);
-
-       public static final IMessage FAIL_INCOMPLETE = new Message("run not completed", IMessage.FAIL, null, null);
-
-       public static final IMessage ABORT_NOMESSAGE = new Message("", IMessage.ABORT, null, null);
-
-       public static final IMessage FAIL_NOMESSAGE = new Message("", IMessage.FAIL, null, null);
-
-       public static final IMessage ERROR_NOMESSAGE = new Message("", IMessage.ERROR, null, null);
-
-       public static final IMessage WARNING_NOMESSAGE = new Message("", IMessage.WARNING, null, null);
-
-       /** handle abort message (ignored if handler is null) */
-       public static boolean abort(IMessageHandler handler, String message) {
-               return ((null != handler) && handler.handleMessage(abort(message)));
-       }
-
-       /** create and handle exception message (ignored if handler is null) */
-       public static boolean abort(IMessageHandler handler, String message, Throwable t) {
-               if (handler != null) {
-                       return handler.handleMessage(abort(message, t));
-               }
-               return false;
-       }
-
-       /** create and handle fail message (ignored if handler is null) */
-       public static boolean fail(IMessageHandler handler, String message) {
-               return ((null != handler) && handler.handleMessage(fail(message)));
-       }
-
-       // /** create and handle fail message from reader (ignored if handler is null) */
-       // public static boolean fail(IMessageHandler handler, String message, LineReader reader) {
-       // return ((null != handler)
-       // && handler.handleMessage(fail(message, reader)));
-       // }
-
-       /** create and handle fail message (ignored if handler is null) */
-       public static boolean fail(IMessageHandler handler, String message, Throwable thrown) {
-               return ((null != handler) && handler.handleMessage(fail(message, thrown)));
-       }
-
-       /** create and handle error message (ignored if handler is null) */
-       public static boolean error(IMessageHandler handler, String message) {
-               return ((null != handler) && handler.handleMessage(error(message)));
-       }
-
-       /** create and handle warn message (ignored if handler is null) */
-       public static boolean warn(IMessageHandler handler, String message) {
-               return ((null != handler) && handler.handleMessage(warn(message)));
-       }
-
-       /** create and handle debug message (ignored if handler is null) */
-       public static boolean debug(IMessageHandler handler, String message) {
-               return ((null != handler) && handler.handleMessage(debug(message)));
-       }
-
-       /** create and handle info message (ignored if handler is null) */
-       public static boolean info(IMessageHandler handler, String message) {
-               return ((null != handler) && handler.handleMessage(info(message)));
-       }
-
-       /** @return ABORT_NOMESSAGE if message is empty or IMessage otherwise */
-       //
-       public static IMessage abort(String message) {
-               if (LangUtil.isEmpty(message)) {
-                       return ABORT_NOMESSAGE;
-               } else {
-                       return new Message(message, IMessage.ABORT, null, null);
-               }
-       }
-
-       /**
-        * @return abort IMessage with thrown and message o ABORT_NOMESSAGE if both are empty/null
-        */
-       //
-       public static IMessage abort(String message, Throwable thrown) {
-               if (!LangUtil.isEmpty(message)) {
-                       return new Message(message, IMessage.ABORT, thrown, null);
-               } else if (null == thrown) {
-                       return ABORT_NOMESSAGE;
-               } else {
-                       return new Message(thrown.getMessage(), IMessage.ABORT, thrown, null);
-               }
-       }
-
-       /** @return FAIL_NOMESSAGE if message is empty or IMessage otherwise */
-       public static IMessage fail(String message) {
-               if (LangUtil.isEmpty(message)) {
-                       return FAIL_NOMESSAGE;
-               } else {
-                       return new Message(message, IMessage.FAIL, null, ISourceLocation.EMPTY);
-
-                       // return fail(message, (LineReader) null);
-               }
-       }
-
-       /**
-        * Create fail message. If message is empty but thrown is not, use thrown.getMessage() as the message. If message is empty and
-        * thrown is null, return FAIL_NOMESSAGE.
-        * 
-        * @return FAIL_NOMESSAGE if thrown is null and message is empty or IMessage FAIL with message and thrown otherwise
-        */
-       public static IMessage fail(String message, Throwable thrown) {
-               if (LangUtil.isEmpty(message)) {
-                       if (null == thrown) {
-                               return FAIL_NOMESSAGE;
-                       } else {
-                               return new Message(thrown.getMessage(), IMessage.FAIL, thrown, null);
-                       }
-               } else {
-                       return new Message(message, IMessage.FAIL, thrown, null);
-               }
-       }
-
-       /**
-        * @return IMessage with IMessage.Kind FAIL and message as text and soure location from reader
-        */
-       // public static IMessage fail(String message) {//, LineReader reader) {
-       // ISourceLocation loc = null;
-       // if (null == reader) {
-       // loc = ISourceLocation.EMPTY;
-       // } else {
-       // int line = reader.getLineNumber();
-       // if (0 < line) {
-       // line = 0;
-       // }
-       // loc = new SourceLocation(reader.getFile(), line, line, 0);
-       // }
-       // return new Message(message, IMessage.FAIL, null, ISourceLocation.EMPTY);
-       // }
-
-       /** @return ERROR_NOMESSAGE if message is empty or IMessage otherwise */
-       //
-       public static IMessage error(String message, ISourceLocation location) {
-               if (LangUtil.isEmpty(message)) {
-                       return ERROR_NOMESSAGE;
-               } else {
-                       return new Message(message, IMessage.ERROR, null, location);
-               }
-       }
-
-       /** @return WARNING_NOMESSAGE if message is empty or IMessage otherwise */
-       //
-       public static IMessage warn(String message, ISourceLocation location) {
-               if (LangUtil.isEmpty(message)) {
-                       return WARNING_NOMESSAGE;
-               } else {
-                       return new Message(message, IMessage.WARNING, null, location);
-               }
-       }
-
-       /** @return ERROR_NOMESSAGE if message is empty or IMessage otherwise */
-       //
-       public static IMessage error(String message) {
-               if (LangUtil.isEmpty(message)) {
-                       return ERROR_NOMESSAGE;
-               } else {
-                       return new Message(message, IMessage.ERROR, null, null);
-               }
-       }
-
-       /** @return WARNING_NOMESSAGE if message is empty or IMessage otherwise */
-       //
-       public static IMessage warn(String message) {
-               if (LangUtil.isEmpty(message)) {
-                       return WARNING_NOMESSAGE;
-               } else {
-                       return new Message(message, IMessage.WARNING, null, null);
-               }
-       }
-
-       /** @return IMessage.DEBUG message with message content */
-       public static IMessage debug(String message) {
-               return new Message(message, IMessage.DEBUG, null, null);
-       }
-
-       /** @return IMessage.INFO message with message content */
-       public static IMessage info(String message) {
-               return new Message(message, IMessage.INFO, null, null);
-       }
-
-       // /** @return ISourceLocation with the current File/line of the reader */
-       // public static ISourceLocation makeSourceLocation(LineReader reader) {
-       // LangUtil.throwIaxIfNull(reader, "reader");
-       //
-       // int line = reader.getLineNumber();
-       // if (0 < line) {
-       // line = 0;
-       // }
-       // return new SourceLocation(reader.getFile(), line, line, 0);
-       // }
-
-       // ------------------------ printing messages
-       /**
-        * Print total counts message to the print stream, starting each on a new line
-        * 
-        * @param messageHolder
-        * @param out
-        */
-       public static void printMessageCounts(PrintStream out, IMessageHolder messageHolder) {
-               if ((null == out) || (null == messageHolder)) {
-                       return;
-               }
-               printMessageCounts(out, messageHolder, "");
-       }
-
-       public static void printMessageCounts(PrintStream out, IMessageHolder holder, String prefix) {
-               out.println(prefix + "MessageHolder: " + MessageUtil.renderCounts(holder));
-       }
-
-       /**
-        * Print all message to the print stream, starting each on a new line
-        * 
-        * @param messageHolder
-        * @param out
-        * @see #print(PrintStream, String, IMessageHolder, IMessageRenderer, IMessageHandler)
-        */
-       public static void print(PrintStream out, IMessageHolder messageHolder) {
-               print(out, messageHolder, (String) null, (IMessageRenderer) null, (IMessageHandler) null);
-       }
-
-       /**
-        * Print all message to the print stream, starting each on a new line, with a prefix.
-        * 
-        * @param messageHolder
-        * @param out
-        * @see #print(PrintStream, String, IMessageHolder, IMessageRenderer, IMessageHandler)
-        */
-       public static void print(PrintStream out, IMessageHolder holder, String prefix) {
-               print(out, holder, prefix, (IMessageRenderer) null, (IMessageHandler) null);
-       }
-
-       /**
-        * Print all message to the print stream, starting each on a new line, with a prefix and using a renderer.
-        * 
-        * @param messageHolder
-        * @param out
-        * @param renderer IMessageRender to render result - use MESSAGE_LINE if null
-        * @see #print(PrintStream, String, IMessageHolder, IMessageRenderer, IMessageHandler)
-        */
-       public static void print(PrintStream out, IMessageHolder holder, String prefix, IMessageRenderer renderer) {
-               print(out, holder, prefix, renderer, (IMessageHandler) null);
-       }
-
-       /**
-        * Print all message to the print stream, starting each on a new line, with a prefix and using a renderer. The first line
-        * renders a summary: {prefix}MessageHolder: {summary} Each message line has the following form:
-        * 
-        * <pre>
-        * {prefix}[{kind} {index}]: {rendering}
-        * </pre>
-        * 
-        * (where "{index}" (length 3) is the position within the set of like-kinded messages, ignoring selector omissions. Renderers
-        * are free to render multi-line output.
-        * 
-        * @param out the PrintStream sink - return silently if null
-        * @param messageHolder the IMessageHolder with the messages to print
-        * @param renderer IMessageRender to render result - use MESSAGE_ALL if null
-        * @param selector IMessageHandler to select messages to render - if null, do all non-null
-        */
-       public static void print(PrintStream out, IMessageHolder holder, String prefix, IMessageRenderer renderer,
-                       IMessageHandler selector) {
-               print(out, holder, prefix, renderer, selector, true);
-       }
-
-       public static void print(PrintStream out, IMessageHolder holder, String prefix, IMessageRenderer renderer,
-                       IMessageHandler selector, boolean printSummary) {
-               if ((null == out) || (null == holder)) {
-                       return;
-               }
-               if (null == renderer) {
-                       renderer = MESSAGE_ALL;
-               }
-               if (null == selector) {
-                       selector = PICK_ALL;
-               }
-               if (printSummary) {
-                       out.println(prefix + "MessageHolder: " + MessageUtil.renderCounts(holder));
-               }
-               for (IMessage.Kind kind : IMessage.KINDS) {
-                       if (!selector.isIgnoring(kind)) {
-                               IMessage[] messages = holder.getMessages(kind, IMessageHolder.EQUAL);
-                               for (int i = 0; i < messages.length; i++) {
-                                       if (selector.handleMessage(messages[i])) {
-                                               String label = (null == prefix ? "" : prefix + "[" + kind + " " + LangUtil.toSizedString(i, 3) + "]: ");
-                                               out.println(label + renderer.renderToString(messages[i]));
-                                       }
-                               }
-                       }
-               }
-       }
-
-       public static String toShortString(IMessage message) {
-               if (null == message) {
-                       return "null";
-               }
-               String m = message.getMessage();
-               Throwable t = message.getThrown();
-
-               return (message.getKind() + (null == m ? "" : ": " + m) + (null == t ? "" : ": " + LangUtil.unqualifiedClassName(t)));
-       }
-
-       /** @return int number of message of this kind (optionally or greater) in list */
-       public static int numMessages(List<IMessage> messages, Kind kind, boolean orGreater) {
-               if (LangUtil.isEmpty(messages)) {
-                       return 0;
-               }
-               IMessageHandler selector = makeSelector(kind, orGreater, null);
-               IMessage[] result = visitMessages(messages, selector, true, false);
-               return result.length;
-       }
-
-       /**
-        * Select all messages in holder except those of the same kind (optionally or greater). If kind is null, then all messages are
-        * rejected, so an empty list is returned.
-        * 
-        * @return unmodifiable list of specified IMessage
-        */
-       public static IMessage[] getMessagesExcept(IMessageHolder holder, final IMessage.Kind kind, final boolean orGreater) {
-               if ((null == holder) || (null == kind)) {
-                       return new IMessage[0];
-               }
-
-               IMessageHandler selector = new IMessageHandler() {
-                       public boolean handleMessage(IMessage message) {
-                               IMessage.Kind test = message.getKind();
-                               return (!(orGreater ? kind.isSameOrLessThan(test) : kind == test));
-                       }
-
-                       public boolean isIgnoring(Kind kind) {
-                               return false;
-                       }
-
-                       public void dontIgnore(IMessage.Kind kind) {
-
-                       }
-
-                       public void ignore(Kind kind) {
-                       }
-               };
-               return visitMessages(holder, selector, true, false);
-       }
-
-       /** @return unmodifiable list of IMessage complying with parameters */
-       public static List<IMessage> getMessages(IMessageHolder holder, IMessage.Kind kind, boolean orGreater, String infix) {
-               if (null == holder) {
-                       return Collections.emptyList();
-               }
-               if ((null == kind) && LangUtil.isEmpty(infix)) {
-                       return holder.getUnmodifiableListView();
-               }
-               IMessageHandler selector = makeSelector(kind, orGreater, infix);
-               IMessage[] messages = visitMessages(holder, selector, true, false);
-               if (LangUtil.isEmpty(messages)) {
-                       return Collections.emptyList();
-               }
-               return Collections.unmodifiableList(Arrays.asList(messages));
-       }
-
-       /**
-        * Extract messages of type kind from the input list.
-        * 
-        * @param messages if null, return EMPTY_LIST
-        * @param kind if null, return messages
-        * @see MessageHandler#getMessages(Kind)
-        */
-       public static List<IMessage> getMessages(List<IMessage> messages, IMessage.Kind kind) {
-               if (null == messages) {
-                       return Collections.emptyList();
-               }
-               if (null == kind) {
-                       return messages;
-               }
-               ArrayList<IMessage> result = new ArrayList<IMessage>();
-               for (IMessage message : messages) {
-                       if (kind == message.getKind()) {
-                               result.add(message);
-                       }
-               }
-               if (0 == result.size()) {
-                       return Collections.emptyList();
-               }
-               return result;
-       }
-
-       /**
-        * Map to the kind of messages associated with this string key.
-        * 
-        * @param kind the String representing the kind of message (IMessage.Kind.toString())
-        * @return Kind the associated IMessage.Kind, or null if not found
-        */
-       public static IMessage.Kind getKind(String kind) {
-               if (null != kind) {
-                       kind = kind.toLowerCase();
-                       for (IMessage.Kind k : IMessage.KINDS) {
-                               if (kind.equals(k.toString())) {
-                                       return k;
-                               }
-                       }
-               }
-               return null;
-       }
-
-       /**
-        * Run visitor over the set of messages in holder, optionally accumulating those accepted by the visitor
-        */
-       public static IMessage[] visitMessages(IMessageHolder holder, IMessageHandler visitor, boolean accumulate, boolean abortOnFail) {
-               if (null == holder) {
-                       return IMessage.RA_IMessage;
-               } else {
-                       return visitMessages(holder.getUnmodifiableListView(), visitor, accumulate, abortOnFail);
-               }
-       }
-
-       /**
-        * Run visitor over the set of messages in holder, optionally accumulating those accepted by the visitor
-        */
-       public static IMessage[] visitMessages(IMessage[] messages, IMessageHandler visitor, boolean accumulate, boolean abortOnFail) {
-               if (LangUtil.isEmpty(messages)) {
-                       return IMessage.RA_IMessage;
-               } else {
-                       return visitMessages(Arrays.asList(messages), visitor, accumulate, abortOnFail);
-               }
-       }
-
-       /**
-        * Run visitor over a collection of messages, optionally accumulating those accepted by the visitor
-        * 
-        * @param messages if null or empty, return IMessage.RA_IMessage
-        * @param visitor run visitor.handleMessage(message) on each message - if null and messages not empty, IllegalArgumentException
-        * @param accumulate if true, then return accepted IMessage[]
-        * @param abortOnFail if true and visitor returns false, stop visiting
-        * @return IMessage.RA_IMessage if collection is empty, if not accumulate, or if visitor accepted no IMessage, or IMessage[] of
-        *         accepted messages otherwise
-        * @throws IllegalArgumentException if any in collection are not instanceof IMessage
-        */
-       public static IMessage[] visitMessages(Collection<IMessage> messages, IMessageHandler visitor, final boolean accumulate,
-                       final boolean abortOnFail) {
-               if (LangUtil.isEmpty(messages)) {
-                       return IMessage.RA_IMessage;
-               }
-               LangUtil.throwIaxIfNull(visitor, "visitor");
-               ArrayList<IMessage> result = (accumulate ? new ArrayList<IMessage>() : null);
-               for (IMessage m : messages) {
-                       if (visitor.handleMessage(m)) {
-                               if (accumulate) {
-                                       result.add(m);
-                               }
-                       } else if (abortOnFail) {
-                               break;
-                       }
-               }
-               if (!accumulate || (0 == result.size())) {
-                       return IMessage.RA_IMessage;
-               } else {
-                       return result.toArray(IMessage.RA_IMessage);
-               }
-       }
-
-       /**
-        * Make an IMessageHandler that handles IMessage if they have the right kind (or greater) and contain some infix String.
-        * 
-        * @param kind the IMessage.Kind required of the message
-        * @param orGreater if true, also accept messages with greater kinds, as defined by IMessage.Kind.COMPARATOR
-        * @param infix the String text to require in the message - may be null or empty to accept any message with the specified kind.
-        * @return IMessageHandler selector that works to param specs
-        */
-       public static IMessageHandler makeSelector(IMessage.Kind kind, boolean orGreater, String infix) {
-               if (!orGreater && LangUtil.isEmpty(infix)) {
-                       if (kind == IMessage.ABORT) {
-                               return PICK_ABORT;
-                       } else if (kind == IMessage.DEBUG) {
-                               return PICK_DEBUG;
-                       } else if (kind == IMessage.DEBUG) {
-                               return PICK_DEBUG;
-                       } else if (kind == IMessage.ERROR) {
-                               return PICK_ERROR;
-                       } else if (kind == IMessage.FAIL) {
-                               return PICK_FAIL;
-                       } else if (kind == IMessage.INFO) {
-                               return PICK_INFO;
-                       } else if (kind == IMessage.WARNING) {
-                               return PICK_WARNING;
-                       }
-               }
-               return new KindSelector(kind, orGreater, infix);
-       }
-
-       // ------------------ visitors to select messages
-       public static final IMessageHandler PICK_ALL = new KindSelector((IMessage.Kind) null);
-       public static final IMessageHandler PICK_ABORT = new KindSelector(IMessage.ABORT);
-       public static final IMessageHandler PICK_DEBUG = new KindSelector(IMessage.DEBUG);
-       public static final IMessageHandler PICK_ERROR = new KindSelector(IMessage.ERROR);
-       public static final IMessageHandler PICK_FAIL = new KindSelector(IMessage.FAIL);
-       public static final IMessageHandler PICK_INFO = new KindSelector(IMessage.INFO);
-       public static final IMessageHandler PICK_WARNING = new KindSelector(IMessage.WARNING);
-       public static final IMessageHandler PICK_ABORT_PLUS = new KindSelector(IMessage.ABORT, true);
-       public static final IMessageHandler PICK_DEBUG_PLUS = new KindSelector(IMessage.DEBUG, true);
-       public static final IMessageHandler PICK_ERROR_PLUS = new KindSelector(IMessage.ERROR, true);
-       public static final IMessageHandler PICK_FAIL_PLUS = new KindSelector(IMessage.FAIL, true);
-       public static final IMessageHandler PICK_INFO_PLUS = new KindSelector(IMessage.INFO, true);
-       public static final IMessageHandler PICK_WARNING_PLUS = new KindSelector(IMessage.WARNING, true);
-
-       /** implementation for PICK_... constants */
-       private static class KindSelector implements IMessageHandler {
-               final IMessage.Kind sought;
-               final boolean floor;
-               final String infix;
-
-               KindSelector(IMessage.Kind sought) {
-                       this(sought, false);
-               }
-
-               KindSelector(IMessage.Kind sought, boolean floor) {
-                       this(sought, floor, null);
-               }
-
-               KindSelector(IMessage.Kind sought, boolean floor, String infix) {
-                       this.sought = sought;
-                       this.floor = floor;
-                       this.infix = (LangUtil.isEmpty(infix) ? null : infix);
-               }
-
-               /**
-                * @return false if this message is null, of true if we seek any kind (null) or if this has the exact kind we seek and this
-                *         has any text sought
-                */
-               public boolean handleMessage(IMessage message) {
-                       return ((null != message) && !isIgnoring(message.getKind()) && textIn(message));
-               }
-
-               /** @return true if handleMessage would return false for a message of this kind */
-               public boolean isIgnoring(IMessage.Kind kind) {
-                       if (!floor) {
-                               return ((null != sought) && (sought != kind));
-                       } else if (null == sought) {
-                               return false;
-                       } else {
-                               return (0 < IMessage.Kind.COMPARATOR.compare(sought, kind));
-                       }
-               }
-
-               public void dontIgnore(IMessage.Kind kind) {
-
-               }
-
-               private boolean textIn(IMessage message) {
-                       if (null == infix) {
-                               return true;
-                       }
-                       String text = message.getMessage();
-                       return (text.indexOf(infix) != -1);
-               }
-
-               public void ignore(Kind kind) {
-               }
-       }
-
-       // ------------------ components to render messages
-       /** parameterize rendering behavior for messages */
-       public static interface IMessageRenderer {
-               String renderToString(IMessage message);
-       }
-
-       /** render message more verbosely if it is worse */
-       public static final IMessageRenderer MESSAGE_SCALED = new IMessageRenderer() {
-               public String toString() {
-                       return "MESSAGE_SCALED";
-               }
-
-               public String renderToString(IMessage message) {
-                       if (null == message) {
-                               return "((IMessage) null)";
-                       }
-                       IMessage.Kind kind = message.getKind();
-                       int level = 3;
-                       if ((kind == IMessage.ABORT) || (kind == IMessage.FAIL)) {
-                               level = 1;
-                       } else if ((kind == IMessage.ERROR) || (kind == IMessage.WARNING)) {
-                               level = 2;
-                       } else {
-                               level = 3;
-                       }
-                       String result = null;
-                       switch (level) {
-                       case (1):
-                               result = MESSAGE_TOSTRING.renderToString(message);
-                               break;
-                       case (2):
-                               result = MESSAGE_LINE.renderToString(message);
-                               break;
-                       case (3):
-                               result = MESSAGE_SHORT.renderToString(message);
-                               break;
-                       }
-                       Throwable thrown = message.getThrown();
-                       if (null != thrown) {
-                               if (level == 3) {
-                                       result += "Thrown: \n" + LangUtil.renderExceptionShort(thrown);
-                               } else {
-                                       result += "Thrown: \n" + LangUtil.renderException(thrown);
-                               }
-                       }
-
-                       return result;
-               }
-       };
-
-       /** render message as label, i.e., less than 33 char */
-       public static final IMessageRenderer MESSAGE_LABEL = new IMessageRenderer() {
-               public String toString() {
-                       return "MESSAGE_LABEL";
-               }
-
-               public String renderToString(IMessage message) {
-                       if (null == message) {
-                               return "((IMessage) null)";
-                       }
-                       return renderMessageLine(message, 5, 5, 32);
-               }
-       };
-
-       /** render message as label, i.e., less than 33 char, with no source location */
-       public static final IMessageRenderer MESSAGE_LABEL_NOLOC = new IMessageRenderer() {
-               public String toString() {
-                       return "MESSAGE_LABEL_NOLOC";
-               }
-
-               public String renderToString(IMessage message) {
-                       if (null == message) {
-                               return "((IMessage) null)";
-                       }
-                       return renderMessageLine(message, 10, 0, 32);
-               }
-       };
-
-       /** render message as line, i.e., less than 75 char, no internal line sep */
-       public static final IMessageRenderer MESSAGE_LINE = new IMessageRenderer() {
-               public String toString() {
-                       return "MESSAGE_LINE";
-               }
-
-               public String renderToString(IMessage message) {
-                       if (null == message) {
-                               return "((IMessage) null)";
-                       }
-                       return renderMessageLine(message, 8, 2, 74);
-               }
-       };
-
-       /**
-        * render message as line, i.e., less than 75 char, no internal line sep, trying to trim text as needed to end with a full
-        * source location
-        */
-       public static final IMessageRenderer MESSAGE_LINE_FORCE_LOC = new IMessageRenderer() {
-               public String toString() {
-                       return "MESSAGE_LINE_FORCE_LOC";
-               }
-
-               public String renderToString(IMessage message) {
-                       if (null == message) {
-                               return "((IMessage) null)";
-                       }
-                       return renderMessageLine(message, 2, 40, 74);
-               }
-       };
-
-       /** render message without restriction, up to 10K, including throwable */
-       public static final IMessageRenderer MESSAGE_ALL = new IMessageRenderer() {
-               public String toString() {
-                       return "MESSAGE_ALL";
-               }
-
-               public String renderToString(IMessage message) {
-                       return renderMessage(message);
-               }
-       };
-
-       // /** render message without restriction, up to 10K, including (but eliding) throwable */
-       // public static final IMessageRenderer MESSAGE_ALL_ELIDED= new IMessageRenderer() {
-       // public String toString() { return "MESSAGE_ALL_ELIDED"; }
-       // public String renderToString(IMessage message) {
-       // return renderMessage(message, true);
-       // }
-       // };
-
-       /** render message without restriction, except any Throwable thrown */
-       public static final IMessageRenderer MESSAGE_MOST = new IMessageRenderer() {
-               public String toString() {
-                       return "MESSAGE_MOST";
-               }
-
-               public String renderToString(IMessage message) {
-                       if (null == message) {
-                               return "((IMessage) null)";
-                       }
-                       return renderMessageLine(message, 1, 1, 10000);
-               }
-       };
-
-       /**
-        * render message as wide line, i.e., less than 256 char, no internal line sep, except any Throwable thrown
-        */
-       public static final IMessageRenderer MESSAGE_WIDELINE = new IMessageRenderer() {
-               public String toString() {
-                       return "MESSAGE_WIDELINE";
-               }
-
-               public String renderToString(IMessage message) {
-                       if (null == message) {
-                               return "((IMessage) null)";
-                       }
-                       return renderMessageLine(message, 8, 2, 255); // XXX revert to 256
-               }
-       };
-       /** render message using its toString() or "((IMessage) null)" */
-       public static final IMessageRenderer MESSAGE_TOSTRING = new IMessageRenderer() {
-               public String toString() {
-                       return "MESSAGE_TOSTRING";
-               }
-
-               public String renderToString(IMessage message) {
-                       if (null == message) {
-                               return "((IMessage) null)";
-                       }
-                       return message.toString();
-               }
-       };
-
-       /** render message using toShortString(IMessage)" */
-       public static final IMessageRenderer MESSAGE_SHORT = new IMessageRenderer() {
-               public String toString() {
-                       return "MESSAGE_SHORT";
-               }
-
-               public String renderToString(IMessage message) {
-                       return toShortString(message);
-               }
-       };
-
-       /**
-        * This renders IMessage as String, ignoring empty elements and eliding any thrown stack traces.
-        * 
-        * @return "((IMessage) null)" if null or String rendering otherwise, including everything (esp. throwable stack trace)
-        * @see renderSourceLocation(ISourceLocation loc)
-        */
-       public static String renderMessage(IMessage message) {
-               return renderMessage(message, true);
-       }
-
-       /**
-        * This renders IMessage as String, ignoring empty elements and eliding any thrown.
-        * 
-        * @return "((IMessage) null)" if null or String rendering otherwise, including everything (esp. throwable stack trace)
-        * @see renderSourceLocation(ISourceLocation loc)
-        */
-       public static String renderMessage(IMessage message, boolean elide) {
-               if (null == message) {
-                       return "((IMessage) null)";
-               }
-
-               ISourceLocation loc = message.getSourceLocation();
-               String locString = (null == loc ? "" : " at " + loc);
-
-               String result = message.getKind() + locString + " " + message.getMessage();
-
-               Throwable thrown = message.getThrown();
-               if (thrown != null) {
-                       result += " -- " + LangUtil.renderExceptionShort(thrown);
-                       result += "\n" + LangUtil.renderException(thrown, elide);
-               }
-
-               if (message.getExtraSourceLocations().isEmpty()) {
-                       return result;
-               } else {
-                       return addExtraSourceLocations(message, result);
-               }
-       }
-
-       public static String addExtraSourceLocations(IMessage message, String baseMessage) {
-               StringWriter buf = new StringWriter();
-               PrintWriter writer = new PrintWriter(buf);
-               writer.println(baseMessage);
-               for (Iterator<ISourceLocation> iter = message.getExtraSourceLocations().iterator(); iter.hasNext();) {
-                       ISourceLocation element = iter.next();
-                       if (element != null) {
-                               writer.print("\tsee also: " + element.toString());
-                               if (iter.hasNext()) {
-                                       writer.println();
-                               }
-                       }
-               }
-               try {
-                       buf.close();
-               } catch (IOException ioe) {
-               }
-               return buf.getBuffer().toString();
-       }
-
-       /**
-        * Render ISourceLocation to String, ignoring empty elements (null or ISourceLocation.NO_FILE or ISourceLocation.NO_COLUMN
-        * (though implementations may return 0 from getColumn() when passed NO_COLUMN as input)).
-        * 
-        * @return "((ISourceLocation) null)" if null or String rendering
-        * 
-        *         <pre>
-        * {file:}line{:column}
-        * </pre>
-        * 
-        */
-       public static String renderSourceLocation(ISourceLocation loc) {
-               if (null == loc) {
-                       return "((ISourceLocation) null)";
-               }
-               StringBuffer sb = new StringBuffer();
-
-               File sourceFile = loc.getSourceFile();
-               if (sourceFile != ISourceLocation.NO_FILE) {
-                       sb.append(sourceFile.getPath());
-                       sb.append(":");
-               }
-               int line = loc.getLine();
-               sb.append("" + line);
-
-               int column = loc.getColumn();
-               if (column != ISourceLocation.NO_COLUMN) {
-                       sb.append(":" + column);
-               }
-
-               return sb.toString();
-       }
-
-       /**
-        * Render message in a line. IMessage.Kind is always printed, then any unqualified exception class, then the remainder of text
-        * and location according to their relative scale, all to fit in max characters or less. This does not render thrown except for
-        * the unqualified class name
-        * 
-        * @param max the number of characters - forced to 32..10000
-        * @param textScale relative proportion to spend on message and/or exception message, relative to source location - if 0,
-        *        message is suppressed
-        * @param locScale relative proportion to spend on source location suppressed if 0
-        * @return "((IMessage) null)" or message per spec
-        */
-       public static String renderMessageLine(IMessage message, int textScale, int locScale, int max) {
-
-               if (null == message) {
-                       return "((IMessage) null)";
-               }
-               if (max < 32) {
-                       max = 32;
-               } else if (max > 10000) {
-                       max = 10000;
-               }
-               if (0 > textScale) {
-                       textScale = -textScale;
-               }
-               if (0 > locScale) {
-                       locScale = -locScale;
-               }
-
-               String text = message.getMessage();
-               Throwable thrown = message.getThrown();
-               ISourceLocation sl = message.getSourceLocation();
-               IMessage.Kind kind = message.getKind();
-               StringBuffer result = new StringBuffer();
-               result.append(kind.toString());
-               result.append(": ");
-               if (null != thrown) {
-                       result.append(LangUtil.unqualifiedClassName(thrown) + " ");
-                       if ((null == text) || ("".equals(text))) {
-                               text = thrown.getMessage();
-                       }
-               }
-
-               if (0 == textScale) {
-                       text = "";
-               } else if ((null != text) && (null != thrown)) {
-                       // decide between message and exception text?
-                       String s = thrown.getMessage();
-                       if ((null != s) && (0 < s.length())) {
-                               text += " - " + s;
-                       }
-               }
-               String loc = "";
-               if ((0 != locScale) && (null != sl)) {
-                       File f = sl.getSourceFile();
-                       if (f == ISourceLocation.NO_FILE) {
-                               f = null;
-                       }
-                       if (null != f) {
-                               loc = f.getName();
-                       }
-                       int line = sl.getLine();
-                       int col = sl.getColumn();
-                       int end = sl.getEndLine();
-                       if ((0 == line) && (0 == col) && (0 == end)) {
-                               // ignore numbers if default
-                       } else {
-                               loc += ":" + line + (col == 0 ? "" : ":" + col);
-                               if (line != end) { // XXX consider suppressing nonstandard...
-                                       loc += ":" + end;
-                               }
-                       }
-                       if (!LangUtil.isEmpty(loc)) {
-                               loc = "@[" + loc; // matching "]" added below after clipping
-                       }
-               }
-
-               // now budget between text and loc
-               float totalScale = locScale + textScale;
-               float remainder = max - result.length() - 4;
-               if ((remainder > 0) && (0 < totalScale)) {
-                       int textSize = (int) (remainder * textScale / totalScale);
-                       int locSize = (int) (remainder * locScale / totalScale);
-                       // adjust for underutilization
-                       int extra = locSize - loc.length();
-                       if (0 < extra) {
-                               locSize = loc.length();
-                               textSize += extra;
-                       }
-                       extra = textSize - text.length();
-                       if (0 < extra) {
-                               textSize = text.length();
-                               if (locSize < loc.length()) {
-                                       locSize += extra;
-                               }
-                       }
-                       if (locSize > loc.length()) {
-                               locSize = loc.length();
-                       }
-                       if (textSize > text.length()) {
-                               textSize = text.length();
-                       }
-                       if (0 < textSize) {
-                               result.append(text.substring(0, textSize));
-                       }
-                       if (0 < locSize) {
-                               if (0 < textSize) {
-                                       result.append(" ");
-                               }
-                               result.append(loc.substring(0, locSize) + "]");
-                       }
-               }
-               return result.toString();
-       }
-
-       /** @return String of the form "{(# {type}) }.." for message kinds, skipping 0 */
-       public static String renderCounts(IMessageHolder holder) {
-               if (0 == holder.numMessages(null, false)) {
-                       return "(0 messages)";
-               }
-               StringBuffer sb = new StringBuffer();
-               for (IMessage.Kind kind : IMessage.KINDS) {
-                       int num = holder.numMessages(kind, false);
-                       if (0 < num) {
-                               sb.append(" (" + num + " " + kind + ") ");
-                       }
-               }
-               return sb.toString();
-       }
-
-       /**
-        * Factory for handler adapted to PrintStream XXX weak - only handles println(String)
-        * 
-        * @param handler the IMessageHandler sink for the messages generated
-        * @param kind the IMessage.Kind of message to create
-        * @param overage the OuputStream for text not captured by the handler (if null, System.out used)
-        * @throws IllegalArgumentException if kind or handler is null
-        */
-       public static PrintStream handlerPrintStream(final IMessageHandler handler, final IMessage.Kind kind,
-                       final OutputStream overage, final String prefix) {
-               LangUtil.throwIaxIfNull(handler, "handler");
-               LangUtil.throwIaxIfNull(kind, "kind");
-               class HandlerPrintStream extends PrintStream {
-                       HandlerPrintStream() {
-                               super(null == overage ? System.out : overage);
-                       }
-
-                       public void println() {
-                               println("");
-                       }
-
-                       public void println(Object o) {
-                               println(null == o ? "null" : o.toString());
-                       }
-
-                       public void println(String input) {
-                               String textMessage = (null == prefix ? input : prefix + input);
-                               IMessage m = new Message(textMessage, kind, null, null);
-                               handler.handleMessage(m);
-                       }
-               }
-               return new HandlerPrintStream();
-       }
-
-       /** utility class */
-       private MessageUtil() {
-       }
-
-       /**
-        * Handle all messages in the second handler using the first
-        * 
-        * @param handler the IMessageHandler sink for all messages in source
-        * @param holder the IMessageHolder source for all messages to handle
-        * @param fastFail if true, stop on first failure
-        * @return false if any sink.handleMessage(..) failed
-        */
-       public static boolean handleAll(IMessageHandler sink, IMessageHolder source, boolean fastFail) {
-               return handleAll(sink, source, null, true, fastFail);
-       }
-
-       /**
-        * Handle messages in the second handler using the first
-        * 
-        * @param handler the IMessageHandler sink for all messages in source
-        * @param holder the IMessageHolder source for all messages to handle
-        * @param kind the IMessage.Kind to select, if not null
-        * @param orGreater if true, also accept greater kinds
-        * @param fastFail if true, stop on first failure
-        * @return false if any sink.handleMessage(..) failed
-        */
-       public static boolean handleAll(IMessageHandler sink, IMessageHolder source, IMessage.Kind kind, boolean orGreater,
-                       boolean fastFail) {
-               LangUtil.throwIaxIfNull(sink, "sink");
-               LangUtil.throwIaxIfNull(source, "source");
-               return handleAll(sink, source.getMessages(kind, orGreater), fastFail);
-       }
-
-       /**
-        * Handle messages in the second handler using the first if they are NOT of this kind (optionally, or greater). If you pass null
-        * as the kind, then all messages are ignored and this returns true.
-        * 
-        * @param handler the IMessageHandler sink for all messages in source
-        * @param holder the IMessageHolder source for all messages to handle
-        * @param kind the IMessage.Kind to reject, if not null
-        * @param orGreater if true, also reject greater kinds
-        * @param fastFail if true, stop on first failure
-        * @return false if any sink.handleMessage(..) failed
-        */
-       public static boolean handleAllExcept(IMessageHandler sink, IMessageHolder source, IMessage.Kind kind, boolean orGreater,
-                       boolean fastFail) {
-               LangUtil.throwIaxIfNull(sink, "sink");
-               LangUtil.throwIaxIfNull(source, "source");
-               if (null == kind) {
-                       return true;
-               }
-               IMessage[] messages = getMessagesExcept(source, kind, orGreater);
-               return handleAll(sink, messages, fastFail);
-       }
-
-       /**
-        * Handle messages in the sink.
-        * 
-        * @param handler the IMessageHandler sink for all messages in source
-        * @param sources the IMessage[] messages to handle
-        * @param fastFail if true, stop on first failure
-        * @return false if any sink.handleMessage(..) failed
-        * @throws IllegalArgumentException if sink is null
-        */
-       public static boolean handleAll(IMessageHandler sink, IMessage[] sources, boolean fastFail) {
-               LangUtil.throwIaxIfNull(sink, "sink");
-               if (LangUtil.isEmpty(sources)) {
-                       return true;
-               }
-               boolean result = true;
-               for (int i = 0; i < sources.length; i++) {
-                       if (!sink.handleMessage(sources[i])) {
-                               if (fastFail) {
-                                       return false;
-                               }
-                               if (result) {
-                                       result = false;
-                               }
-                       }
-               }
-               return result;
-       }
-}
diff --git a/bridge/src/org/aspectj/bridge/MessageWriter.java b/bridge/src/org/aspectj/bridge/MessageWriter.java
deleted file mode 100644 (file)
index 3fbeb91..0000000
+++ /dev/null
@@ -1,84 +0,0 @@
-/* *******************************************************************
- * Copyright (c) 1999-2001 Xerox Corporation, 
- *               2002 Palo Alto Research Center, Incorporated (PARC).
- * All rights reserved. 
- * This program and the accompanying materials are made available 
- * under the terms of the Eclipse Public License v1.0 
- * which accompanies this distribution and is available at 
- * http://www.eclipse.org/legal/epl-v10.html 
- *  
- * Contributors: 
- *     Xerox/PARC     initial implementation 
- * ******************************************************************/
-
-package org.aspectj.bridge;
-
-import java.io.PrintWriter;
-
-/**
- * An IMessageHandler implementation that writes all to a PrintWriter.
- * Clients may set this up to throw AbortException for FAIL or ERROR messages.
- * Subclasses may control whether messages are printed and how they
- * are rendered by overriding render(IMessage).
- */
-public class MessageWriter implements IMessageHandler {
-    
-    protected PrintWriter writer;
-    protected boolean abortOnFailure;
-    public MessageWriter(PrintWriter writer, boolean abortOnFailure) {
-        this.writer = (null != writer ? writer : new PrintWriter(System.out));
-        this.abortOnFailure = abortOnFailure;
-    }
-    
-    /**
-     * Handle message by printing and
-     * (if abortOnFailure) throwing an AbortException if 
-     * the messages is a failure or an abort (but not for errors).
-        * @see org.aspectj.bridge.IMessageHandler#handleMessage(IMessage)
-        */
-       public boolean handleMessage(IMessage message) throws AbortException {
-        if ((null != message) && !isIgnoring(message.getKind())) {
-            String result = render(message);
-            if (null != result) {
-                writer.println(result);
-                writer.flush();
-                if (abortOnFailure
-                    && (message.isFailed() || message.isAbort())) {
-                    throw new AbortException(message);
-                }
-            }
-        }
-               return true;
-       }
-    
-    /**
-        * @see org.aspectj.bridge.IMessageHandler#isIgnoring(org.aspectj.bridge.IMessage.Kind)
-        */
-       public boolean isIgnoring(IMessage.Kind kind) { 
-        // XXX share MessageHandler implementation in superclass
-               return false;
-       }
-
-    /**
-     * No-op
-     * @see org.aspectj.bridge.IMessageHandler#isIgnoring(org.aspectj.bridge.IMessage.Kind)
-     * @param kind
-     */
-    public void dontIgnore(IMessage.Kind kind) {
-        
-    }
-
-    /**
-     * No-op
-     * @see org.aspectj.bridge.IMessageHandler#ignore(org.aspectj.bridge.IMessage.Kind)
-     * @param kind
-     */
-       public void ignore(IMessage.Kind kind) {
-       }
-
-    /** @return null to not print, or message rendering (including newlines) */
-    protected String render(IMessage message) {
-        return message.toString();    
-    }
-
-}
diff --git a/bridge/src/org/aspectj/bridge/ReflectionFactory.java b/bridge/src/org/aspectj/bridge/ReflectionFactory.java
deleted file mode 100644 (file)
index 8eb65b3..0000000
+++ /dev/null
@@ -1,103 +0,0 @@
-/* *******************************************************************
- * Copyright (c) 1999-2001 Xerox Corporation, 
- *               2002 Palo Alto Research Center, Incorporated (PARC).
- * All rights reserved. 
- * This program and the accompanying materials are made available 
- * under the terms of the Eclipse Public License v1.0 
- * which accompanies this distribution and is available at 
- * http://www.eclipse.org/legal/epl-v10.html 
- *  
- * Contributors: 
- *     Xerox/PARC     initial implementation 
- * ******************************************************************/
-
-package org.aspectj.bridge;
-
-import java.lang.reflect.Constructor;
-import java.util.Arrays;
-
-/**
- * 
- */
-public class ReflectionFactory { // XXX lease, pool
-       public static final String OLD_AJC = "bridge.tools.impl.OldAjc";
-       public static final String ECLIPSE = "org.aspectj.ajdt.ajc.AjdtCommand";
-
-       private static final Object[] NONE = new Object[0];
-
-       /**
-        * Produce a compiler as an ICommand.
-        * 
-        * @param cname the fully-qualified class name of the command to create by reflection (assuming a public no-argument
-        *        constructor).
-        * @return ICommand compiler or null
-        */
-       public static ICommand makeCommand(String cname, IMessageHandler errorSink) {
-               return (ICommand) make(ICommand.class, cname, NONE, errorSink);
-       }
-
-       /**
-        * Make an object of type c by reflectively loading the class cname and creating an instance using args (if any), signalling
-        * errors (if any) to any errorSink.
-        */
-       private static Object make(Class<?> c, String cname, Object[] args, IMessageHandler errorSink) {
-               final boolean makeErrors = (null != errorSink);
-               Object result = null;
-               try {
-                       final Class<?> cfn = Class.forName(cname);
-                       String error = null;
-                       if (args == NONE) {
-                               result = cfn.newInstance();
-                       } else {
-                               Class<?>[] types = getTypes(args);
-                               Constructor<?> constructor = cfn.getConstructor(types);
-                               if (null != constructor) {
-                                       result = constructor.newInstance(args);
-                               } else {
-                                       if (makeErrors) {
-                                               error = "no constructor for " + c + " using " + Arrays.asList(types);
-                                       }
-                               }
-                       }
-                       if (null != result) {
-                               if (!c.isAssignableFrom(result.getClass())) {
-                                       if (makeErrors) {
-                                               error = "expecting type " + c + " got " + result.getClass();
-                                       }
-                                       result = null;
-                               }
-                       }
-                       if (null != error) {
-                               IMessage mssg = new Message(error, IMessage.FAIL, null, null);
-                               errorSink.handleMessage(mssg);
-                       }
-               } catch (Throwable t) {
-                       if (makeErrors) {
-                               String mssg = "ReflectionFactory unable to load " + cname + " as " + c.getName();
-                               IMessage m = new Message(mssg, IMessage.FAIL, t, null);
-                               errorSink.handleMessage(m);
-                       }
-               }
-               return result;
-       }
-
-       /**
-        * @return Class[] with types of args or matching null elements
-        */
-       private static Class<?>[] getTypes(Object[] args) {
-               if ((null == args) || (0 < args.length)) {
-                       return new Class[0];
-               } else {
-                       Class<?>[] result = new Class[args.length];
-                       for (int i = 0; i < result.length; i++) {
-                               if (null != args[i]) {
-                                       result[i] = args[i].getClass();
-                               }
-                       }
-                       return result;
-               }
-       }
-
-       private ReflectionFactory() {
-       }
-}
diff --git a/bridge/src/org/aspectj/bridge/SourceLocation.java b/bridge/src/org/aspectj/bridge/SourceLocation.java
deleted file mode 100644 (file)
index 739dd52..0000000
+++ /dev/null
@@ -1,199 +0,0 @@
-/* *******************************************************************
- * Copyright (c) 1999-2001 Xerox Corporation, 
- *               2002 Palo Alto Research Center, Incorporated (PARC).
- * All rights reserved. 
- * This program and the accompanying materials are made available 
- * under the terms of the Eclipse Public License v1.0 
- * which accompanies this distribution and is available at 
- * http://www.eclipse.org/legal/epl-v10.html 
- *  
- * Contributors: 
- *     Xerox/PARC     initial implementation 
- * ******************************************************************/
-
-package org.aspectj.bridge;
-
-import java.io.File;
-
-import org.aspectj.util.LangUtil;
-
-/**
- * Immutable source location. This guarantees that the source file is not null and that the numeric values are positive and line <=
- * endLine.
- * 
- * @see org.aspectj.lang.reflect.SourceLocation
- * @see org.aspectj.compiler.base.parser.SourceInfo
- * @see org.aspectj.tools.ide.SourceLine
- * @see org.aspectj.testing.harness.ErrorLine
- */
-public class SourceLocation implements ISourceLocation {
-
-       private static final long serialVersionUID = -5434765814401009794L;
-
-       private transient int cachedHashcode = -1;
-
-       /** used when SourceLocation is not available */
-       public static final ISourceLocation UNKNOWN = new SourceLocation(ISourceLocation.NO_FILE, 0, 0, 0);
-
-       private final File sourceFile;
-       private final int startLine;
-       private final int column;
-       private final int endLine;
-       private int offset;
-       private final String context;
-       private boolean noColumn;
-       private String sourceFileName;
-
-       /** @throws IllegalArgumentException if the input would not be a valid line */
-       public static final void validLine(int line) {
-               if (line < 0) {
-                       throw new IllegalArgumentException("negative line: " + line);
-               } else if (line > ISourceLocation.MAX_LINE) {
-                       throw new IllegalArgumentException("line too large: " + line);
-               }
-       }
-
-       /** @throws IllegalArgumentException if the input would not be a valid column */
-       public static final void validColumn(int column) {
-               if (column < 0) {
-                       throw new IllegalArgumentException("negative column: " + column);
-               } else if (column > ISourceLocation.MAX_COLUMN) {
-                       throw new IllegalArgumentException("column too large: " + column);
-               }
-       }
-
-       /**
-        * Same as SourceLocation(file, line, line, 0), except that column is not rendered during toString()
-        */
-       public SourceLocation(File file, int line) {
-               this(file, line, line, NO_COLUMN);
-       }
-
-       /** same as SourceLocation(file, line, endLine, ISourceLocation.NO_COLUMN) */
-       public SourceLocation(File file, int line, int endLine) {
-               this(file, line, endLine, ISourceLocation.NO_COLUMN);
-       }
-
-       /**
-        * @param file File of the source; if null, use ISourceLocation.NO_FILE, not null
-        * @param line int starting line of the location - positive number
-        * @param endLine int ending line of the location - <= starting line
-        * @param column int character position of starting location - positive number
-        */
-       public SourceLocation(File file, int line, int endLine, int column) {
-               this(file, line, endLine, column, (String) null);
-       }
-
-       public SourceLocation(File file, int line, int endLine, int column, String context) {
-               if (column == NO_COLUMN) {
-                       column = 0;
-                       noColumn = true;
-               }
-               if (null == file) {
-                       file = ISourceLocation.NO_FILE;
-               }
-               validLine(line);
-               validLine(endLine);
-               LangUtil.throwIaxIfFalse(line <= endLine, line + " > " + endLine);
-               LangUtil.throwIaxIfFalse(column >= 0, "negative column: " + column);
-               this.sourceFile = file;
-               this.startLine = line;
-               this.column = column;
-               this.endLine = endLine;
-               this.context = context;
-       }
-
-       public SourceLocation(File file, int line, int endLine, int column, String context, String sourceFileName) {
-               this(file, line, endLine, column, context);
-               this.sourceFileName = sourceFileName;
-       }
-
-       public File getSourceFile() {
-               return sourceFile;
-       }
-
-       public int getLine() {
-               return startLine;
-       }
-
-       /**
-        * @return int actual column or 0 if not available per constructor treatment of ISourceLocation.NO_COLUMN
-        */
-       public int getColumn() {
-               return column;
-       }
-
-       public int getEndLine() {
-               return endLine;
-       }
-
-       /** @return null String or application-specific context */
-       public String getContext() {
-               return context;
-       }
-
-       /** @return String {context\n}{file:}line{:column} */
-       public String toString() {
-               StringBuffer sb = new StringBuffer();
-               if (null != context) {
-                       sb.append(context);
-                       sb.append(LangUtil.EOL);
-               }
-               if (sourceFile != ISourceLocation.NO_FILE) {
-                       sb.append(sourceFile.getPath());
-               }
-               if (startLine > 0) {
-                       sb.append(":");
-                       sb.append(startLine); // "" + startLine + "-" + endLine);
-               }
-               if (!noColumn) {
-                       sb.append(":" + column);
-               }
-               if (offset >= 0) {
-                       sb.append("::" + offset);
-               }
-               return sb.toString();
-       }
-
-       // XXX Ctors for this type should know about an offset, rather than
-       // it being set through these methods - but there are just too many
-       // ctors at the moment! It needs sorting out.
-       public int getOffset() {
-               return offset;
-       }
-
-       public void setOffset(int i) {
-               cachedHashcode = -1;
-               offset = i;
-       }
-
-       public String getSourceFileName() {
-               return sourceFileName;
-       }
-
-       public boolean equals(Object obj) {
-               if (!(obj instanceof SourceLocation)) {
-                       return false;
-               }
-               SourceLocation o = (SourceLocation) obj;
-               return startLine == o.startLine && column == o.column && endLine == o.endLine && offset == o.offset
-                               && (sourceFile == null ? o.sourceFile == null : sourceFile.equals(o.sourceFile))
-                               && (context == null ? o.context == null : context.equals(o.context)) && noColumn == o.noColumn
-                               && (sourceFileName == null ? o.sourceFileName == null : sourceFileName.equals(o.sourceFileName));
-       }
-
-       public int hashCode() {
-               if (cachedHashcode == -1) {
-                       cachedHashcode = (sourceFile == null ? 0 : sourceFile.hashCode());
-                       cachedHashcode = cachedHashcode * 37 + startLine;
-                       cachedHashcode = cachedHashcode * 37 + column;
-                       cachedHashcode = cachedHashcode * 37 + endLine;
-                       cachedHashcode = cachedHashcode * 37 + offset;
-                       cachedHashcode = cachedHashcode * 37 + (context == null ? 0 : context.hashCode());
-                       cachedHashcode = cachedHashcode * 37 + (noColumn ? 0 : 1);
-                       cachedHashcode = cachedHashcode * 37 + (sourceFileName == null ? 0 : sourceFileName.hashCode());
-               }
-               return cachedHashcode;
-       }
-
-}
diff --git a/bridge/src/org/aspectj/bridge/Version.java b/bridge/src/org/aspectj/bridge/Version.java
deleted file mode 100644 (file)
index 835127c..0000000
+++ /dev/null
@@ -1,89 +0,0 @@
-/* ********************************************************************
- * Copyright (c) 1998-2001 Xerox Corporation, 
- *               2002 Palo Alto Research Center, Incorporated (PARC).
- * All rights reserved. 
- * This program and the accompanying materials are made available 
- * under the terms of the Eclipse Public License v1.0 
- * which accompanies this distribution and is available at
- * http://www.eclipse.org/legal/epl-v10.html
- * 
- * Contributors:
- *     Xerox/PARC     initial implementation
- * *******************************************************************/
-
-package org.aspectj.bridge;
-
-import java.text.ParsePosition;
-import java.text.SimpleDateFormat;
-import java.util.Date;
-
-/** release-specific version information */
-public class Version {
-    
-    // generated from build/lib/BridgeVersion.java
-
-    /** default version value for development version */
-    public static final String DEVELOPMENT = "DEVELOPMENT";
-    // VersionUptodate.java depends on this value
-
-    /** default time value for development version */
-    public static final long NOTIME = 0L;
-    
-    /** set by build script */
-    public static final String text = "DEVELOPMENT";
-    // VersionUptodate.java scans for "static final String text = "
-    
-    /** 
-      * Time text set by build script using SIMPLE_DATE_FORMAT.
-      * (if DEVELOPMENT version, invalid)
-      */
-    public static final String time_text = "Friday Nov 18, 2016 at 16:34:52 GMT";
-
-    /** 
-      * time in seconds-since-... format, used by programmatic clients.
-      * (if DEVELOPMENT version, NOTIME)
-      */
-    private static long time = -1; // -1 == uninitialized
-    
-       /** format used by build script to set time_text */
-    public static final String SIMPLE_DATE_FORMAT = "EEEE MMM d, yyyy 'at' HH:mm:ss z";
-    
-    public static long getTime() {
-       if (time==-1) {
-               long foundTime = NOTIME;
-           // if not DEVELOPMENT version, read time text using format used to set time 
-            try {
-                SimpleDateFormat format = new SimpleDateFormat(SIMPLE_DATE_FORMAT);
-                ParsePosition pos = new ParsePosition(0);
-                Date date = format.parse(time_text, pos);
-                if (date!=null) foundTime = date.getTime();
-            } catch (Throwable t) {            
-            }
-            time = foundTime;
-       }
-       return time;
-    }
-
-    /**
-     * Test whether the version is as specified by any first argument.
-     * Emit text to System.err on failure
-     * @param args String[] with first argument equal to Version.text
-     * @see Version#text
-     */
-    public static void main(String[] args) {
-        if ((null != args) && (0 < args.length)) {
-            if (!Version.text.equals(args[0])) {
-                System.err.println("version expected: \"" 
-                                + args[0] 
-                                + "\" actual=\"" 
-                                + Version.text 
-                                + "\"");
-            }
-        }
-    }
-}
-    
-
-
-
-
diff --git a/bridge/src/org/aspectj/bridge/WeaveMessage.java b/bridge/src/org/aspectj/bridge/WeaveMessage.java
deleted file mode 100644 (file)
index 2c697a8..0000000
+++ /dev/null
@@ -1,117 +0,0 @@
-/* *******************************************************************
- * Copyright (c) 2004 IBM Corporation
- * All rights reserved. 
- * This program and the accompanying materials are made available 
- * under the terms of the Eclipse Public License v1.0 
- * which accompanies this distribution and is available at 
- * http://www.eclipse.org/legal/epl-v10.html 
- *  
- * Contributors: 
- *    Andy Clement IBM     initial implementation 30-May-2004
- * ******************************************************************/
-
-package org.aspectj.bridge;
-
-public class WeaveMessage extends Message {
-
-       // Kinds of weaving message we can produce
-
-       public static WeaveMessageKind WEAVEMESSAGE_DECLAREPARENTSIMPLEMENTS = new WeaveMessageKind(1,
-                       "Extending interface set for type '%1' (%2) to include '%3' (%4)");
-
-       public static WeaveMessageKind WEAVEMESSAGE_ITD = new WeaveMessageKind(2, "Type '%1' (%2) has intertyped %3 from '%4' (%5)");
-
-       // %7 is information like "[with runtime test]"
-       public static WeaveMessageKind WEAVEMESSAGE_ADVISES = new WeaveMessageKind(3,
-                       "Join point '%1' in Type '%2' (%3) advised by %4 advice from '%5' (%6)%7");
-
-       public static WeaveMessageKind WEAVEMESSAGE_DECLAREPARENTSEXTENDS = new WeaveMessageKind(4,
-                       "Setting superclass of type '%1' (%2) to '%3' (%4)");
-
-       public static WeaveMessageKind WEAVEMESSAGE_SOFTENS = new WeaveMessageKind(5,
-                       "Softening exceptions in type '%1' (%2) as defined by aspect '%3' (%4)");
-
-       public static WeaveMessageKind WEAVEMESSAGE_ANNOTATES = new WeaveMessageKind(6,
-                       "'%1' (%2) is annotated with %3 %4 annotation from '%5' (%6)");
-
-       public static WeaveMessageKind WEAVEMESSAGE_MIXIN = new WeaveMessageKind(7, "Mixing interface '%1' (%2) into type '%3' (%4)");
-
-       public static WeaveMessageKind WEAVEMESSAGE_REMOVES_ANNOTATION = new WeaveMessageKind(6,
-                       "'%1' (%2) has had %3 %4 annotation removed by '%5' (%6)");
-
-       private String affectedtypename;
-       private String aspectname;
-
-       // private ctor - use the static factory method
-       private WeaveMessage(String message, String affectedtypename, String aspectname) {
-               super(message, IMessage.WEAVEINFO, null, null);
-               this.affectedtypename = affectedtypename;
-               this.aspectname = aspectname;
-       }
-
-       /**
-        * Static helper method for constructing weaving messages.
-        * 
-        * @param kind what kind of message (e.g. declare parents)
-        * @param inserts inserts for the message (inserts are marked %n in the message)
-        * @return new weaving message
-        */
-       public static WeaveMessage constructWeavingMessage(WeaveMessageKind kind, String[] inserts) {
-               StringBuffer str = new StringBuffer(kind.getMessage());
-               int pos = -1;
-               while ((pos = new String(str).indexOf("%")) != -1) {
-                       int n = Character.getNumericValue(str.charAt(pos + 1));
-                       str.replace(pos, pos + 2, inserts[n - 1]);
-               }
-               return new WeaveMessage(str.toString(), null, null);
-       }
-
-       /**
-        * Static helper method for constructing weaving messages.
-        * 
-        * @param kind what kind of message (e.g. declare parents)
-        * @param inserts inserts for the message (inserts are marked %n in the message)
-        * @param affectedtypename the type which is being advised/declaredUpon
-        * @param aspectname the aspect that defined the advice or declares
-        * @return new weaving message
-        */
-       public static WeaveMessage constructWeavingMessage(WeaveMessageKind kind, String[] inserts, String affectedtypename,
-                       String aspectname) {
-               StringBuffer str = new StringBuffer(kind.getMessage());
-               int pos = -1;
-               while ((pos = new String(str).indexOf("%")) != -1) {
-                       int n = Character.getNumericValue(str.charAt(pos + 1));
-                       str.replace(pos, pos + 2, inserts[n - 1]);
-               }
-               return new WeaveMessage(str.toString(), affectedtypename, aspectname);
-       }
-
-       /**
-        * @return Returns the aspectname.
-        */
-       public String getAspectname() {
-               return aspectname;
-       }
-
-       /**
-        * @return Returns the affectedtypename.
-        */
-       public String getAffectedtypename() {
-               return affectedtypename;
-       }
-
-       public static class WeaveMessageKind {
-
-               // private int id;
-               private String message;
-
-               public WeaveMessageKind(int id, String message) {
-                       // this.id = id;
-                       this.message = message;
-               }
-
-               public String getMessage() {
-                       return message;
-               }
-       }
-}
diff --git a/bridge/src/org/aspectj/bridge/context/CompilationAndWeavingContext.java b/bridge/src/org/aspectj/bridge/context/CompilationAndWeavingContext.java
deleted file mode 100644 (file)
index 28a414a..0000000
+++ /dev/null
@@ -1,260 +0,0 @@
-/* *******************************************************************
- * Copyright (c) 2005-2012 Contributors.
- * All rights reserved. 
- * This program and the accompanying materials are made available 
- * under the terms of the Eclipse Public License v1.0 
- * which accompanies this distribution and is available at 
- * http://eclipse.org/legal/epl-v10.html 
- *  
- * Contributors: 
- *   Adrian Colyer                     Initial implementation
- *   Andy Clement                      various fixes
- *   Trask Stanalker           #373195
- * ******************************************************************/
-package org.aspectj.bridge.context;
-
-import java.lang.ref.WeakReference;
-import java.util.HashMap;
-import java.util.Map;
-import java.util.Stack;
-
-/**
- * This class is responsible for tracking progress through the various phases of compilation and weaving. 
- * When an exception occurs (or a message is issued, if desired), you can ask this class for a 
- * "stack trace" that gives information about what the compiler was doing at the time. 
- * The trace will say something like: 
- * "when matching pointcut xyz when matching shadow sss when weaving type ABC when weaving shadow mungers"
- */
-public class CompilationAndWeavingContext {
-
-       private static int nextTokenId = 1;
-
-       // unique constants for the different phases that can be registered
-
-       // "FRONT END"
-       public static final int BATCH_BUILD = 0;
-       public static final int INCREMENTAL_BUILD = 1;
-       public static final int PROCESSING_COMPILATION_UNIT = 2;
-       public static final int RESOLVING_COMPILATION_UNIT = 3;
-       public static final int ANALYSING_COMPILATION_UNIT = 4;
-       public static final int GENERATING_UNWOVEN_CODE_FOR_COMPILATION_UNIT = 5;
-       public static final int COMPLETING_TYPE_BINDINGS = 6;
-       public static final int PROCESSING_DECLARE_PARENTS = 7;
-       public static final int CHECK_AND_SET_IMPORTS = 8;
-       public static final int CONNECTING_TYPE_HIERARCHY = 9;
-       public static final int BUILDING_FIELDS_AND_METHODS = 10;
-       public static final int COLLECTING_ITDS_AND_DECLARES = 11;
-       public static final int PROCESSING_DECLARE_ANNOTATIONS = 12;
-       public static final int WEAVING_INTERTYPE_DECLARATIONS = 13;
-       public static final int RESOLVING_POINTCUT_DECLARATIONS = 14;
-       public static final int ADDING_DECLARE_WARNINGS_AND_ERRORS = 15;
-       public static final int VALIDATING_AT_ASPECTJ_ANNOTATIONS = 16;
-       public static final int ACCESS_FOR_INLINE = 17;
-       public static final int ADDING_AT_ASPECTJ_ANNOTATIONS = 18;
-       public static final int FIXING_SUPER_CALLS_IN_ITDS = 19;
-       public static final int FIXING_SUPER_CALLS = 20;
-       public static final int OPTIMIZING_THIS_JOIN_POINT_CALLS = 21;
-
-       // "BACK END"
-
-       public static final int WEAVING = 22;
-       public static final int PROCESSING_REWEAVABLE_STATE = 23;
-       public static final int PROCESSING_TYPE_MUNGERS = 24;
-       public static final int WEAVING_ASPECTS = 25;
-       public static final int WEAVING_CLASSES = 26;
-       public static final int WEAVING_TYPE = 27;
-       public static final int MATCHING_SHADOW = 28;
-       public static final int IMPLEMENTING_ON_SHADOW = 29;
-       public static final int MATCHING_POINTCUT = 30;
-       public static final int MUNGING_WITH = 31;
-       public static final int PROCESSING_ATASPECTJTYPE_MUNGERS_ONLY = 32;
-
-       // phase names
-       public static final String[] PHASE_NAMES = new String[] { "batch building", "incrementally building",
-                       "processing compilation unit", "resolving types defined in compilation unit",
-                       "analysing types defined in compilation unit", "generating unwoven code for type defined in compilation unit",
-                       "completing type bindings", "processing declare parents", "checking and setting imports", "connecting type hierarchy",
-                       "building fields and methods", "collecting itds and declares", "processing declare annotations",
-                       "weaving intertype declarations", "resolving pointcut declarations", "adding declare warning and errors",
-                       "validating @AspectJ annotations", "creating accessors for inlining", "adding @AspectJ annotations",
-                       "fixing super calls in ITDs in interface context", "fixing super calls in ITDs",
-                       "optimizing thisJoinPoint calls",
-
-                       // BACK END
-
-                       "weaving", "processing reweavable state", "processing type mungers", "weaving aspects", "weaving classes",
-                       "weaving type", "matching shadow", "implementing on shadow", "matching pointcut", "type munging with",
-                       "type munging for @AspectJ aspectOf" };
-
-       // context stacks, one per thread
-       private static ThreadLocal<Stack<ContextStackEntry>> contextMap = new ThreadLocal<Stack<ContextStackEntry>>();
-
-       // single thread mode stack
-       private static Stack<ContextStackEntry> contextStack = new Stack<ContextStackEntry>();
-
-       // formatters, by phase id
-       private static Map<Integer, ContextFormatter> formatterMap = new HashMap<Integer, ContextFormatter>();
-
-       private static ContextFormatter defaultFormatter = new DefaultFormatter();
-
-       private static boolean multiThreaded = true;
-
-       /**
-        * this is a static service
-        */
-       private CompilationAndWeavingContext() {
-       }
-
-       public static void reset() {
-               if (!multiThreaded) {
-                       contextMap.remove();
-                       contextStack.clear();
-                       formatterMap.clear();
-                       nextTokenId = 1;
-               } else {
-                       contextMap.remove();
-                       // TODO what about formatterMap?
-                       // TODO what about nextTokenId?
-               }
-       }
-
-       public static void setMultiThreaded(boolean mt) {
-               multiThreaded = mt;
-       }
-
-       public static void registerFormatter(int phaseId, ContextFormatter aFormatter) {
-               formatterMap.put(new Integer(phaseId), aFormatter);
-       }
-
-       /**
-        * Returns a string description of what the compiler/weaver is currently doing
-        */
-       public static String getCurrentContext() {
-               Stack<ContextStackEntry> contextStack = getContextStack();
-               Stack<String> explanationStack = new Stack<String>();
-               for (ContextStackEntry entry : contextStack) {
-                       Object data = entry.getData();
-                       if (data != null) {
-                               explanationStack.push(getFormatter(entry).formatEntry(entry.phaseId, data));
-                       }
-               }
-               StringBuffer sb = new StringBuffer();
-               while (!explanationStack.isEmpty()) {
-                       sb.append("when ");
-                       sb.append(explanationStack.pop().toString());
-                       sb.append("\n");
-               }
-               return sb.toString();
-       }
-
-       public static ContextToken enteringPhase(int phaseId, Object data) {
-               Stack<ContextStackEntry> contextStack = getContextStack();
-               ContextTokenImpl nextToken = nextToken();
-               contextStack.push(new ContextStackEntry(nextToken, phaseId, new WeakReference<Object>(data)));
-               return nextToken;
-       }
-
-       /**
-        * Exit a phase, all stack entries from the one with the given token down will be removed.
-        */
-       public static void leavingPhase(ContextToken aToken) {
-               Stack<ContextStackEntry> contextStack = getContextStack();
-               while (!contextStack.isEmpty()) {
-                       ContextStackEntry entry = contextStack.pop();
-                       if (entry.contextToken == aToken) {
-                               break;
-                       }
-               }
-       }
-
-       /**
-        * Forget about the context for the current thread
-        */
-       public static void resetForThread() {
-               if (!multiThreaded) {
-                       return;
-               }
-               contextMap.remove();
-       }
-
-       private static Stack<ContextStackEntry> getContextStack() {
-               if (!multiThreaded) {
-                       return contextStack;
-               } else {
-                       Stack<ContextStackEntry> contextStack = contextMap.get();
-                       if (contextStack == null) {
-                               contextStack = new Stack<ContextStackEntry>();
-                               contextMap.set(contextStack);
-                       }
-                       return contextStack;
-               }
-       }
-
-       private static ContextTokenImpl nextToken() {
-               return new ContextTokenImpl(nextTokenId++);
-       }
-
-       private static ContextFormatter getFormatter(ContextStackEntry entry) {
-               Integer key = new Integer(entry.phaseId);
-               if (formatterMap.containsKey(key)) {
-                       return formatterMap.get(key);
-               } else {
-                       return defaultFormatter;
-               }
-       }
-
-       private static class ContextTokenImpl implements ContextToken {
-               public int tokenId;
-
-               public ContextTokenImpl(int id) {
-                       this.tokenId = id;
-               }
-       }
-
-       // dumb data structure
-       private static class ContextStackEntry {
-               public ContextTokenImpl contextToken;
-               public int phaseId;
-               private WeakReference<Object> dataRef;
-
-               public ContextStackEntry(ContextTokenImpl ct, int phase, WeakReference<Object> data) {
-                       this.contextToken = ct;
-                       this.phaseId = phase;
-                       this.dataRef = data;
-               }
-
-               public Object getData() {
-                       return dataRef.get();
-               }
-
-               public String toString() {
-                       Object data = getData();
-                       if (data == null) {
-                               return "referenced context entry has gone out of scope";
-                       } else {
-                               return CompilationAndWeavingContext.getFormatter(this).formatEntry(phaseId, data);
-                       }
-               }
-       }
-
-       private static class DefaultFormatter implements ContextFormatter {
-
-               public String formatEntry(int phaseId, Object data) {
-                       StringBuffer sb = new StringBuffer();
-                       sb.append(PHASE_NAMES[phaseId]);
-                       sb.append(" ");
-                       if (data instanceof char[]) {
-                               sb.append(new String((char[]) data));
-                       } else {
-                               try {
-                                       sb.append(data.toString());
-                               } catch (RuntimeException ex) {
-                                       // don't lose vital info because of bad toString
-                                       sb.append("** broken toString in data object **");
-                               }
-                       }
-                       return sb.toString();
-               }
-
-       }
-}
diff --git a/bridge/src/org/aspectj/bridge/context/ContextFormatter.java b/bridge/src/org/aspectj/bridge/context/ContextFormatter.java
deleted file mode 100644 (file)
index 9f1b591..0000000
+++ /dev/null
@@ -1,21 +0,0 @@
-/* *******************************************************************
- * Copyright (c) 2005 Contributors.
- * All rights reserved. 
- * This program and the accompanying materials are made available 
- * under the terms of the Eclipse Public License v1.0 
- * which accompanies this distribution and is available at 
- * http://eclipse.org/legal/epl-v10.html 
- *  
- * Contributors: 
- *   Adrian Colyer                     Initial implementation
- * ******************************************************************/
-package org.aspectj.bridge.context;
-
-/**
- * @author colyer
- * Implementors of this interface know how to turn the "Object" data and phase id 
- * associated with a context stack entry into a meaningful string.
- */
-public interface ContextFormatter {
-       String formatEntry(int phaseId, Object data);
-}
diff --git a/bridge/src/org/aspectj/bridge/context/ContextToken.java b/bridge/src/org/aspectj/bridge/context/ContextToken.java
deleted file mode 100644 (file)
index 2415fa7..0000000
+++ /dev/null
@@ -1,20 +0,0 @@
-/* *******************************************************************
- * Copyright (c) 2005 Contributors.
- * All rights reserved. 
- * This program and the accompanying materials are made available 
- * under the terms of the Eclipse Public License v1.0 
- * which accompanies this distribution and is available at 
- * http://eclipse.org/legal/epl-v10.html 
- *  
- * Contributors: 
- *   Adrian Colyer                     Initial implementation
- * ******************************************************************/
-package org.aspectj.bridge.context;
-
-/**
- * When an entry is added to the CompilationAndWeavingContext stack,
- * a ContextToken is returned. 
- * When leaving a compilation or weaving phase, this token must be supplied.
- * The token details are opaque to clients
- */
-public interface ContextToken {}
diff --git a/bridge/src/org/aspectj/bridge/context/PinpointingMessageHandler.java b/bridge/src/org/aspectj/bridge/context/PinpointingMessageHandler.java
deleted file mode 100644 (file)
index c54ff67..0000000
+++ /dev/null
@@ -1,115 +0,0 @@
-/* *******************************************************************
- * Copyright (c) 2005 Contributors.
- * All rights reserved. 
- * This program and the accompanying materials are made available 
- * under the terms of the Eclipse Public License v1.0 
- * which accompanies this distribution and is available at 
- * http://eclipse.org/legal/epl-v10.html 
- *  
- * Contributors: 
- *   Adrian Colyer                     Initial implementation
- * ******************************************************************/
-package org.aspectj.bridge.context;
-
-import java.io.PrintWriter;
-import java.io.StringWriter;
-import java.util.List;
-
-import org.aspectj.bridge.AbortException;
-import org.aspectj.bridge.IMessage;
-import org.aspectj.bridge.IMessageHandler;
-import org.aspectj.bridge.ISourceLocation;
-import org.aspectj.bridge.IMessage.Kind;
-
-/**
- * @author colyer
- * Facade for an IMessageHandler
- * Extends message with details of exactly what the compiler / weaver was doing at the 
- * time. Use the -Xdev:Pinpoint option to turn this facility on.
- */
-public class PinpointingMessageHandler implements IMessageHandler {
-
-       private IMessageHandler delegate;
-       
-       public PinpointingMessageHandler(IMessageHandler delegate) {
-               this.delegate = delegate;
-       }
-
-       /* (non-Javadoc)
-        * @see org.aspectj.bridge.IMessageHandler#handleMessage(org.aspectj.bridge.IMessage)
-        */
-       public boolean handleMessage(IMessage message) throws AbortException {
-               if (!isIgnoring(message.getKind())) {
-                       MessageIssued ex = new MessageIssued();
-                       ex.fillInStackTrace();
-                       StringWriter sw = new StringWriter();
-                       ex.printStackTrace(new PrintWriter(sw));
-                       StringBuffer sb = new StringBuffer();
-                       sb.append(CompilationAndWeavingContext.getCurrentContext());
-                       sb.append(sw.toString());
-                       IMessage pinpointedMessage = new PinpointedMessage(message,sb.toString());
-                       return delegate.handleMessage(pinpointedMessage);
-               } else {
-                       return delegate.handleMessage(message);
-               }
-       }
-
-       /* (non-Javadoc)
-        * @see org.aspectj.bridge.IMessageHandler#isIgnoring(org.aspectj.bridge.IMessage.Kind)
-        */
-       public boolean isIgnoring(Kind kind) {
-               return delegate.isIgnoring(kind);
-       }
-
-       /* (non-Javadoc)
-        * @see org.aspectj.bridge.IMessageHandler#dontIgnore(org.aspectj.bridge.IMessage.Kind)
-        */
-       public void dontIgnore(Kind kind) {
-               delegate.dontIgnore(kind);
-       }
-
-
-       /* (non-Javadoc)
-        * @see org.aspectj.bridge.IMessageHandler#ignore(org.aspectj.bridge.IMessage.Kind)
-        */
-       public void ignore(Kind kind) {
-               delegate.ignore(kind);
-       }
-       
-       private static class PinpointedMessage implements IMessage {
-
-               private IMessage delegate;
-               private String message;
-               
-               public PinpointedMessage(IMessage delegate, String pinpoint) {
-                       this.delegate = delegate;
-                       this.message = delegate.getMessage() + "\n" + pinpoint;
-               }
-               
-               public String getMessage() { return this.message; }
-               public Kind getKind() { return delegate.getKind();}
-               public boolean isError() { return delegate.isError(); }
-               public boolean isWarning() { return delegate.isWarning();}
-               public boolean isDebug() { return delegate.isDebug();}
-               public boolean isInfo() { return delegate.isInfo();}
-               public boolean isAbort() { return delegate.isAbort();}
-               public boolean isTaskTag() { return delegate.isTaskTag();}
-               public boolean isFailed() { return delegate.isFailed();}
-               public boolean getDeclared() { return delegate.getDeclared(); }
-               public int getID() { return delegate.getID();}
-               public int getSourceStart() { return delegate.getSourceStart();}
-               public int getSourceEnd() { return delegate.getSourceEnd();}
-               public Throwable getThrown() { return delegate.getThrown();}
-               public ISourceLocation getSourceLocation() { return delegate.getSourceLocation();}
-               public String getDetails() { return delegate.getDetails();}
-               public List<ISourceLocation> getExtraSourceLocations() { return delegate.getExtraSourceLocations();}
-       }
-
-       private static class MessageIssued extends RuntimeException {
-               private static final long serialVersionUID = 1L;
-
-               public String getMessage() {
-                       return "message issued...";
-               }
-       }
-}
diff --git a/bridge/src/test/java/org/aspectj/bridge/CountingMessageHandlerTest.java b/bridge/src/test/java/org/aspectj/bridge/CountingMessageHandlerTest.java
new file mode 100644 (file)
index 0000000..dc357a8
--- /dev/null
@@ -0,0 +1,82 @@
+/* *******************************************************************
+ * Copyright (c) 1999-2001 Xerox Corporation, 
+ *               2002 Palo Alto Research Center, Incorporated (PARC).
+ * All rights reserved. 
+ * This program and the accompanying materials are made available 
+ * under the terms of the Eclipse Public License v1.0 
+ * which accompanies this distribution and is available at 
+ * http://www.eclipse.org/legal/epl-v10.html 
+ *  
+ * Contributors: 
+ *     Xerox/PARC     initial implementation 
+ * ******************************************************************/
+
+package org.aspectj.bridge;
+
+
+import junit.framework.TestCase;
+import junit.textui.TestRunner;
+
+/**
+ * 
+ */
+public class CountingMessageHandlerTest extends TestCase {
+
+   private static final String ME 
+        = "org.aspectj.bridge.CountingMessageHandlerTest"; // XXX
+
+    /** @param args ignored */
+    public static void main(String[] args) {
+        TestRunner.main(new String[] {ME});
+    }
+
+       /**
+        * Constructor for MessageTest.
+        * @param name
+        */
+       public CountingMessageHandlerTest(String name) {
+               super(name);
+       }
+
+    public void testSimpleWrapping() {
+        MessageHandler m = new MessageHandler();
+        CountingMessageHandler me = new CountingMessageHandler(m);
+        checkCountingMessageHandler(me);
+    }
+
+    public void testCounterWrapping() {
+        MessageHandler m = new MessageHandler();
+        CountingMessageHandler first = new CountingMessageHandler(m);
+        CountingMessageHandler me = new CountingMessageHandler(first);
+        checkCountingMessageHandler(me);
+    }
+
+    void checkCountingMessageHandler(CountingMessageHandler me) {
+        MessageUtil.warn(me, "warn 1");
+        assertTrue(!me.hasErrors());
+        assertEquals(0 , me.numMessages(IMessage.ERROR, false));
+        assertEquals(1 , me.numMessages(IMessage.WARNING, false));
+        assertEquals(0 , me.numMessages(IMessage.INFO, false));
+        assertEquals(0 , me.numMessages(IMessage.ERROR, true));
+        assertEquals(1 , me.numMessages(IMessage.WARNING, true));
+        assertEquals(1 , me.numMessages(IMessage.INFO, true));
+        
+        MessageUtil.info(me, "info 1");
+        assertTrue(!me.hasErrors());
+        assertEquals(0 , me.numMessages(IMessage.ERROR, false));
+        assertEquals(1 , me.numMessages(IMessage.WARNING, false));
+        assertEquals(1 , me.numMessages(IMessage.INFO, false));
+        assertEquals(0 , me.numMessages(IMessage.ERROR, true));
+        assertEquals(1 , me.numMessages(IMessage.WARNING, true));
+        assertEquals(2 , me.numMessages(IMessage.INFO, true));
+
+        MessageUtil.error(me, "error 1");
+        assertTrue(me.hasErrors());
+        assertEquals(1 , me.numMessages(IMessage.ERROR, false));
+        assertEquals(1 , me.numMessages(IMessage.WARNING, false));
+        assertEquals(1 , me.numMessages(IMessage.INFO, false));
+        assertEquals(1 , me.numMessages(IMessage.ERROR, true));
+        assertEquals(2 , me.numMessages(IMessage.WARNING, true));
+        assertEquals(3 , me.numMessages(IMessage.INFO, true));
+    }    
+}
diff --git a/bridge/src/test/java/org/aspectj/bridge/MessageTest.java b/bridge/src/test/java/org/aspectj/bridge/MessageTest.java
new file mode 100644 (file)
index 0000000..be30c48
--- /dev/null
@@ -0,0 +1,321 @@
+/* *******************************************************************
+ * Copyright (c) 1999-2001 Xerox Corporation, 
+ *               2002 Palo Alto Research Center, Incorporated (PARC).
+ * All rights reserved. 
+ * This program and the accompanying materials are made available 
+ * under the terms of the Eclipse Public License v1.0 
+ * which accompanies this distribution and is available at 
+ * http://www.eclipse.org/legal/epl-v10.html 
+ *  
+ * Contributors: 
+ *     Xerox/PARC     initial implementation 
+ * ******************************************************************/
+
+package org.aspectj.bridge;
+
+import java.io.File;
+import java.util.Arrays;
+import java.util.BitSet;
+import java.util.Comparator;
+import java.util.Iterator;
+import java.util.List;
+import java.util.ListIterator;
+
+import junit.framework.AssertionFailedError;
+import junit.framework.TestCase;
+import junit.textui.TestRunner;
+
+/**
+ * 
+ */
+public class MessageTest extends TestCase {
+
+   private static final String ME 
+        = "org.aspectj.bridge.MessageTest"; // XXX
+
+    /** @param args ignored */
+    public static void main(String[] args) {
+        TestRunner.main(new String[] {ME});
+    }
+
+       /**
+        * Constructor for MessageTest.
+        * @param name
+        */
+       public MessageTest(String name) {
+               super(name);
+       }
+    
+    <T> void checkListOrder(List<T> list, Comparator<T> c) { // XXX util
+        assertNotNull(list);
+        assertNotNull(c);
+        ListIterator<T> it = list.listIterator();
+        T last = null;
+        T current = null;
+        while (it.hasNext()) {
+            current = it.next();
+            if (null != last) {
+                int i = c.compare(last, current);
+                if (i > 0) {
+                    assertTrue( last + " > " + current + " (" + i + ")", false);
+                }                
+            } 
+            last = current;
+        }
+    }
+        
+    public void testKindOrder() {
+        // first briefly validate the checker
+        checkListOrder(Arrays.asList(new String[] { "a", "b", "C" }),
+            String.CASE_INSENSITIVE_ORDER);
+        checkListOrder(IMessage.KINDS, IMessage.Kind.COMPARATOR);
+    }
+    
+    public void testKind_isSameOrLessThan() {
+        IMessage.Kind last;
+        IMessage.Kind next = null;
+        for (Iterator<IMessage.Kind> iter = IMessage.KINDS.iterator(); iter.hasNext();) {
+            last = next;
+            next = iter.next();
+            if (null == last) {
+                continue;
+            }
+            String label = "last: " + last + " next: " + next;
+            assertTrue(label, !next.isSameOrLessThan(null));
+            assertTrue(label, !next.isSameOrLessThan(last));
+            assertTrue(label, last.isSameOrLessThan(next));
+            assertTrue(label, next.isSameOrLessThan(next));
+        }    
+    }
+    
+    public void testMessageHandler() {
+        boolean handleMessageResult = true;
+        checkEmptyMessageHolder(new MessageHandler(handleMessageResult), handleMessageResult);
+        handleMessageResult = false;
+        checkEmptyMessageHolder(new MessageHandler(handleMessageResult), handleMessageResult);
+    }
+    
+    public void checkEmptyMessageHolder(
+        IMessageHolder h, 
+        final boolean handleMessageResult) {
+       //  { INFO, DEBUG, WARNING, ERROR, FAIL, ABORT }));  
+        assertNotNull(h);
+        assertTrue(!h.hasAnyMessage(null, true));
+        assertTrue(!h.hasAnyMessage(null, false));
+        assertTrue(!h.hasAnyMessage(IMessage.INFO, true));
+        assertTrue(!h.hasAnyMessage(IMessage.INFO, false));
+        
+        assertTrue(handleMessageResult == h.handleMessage(make("error 1", IMessage.ERROR)));
+        assertTrue(handleMessageResult == h.handleMessage(make("error 2", IMessage.ERROR)));
+        assertTrue(handleMessageResult == h.handleMessage(make("fail 1", IMessage.FAIL)));
+        assertTrue(handleMessageResult == h.handleMessage(make("fail 2", IMessage.FAIL)));
+        assertTrue(handleMessageResult == h.handleMessage(make("debug 1", IMessage.DEBUG)));
+        assertTrue(handleMessageResult == h.handleMessage(make("debug 2", IMessage.DEBUG)));
+        
+        assertTrue(h.hasAnyMessage(null, true));
+        assertTrue(h.hasAnyMessage(null, false));
+        assertTrue(h.hasAnyMessage(IMessage.ERROR, true));
+        assertTrue(h.hasAnyMessage(IMessage.ERROR, false));
+        assertTrue(h.hasAnyMessage(IMessage.FAIL, true));
+        assertTrue(h.hasAnyMessage(IMessage.FAIL, false));
+        assertTrue(h.hasAnyMessage(IMessage.DEBUG, true));
+        assertTrue(h.hasAnyMessage(IMessage.DEBUG, false));
+        
+        assertTrue(!h.hasAnyMessage(IMessage.INFO, IMessageHolder.EQUAL));
+        assertTrue(!h.hasAnyMessage(IMessage.WARNING, IMessageHolder.EQUAL));
+        assertTrue(!h.hasAnyMessage(IMessage.ABORT, IMessageHolder.EQUAL));
+        assertTrue(h.hasAnyMessage(IMessage.INFO, IMessageHolder.ORGREATER));
+        assertTrue(h.hasAnyMessage(IMessage.WARNING, IMessageHolder.ORGREATER));
+        assertTrue(!h.hasAnyMessage(IMessage.ABORT, IMessageHolder.ORGREATER));
+        
+        assertTrue(0 == h.numMessages(IMessage.INFO, IMessageHolder.EQUAL));
+        assertTrue(0 == h.numMessages(IMessage.WARNING, IMessageHolder.EQUAL));
+        assertTrue(0 == h.numMessages(IMessage.ABORT, IMessageHolder.EQUAL));
+
+        assertTrue(6 == h.numMessages(null, IMessageHolder.ORGREATER));
+        assertTrue(6 == h.numMessages(null, IMessageHolder.EQUAL));
+        assertTrue(6 == h.numMessages(IMessage.INFO, IMessageHolder.ORGREATER));
+        assertTrue(6 == h.numMessages(IMessage.DEBUG, IMessageHolder.ORGREATER));
+        assertTrue(4 == h.numMessages(IMessage.WARNING, IMessageHolder.ORGREATER));
+        assertTrue(4 == h.numMessages(IMessage.ERROR, IMessageHolder.ORGREATER));
+        assertTrue(2 == h.numMessages(IMessage.FAIL, IMessageHolder.ORGREATER));
+        assertTrue(0 == h.numMessages(IMessage.ABORT, IMessageHolder.ORGREATER));
+        
+    } 
+    
+    public void testMessage() {
+        String input = "input";
+        Throwable thrown = null;
+        ISourceLocation sl = null;
+        Class<?> exClass = null;
+        String descriptor = "Message"; // for make(...)
+        IMessage.Kind kind = IMessage.INFO;
+
+        // -- kind variants
+        roundTrip(input, kind, thrown, sl, descriptor, exClass);
+        kind = IMessage.WARNING;
+        roundTrip(input, kind, thrown, sl, descriptor, exClass);
+        kind = IMessage.ERROR;
+        roundTrip(input, kind, thrown, sl, descriptor, exClass);
+        kind = IMessage.DEBUG;
+        roundTrip(input, kind, thrown, sl, descriptor, exClass);
+        kind = IMessage.FAIL;
+        roundTrip(input, kind, thrown, sl, descriptor, exClass);
+
+        // -- throwable
+        kind = IMessage.FAIL;
+        thrown = new AbortException();
+        input = null;
+        roundTrip(input, kind, thrown, sl, descriptor, exClass);
+
+        // -- source location
+        kind = IMessage.WARNING;
+        thrown = null;
+        input = "type not found";
+        File f = new File("some/file.java"); // XXX unchecked
+        sl = new SourceLocation(f, 0, 0, 0);
+        roundTrip(input, kind, thrown, sl, descriptor, exClass);
+        sl = new SourceLocation(f, 1, 1, 0);
+        roundTrip(input, kind, thrown, sl, descriptor, exClass);
+
+        // -- input error tests - null kind, null input (factory-dependent)
+        kind = null;
+        exClass = IllegalArgumentException.class;
+        roundTrip(input, kind, thrown, sl, descriptor, exClass);
+        input = null;
+        kind = IMessage.INFO;
+        roundTrip(input, kind, thrown, sl, descriptor, exClass);                        
+    }
+    
+    protected IMessage make(String message, IMessage.Kind kind) {
+        return new Message(message, kind, null, null);
+    }
+
+    /** make a Message per descriptor and input */
+    protected IMessage make(String input, IMessage.Kind kind,
+        Throwable thrown, ISourceLocation sourceLocation, 
+        String descriptor) { // XXX ignored for now
+            return new Message(input, kind, thrown, sourceLocation);
+    }
+
+    /**
+     * Simple round-trip on the message
+     */
+    protected void roundTrip(String input, IMessage.Kind kind,
+        Throwable thrown, ISourceLocation sourceLocation, 
+        String descriptor, Class<?> exClass) {
+        try {
+            IMessage m = make(input, kind, thrown, sourceLocation, descriptor);
+            if ((null == input) && (null != thrown)) {
+                input = thrown.getMessage();
+            }
+            roundTripCheck(m, input, kind, thrown, sourceLocation);
+        } catch (AssertionFailedError x) {
+            throw x;
+        } catch (Throwable t) {
+            assertTrue(null != exClass);
+            assertTrue(exClass.isAssignableFrom(t.getClass()));
+        }
+    }
+
+    protected void roundTripCheck(IMessage message, String input, IMessage.Kind kind,
+        Throwable thrown, ISourceLocation sourceLocation) {
+            IMessage m = message;
+            assertTrue("not null", null != m);
+            assertEquals(input, m.getMessage());
+            assertTrue(""+kind, kind == m.getKind());
+            assertTrue(""+thrown, equals(thrown, m.getThrown()));
+            assertTrue(""+sourceLocation, 
+                equals(sourceLocation, m.getSourceLocation()));
+            String err = new KindTest().testKindSet(message, kind);
+            if (null != err) {
+                assertTrue(err, false);
+            }
+    }
+    
+    protected static boolean equals(Object one, Object two) {
+        if (null == one) {
+            return (null == two);
+        } else if (null == two) {
+            return false;
+        } else {
+            return one.equals(two);
+        }
+    }
+}
+
+/** test correlation between message and enclosed kind */
+class KindTest {
+    /** order tracked in checkKindMethods() */
+    static final IMessage.Kind[] KINDS = new IMessage.Kind[] 
+            {  IMessage.ABORT, IMessage.DEBUG, IMessage.ERROR, 
+                IMessage.INFO, IMessage.WARNING, IMessage.FAIL };
+
+    static final List<IMessage.Kind> KINDLIST = Arrays.asList(KINDS);
+
+    /** used to clear instance BitSet */
+    static final BitSet UNSET = new BitSet(KINDS.length);
+
+
+    final BitSet expected = new BitSet(KINDS.length);
+    IMessage.Kind kind = IMessage.INFO;
+    
+    /** @return error if failed */
+    public String testKindSet(IMessage m, IMessage.Kind newKind) {
+        IMessage.Kind oldKind = this.kind;
+        String result = setKind(newKind);
+        if (null == result) {
+            result = checkKindSet(m, newKind);
+        }
+        if (null == result) {
+            result = checkExpectedKind(m);
+        }
+        return (null != result? result : setKind(oldKind));
+    }
+    
+    /** @return error if failed */
+    private String setKind(IMessage.Kind kind) {
+        this.kind = kind;
+        int index = KINDLIST.indexOf(kind);
+        if (-1 == index) {
+            return "unknown kind: " + kind;
+        }
+        expected.and(UNSET);
+        expected.set(index);
+        return null;
+    }
+    
+    /** @return error if failed */
+    String checkExpectedKind(IMessage m) {
+        StringBuffer result = new StringBuffer();
+        for (int i = 0; i < KINDS.length; i++) {
+            if (expected.get(i) != checkKindMethods(m, i)) {
+                String s = "expected " + expected.get(i)
+                    + " for is{Method} for " + KINDS[i];
+                result.append(s + "\n");
+            } 
+               }  
+        return (0 < result.length() ? result.toString() : null); 
+    }
+    
+    String checkKindSet(IMessage m, IMessage.Kind kind) {
+        if (kind != m.getKind()) {
+            return "expected kind " + kind + " got " + m.getKind();
+        }
+        return null;
+    }
+    
+    /** @return true if index matches isFoo() reporting */
+    boolean checkKindMethods(IMessage m, int index) {
+        switch (index) {
+            case (0) : return m.isAbort(); 
+            case (1) : return m.isDebug(); 
+            case (2) : return m.isError(); 
+            case (3) : return m.isInfo(); 
+            case (4) : return m.isWarning(); 
+            case (5) : return m.isFailed(); 
+            default : throw new IllegalArgumentException("index=" + index);
+                                
+        }
+    }
+}
diff --git a/bridge/src/test/java/org/aspectj/bridge/VersionTest.java b/bridge/src/test/java/org/aspectj/bridge/VersionTest.java
new file mode 100644 (file)
index 0000000..cee4c84
--- /dev/null
@@ -0,0 +1,60 @@
+/* *******************************************************************
+ * Copyright (c) 1999-2001 Xerox Corporation, 
+ *               2002 Palo Alto Research Center, Incorporated (PARC).
+ * All rights reserved. 
+ * This program and the accompanying materials are made available 
+ * under the terms of the Eclipse Public License v1.0 
+ * which accompanies this distribution and is available at 
+ * http://www.eclipse.org/legal/epl-v10.html 
+ *  
+ * Contributors: 
+ *     Xerox/PARC     initial implementation 
+ * ******************************************************************/
+
+package org.aspectj.bridge;
+
+import java.text.SimpleDateFormat;
+import java.util.Date;
+import java.util.Locale;
+import java.util.TimeZone;
+
+import org.aspectj.util.LangUtil;
+
+import junit.framework.TestCase;
+import junit.textui.TestRunner;
+
+/**
+ * 
+ */
+public class VersionTest extends TestCase {
+
+       private static final String ME = "org.aspectj.bridge.VersionTest";
+
+       /** @param args ignored */
+       public static void main(String[] args) {
+               TestRunner.main(new String[] { ME });
+       }
+
+       /**
+        * Constructor for MessageTest.
+        * 
+        * @param name
+        */
+       public VersionTest(String name) {
+               super(name);
+       }
+
+       public void testVersion() {
+               if (LangUtil.is11VMOrGreater()) {
+                       return;
+               }
+               if (Version.time_text.equals("")) {
+                       return; // dev build, we can only test this on the build server.
+               }
+               Date date = new Date(Version.getTime());
+               SimpleDateFormat format = new SimpleDateFormat(Version.SIMPLE_DATE_FORMAT, Locale.getDefault());
+               format.setTimeZone(TimeZone.getTimeZone("GMT"));
+               String timeString = format.format(date);
+               assertEquals(Version.time_text, timeString);
+       }
+}
diff --git a/bridge/src/test/java/org/aspectj/bridge/context/CompilationAndWeavingContextTest.java b/bridge/src/test/java/org/aspectj/bridge/context/CompilationAndWeavingContextTest.java
new file mode 100644 (file)
index 0000000..825a52b
--- /dev/null
@@ -0,0 +1,67 @@
+/* *******************************************************************
+ * Copyright (c) 2005 Contributors.
+ * All rights reserved. 
+ * This program and the accompanying materials are made available 
+ * under the terms of the Eclipse Public License v1.0 
+ * which accompanies this distribution and is available at 
+ * http://eclipse.org/legal/epl-v10.html 
+ *  
+ * Contributors: 
+ *   Adrian Colyer                     Initial implementation
+ * ******************************************************************/
+package org.aspectj.bridge.context;
+
+import junit.framework.TestCase;
+
+/**
+ * @author colyer
+ *
+ */
+public class CompilationAndWeavingContextTest extends TestCase {
+
+       public void testEnteringPhase() {
+               CompilationAndWeavingContext.enteringPhase(1,"XYZ");
+               assertEquals("when fiddling XYZ\n",CompilationAndWeavingContext.getCurrentContext());
+       }
+       
+       public void testDoubleEntry() {
+               CompilationAndWeavingContext.enteringPhase(1,"XYZ");
+               CompilationAndWeavingContext.enteringPhase(2, "ABC");
+               assertEquals("when mucking about with ABC\nwhen fiddling XYZ\n",CompilationAndWeavingContext.getCurrentContext());              
+       }
+       
+       public void testEntryEntryExit() {
+               CompilationAndWeavingContext.enteringPhase(1,"XYZ");
+               ContextToken ct = CompilationAndWeavingContext.enteringPhase(2, "ABC");
+               CompilationAndWeavingContext.leavingPhase(ct);
+               assertEquals("when fiddling XYZ\n",CompilationAndWeavingContext.getCurrentContext());           
+       }
+       
+       public void testEntryExitTop() {
+               ContextToken ct = CompilationAndWeavingContext.enteringPhase(1,"XYZ");
+               CompilationAndWeavingContext.enteringPhase(2, "ABC");
+               CompilationAndWeavingContext.leavingPhase(ct);
+               assertEquals("",CompilationAndWeavingContext.getCurrentContext());              
+       }
+
+       
+       protected void setUp() throws Exception {
+               CompilationAndWeavingContext.reset();
+               CompilationAndWeavingContext.registerFormatter(1, new MyContextFormatter("fiddling "));
+               CompilationAndWeavingContext.registerFormatter(2, new MyContextFormatter("mucking about with "));
+       }
+       
+       private static class MyContextFormatter implements ContextFormatter {
+
+               private String prefix;
+               
+               public MyContextFormatter(String prefix) {
+                       this.prefix = prefix;
+               }
+               
+               public String formatEntry(int phaseId, Object data) {
+                       return prefix + data.toString();
+               }
+               
+       }
+}
diff --git a/bridge/testsrc/org/aspectj/bridge/BridgeModuleTests.java b/bridge/testsrc/org/aspectj/bridge/BridgeModuleTests.java
deleted file mode 100644 (file)
index 5811f98..0000000
+++ /dev/null
@@ -1,35 +0,0 @@
-package org.aspectj.bridge;
-/* *******************************************************************
- * Copyright (c) 1999-2001 Xerox Corporation, 
- *               2002 Palo Alto Research Center, Incorporated (PARC).
- * All rights reserved. 
- * This program and the accompanying materials are made available 
- * under the terms of the Eclipse Public License v1.0 
- * which accompanies this distribution and is available at 
- * http://www.eclipse.org/legal/epl-v10.html 
- *  
- * Contributors: 
- *     Xerox/PARC     initial implementation 
- * ******************************************************************/
-
-
-// default package
-
-import org.aspectj.bridge.context.CompilationAndWeavingContextTest;
-
-import junit.framework.Test;
-import junit.framework.TestCase;
-import junit.framework.TestSuite;
-
-public class BridgeModuleTests extends TestCase {
-
-    public static Test suite() { 
-        TestSuite suite = new TestSuite(BridgeModuleTests.class.getName());
-        suite.addTest(org.aspectj.bridge.BridgeTests.suite()); 
-        suite.addTestSuite(CompilationAndWeavingContextTest.class);
-        return suite;
-    }
-
-    public BridgeModuleTests(String name) { super(name); }
-
-}  
diff --git a/bridge/testsrc/org/aspectj/bridge/BridgeTests.java b/bridge/testsrc/org/aspectj/bridge/BridgeTests.java
deleted file mode 100644 (file)
index 5d0b1d0..0000000
+++ /dev/null
@@ -1,35 +0,0 @@
-/* *******************************************************************
- * Copyright (c) 1999-2001 Xerox Corporation, 
- *               2002 Palo Alto Research Center, Incorporated (PARC).
- * All rights reserved. 
- * This program and the accompanying materials are made available 
- * under the terms of the Eclipse Public License v1.0 
- * which accompanies this distribution and is available at 
- * http://www.eclipse.org/legal/epl-v10.html 
- *  
- * Contributors: 
- *     Xerox/PARC     initial implementation 
- * ******************************************************************/
-
-
-package org.aspectj.bridge;
-
-import junit.framework.Test;
-import junit.framework.TestCase;
-import junit.framework.TestSuite;
-
-public class BridgeTests extends TestCase {
-
-    public static Test suite() { 
-        TestSuite suite = new TestSuite(BridgeTests.class.getName());
-        //$JUnit-BEGIN$
-        suite.addTestSuite(CountingMessageHandlerTest.class); 
-        suite.addTestSuite(MessageTest.class); 
-        suite.addTestSuite(VersionTest.class); 
-        //$JUnit-END$
-        return suite;
-    }
-
-    public BridgeTests(String name) { super(name); }
-
-}  
diff --git a/bridge/testsrc/org/aspectj/bridge/CountingMessageHandlerTest.java b/bridge/testsrc/org/aspectj/bridge/CountingMessageHandlerTest.java
deleted file mode 100644 (file)
index dc357a8..0000000
+++ /dev/null
@@ -1,82 +0,0 @@
-/* *******************************************************************
- * Copyright (c) 1999-2001 Xerox Corporation, 
- *               2002 Palo Alto Research Center, Incorporated (PARC).
- * All rights reserved. 
- * This program and the accompanying materials are made available 
- * under the terms of the Eclipse Public License v1.0 
- * which accompanies this distribution and is available at 
- * http://www.eclipse.org/legal/epl-v10.html 
- *  
- * Contributors: 
- *     Xerox/PARC     initial implementation 
- * ******************************************************************/
-
-package org.aspectj.bridge;
-
-
-import junit.framework.TestCase;
-import junit.textui.TestRunner;
-
-/**
- * 
- */
-public class CountingMessageHandlerTest extends TestCase {
-
-   private static final String ME 
-        = "org.aspectj.bridge.CountingMessageHandlerTest"; // XXX
-
-    /** @param args ignored */
-    public static void main(String[] args) {
-        TestRunner.main(new String[] {ME});
-    }
-
-       /**
-        * Constructor for MessageTest.
-        * @param name
-        */
-       public CountingMessageHandlerTest(String name) {
-               super(name);
-       }
-
-    public void testSimpleWrapping() {
-        MessageHandler m = new MessageHandler();
-        CountingMessageHandler me = new CountingMessageHandler(m);
-        checkCountingMessageHandler(me);
-    }
-
-    public void testCounterWrapping() {
-        MessageHandler m = new MessageHandler();
-        CountingMessageHandler first = new CountingMessageHandler(m);
-        CountingMessageHandler me = new CountingMessageHandler(first);
-        checkCountingMessageHandler(me);
-    }
-
-    void checkCountingMessageHandler(CountingMessageHandler me) {
-        MessageUtil.warn(me, "warn 1");
-        assertTrue(!me.hasErrors());
-        assertEquals(0 , me.numMessages(IMessage.ERROR, false));
-        assertEquals(1 , me.numMessages(IMessage.WARNING, false));
-        assertEquals(0 , me.numMessages(IMessage.INFO, false));
-        assertEquals(0 , me.numMessages(IMessage.ERROR, true));
-        assertEquals(1 , me.numMessages(IMessage.WARNING, true));
-        assertEquals(1 , me.numMessages(IMessage.INFO, true));
-        
-        MessageUtil.info(me, "info 1");
-        assertTrue(!me.hasErrors());
-        assertEquals(0 , me.numMessages(IMessage.ERROR, false));
-        assertEquals(1 , me.numMessages(IMessage.WARNING, false));
-        assertEquals(1 , me.numMessages(IMessage.INFO, false));
-        assertEquals(0 , me.numMessages(IMessage.ERROR, true));
-        assertEquals(1 , me.numMessages(IMessage.WARNING, true));
-        assertEquals(2 , me.numMessages(IMessage.INFO, true));
-
-        MessageUtil.error(me, "error 1");
-        assertTrue(me.hasErrors());
-        assertEquals(1 , me.numMessages(IMessage.ERROR, false));
-        assertEquals(1 , me.numMessages(IMessage.WARNING, false));
-        assertEquals(1 , me.numMessages(IMessage.INFO, false));
-        assertEquals(1 , me.numMessages(IMessage.ERROR, true));
-        assertEquals(2 , me.numMessages(IMessage.WARNING, true));
-        assertEquals(3 , me.numMessages(IMessage.INFO, true));
-    }    
-}
diff --git a/bridge/testsrc/org/aspectj/bridge/MessageTest.java b/bridge/testsrc/org/aspectj/bridge/MessageTest.java
deleted file mode 100644 (file)
index be30c48..0000000
+++ /dev/null
@@ -1,321 +0,0 @@
-/* *******************************************************************
- * Copyright (c) 1999-2001 Xerox Corporation, 
- *               2002 Palo Alto Research Center, Incorporated (PARC).
- * All rights reserved. 
- * This program and the accompanying materials are made available 
- * under the terms of the Eclipse Public License v1.0 
- * which accompanies this distribution and is available at 
- * http://www.eclipse.org/legal/epl-v10.html 
- *  
- * Contributors: 
- *     Xerox/PARC     initial implementation 
- * ******************************************************************/
-
-package org.aspectj.bridge;
-
-import java.io.File;
-import java.util.Arrays;
-import java.util.BitSet;
-import java.util.Comparator;
-import java.util.Iterator;
-import java.util.List;
-import java.util.ListIterator;
-
-import junit.framework.AssertionFailedError;
-import junit.framework.TestCase;
-import junit.textui.TestRunner;
-
-/**
- * 
- */
-public class MessageTest extends TestCase {
-
-   private static final String ME 
-        = "org.aspectj.bridge.MessageTest"; // XXX
-
-    /** @param args ignored */
-    public static void main(String[] args) {
-        TestRunner.main(new String[] {ME});
-    }
-
-       /**
-        * Constructor for MessageTest.
-        * @param name
-        */
-       public MessageTest(String name) {
-               super(name);
-       }
-    
-    <T> void checkListOrder(List<T> list, Comparator<T> c) { // XXX util
-        assertNotNull(list);
-        assertNotNull(c);
-        ListIterator<T> it = list.listIterator();
-        T last = null;
-        T current = null;
-        while (it.hasNext()) {
-            current = it.next();
-            if (null != last) {
-                int i = c.compare(last, current);
-                if (i > 0) {
-                    assertTrue( last + " > " + current + " (" + i + ")", false);
-                }                
-            } 
-            last = current;
-        }
-    }
-        
-    public void testKindOrder() {
-        // first briefly validate the checker
-        checkListOrder(Arrays.asList(new String[] { "a", "b", "C" }),
-            String.CASE_INSENSITIVE_ORDER);
-        checkListOrder(IMessage.KINDS, IMessage.Kind.COMPARATOR);
-    }
-    
-    public void testKind_isSameOrLessThan() {
-        IMessage.Kind last;
-        IMessage.Kind next = null;
-        for (Iterator<IMessage.Kind> iter = IMessage.KINDS.iterator(); iter.hasNext();) {
-            last = next;
-            next = iter.next();
-            if (null == last) {
-                continue;
-            }
-            String label = "last: " + last + " next: " + next;
-            assertTrue(label, !next.isSameOrLessThan(null));
-            assertTrue(label, !next.isSameOrLessThan(last));
-            assertTrue(label, last.isSameOrLessThan(next));
-            assertTrue(label, next.isSameOrLessThan(next));
-        }    
-    }
-    
-    public void testMessageHandler() {
-        boolean handleMessageResult = true;
-        checkEmptyMessageHolder(new MessageHandler(handleMessageResult), handleMessageResult);
-        handleMessageResult = false;
-        checkEmptyMessageHolder(new MessageHandler(handleMessageResult), handleMessageResult);
-    }
-    
-    public void checkEmptyMessageHolder(
-        IMessageHolder h, 
-        final boolean handleMessageResult) {
-       //  { INFO, DEBUG, WARNING, ERROR, FAIL, ABORT }));  
-        assertNotNull(h);
-        assertTrue(!h.hasAnyMessage(null, true));
-        assertTrue(!h.hasAnyMessage(null, false));
-        assertTrue(!h.hasAnyMessage(IMessage.INFO, true));
-        assertTrue(!h.hasAnyMessage(IMessage.INFO, false));
-        
-        assertTrue(handleMessageResult == h.handleMessage(make("error 1", IMessage.ERROR)));
-        assertTrue(handleMessageResult == h.handleMessage(make("error 2", IMessage.ERROR)));
-        assertTrue(handleMessageResult == h.handleMessage(make("fail 1", IMessage.FAIL)));
-        assertTrue(handleMessageResult == h.handleMessage(make("fail 2", IMessage.FAIL)));
-        assertTrue(handleMessageResult == h.handleMessage(make("debug 1", IMessage.DEBUG)));
-        assertTrue(handleMessageResult == h.handleMessage(make("debug 2", IMessage.DEBUG)));
-        
-        assertTrue(h.hasAnyMessage(null, true));
-        assertTrue(h.hasAnyMessage(null, false));
-        assertTrue(h.hasAnyMessage(IMessage.ERROR, true));
-        assertTrue(h.hasAnyMessage(IMessage.ERROR, false));
-        assertTrue(h.hasAnyMessage(IMessage.FAIL, true));
-        assertTrue(h.hasAnyMessage(IMessage.FAIL, false));
-        assertTrue(h.hasAnyMessage(IMessage.DEBUG, true));
-        assertTrue(h.hasAnyMessage(IMessage.DEBUG, false));
-        
-        assertTrue(!h.hasAnyMessage(IMessage.INFO, IMessageHolder.EQUAL));
-        assertTrue(!h.hasAnyMessage(IMessage.WARNING, IMessageHolder.EQUAL));
-        assertTrue(!h.hasAnyMessage(IMessage.ABORT, IMessageHolder.EQUAL));
-        assertTrue(h.hasAnyMessage(IMessage.INFO, IMessageHolder.ORGREATER));
-        assertTrue(h.hasAnyMessage(IMessage.WARNING, IMessageHolder.ORGREATER));
-        assertTrue(!h.hasAnyMessage(IMessage.ABORT, IMessageHolder.ORGREATER));
-        
-        assertTrue(0 == h.numMessages(IMessage.INFO, IMessageHolder.EQUAL));
-        assertTrue(0 == h.numMessages(IMessage.WARNING, IMessageHolder.EQUAL));
-        assertTrue(0 == h.numMessages(IMessage.ABORT, IMessageHolder.EQUAL));
-
-        assertTrue(6 == h.numMessages(null, IMessageHolder.ORGREATER));
-        assertTrue(6 == h.numMessages(null, IMessageHolder.EQUAL));
-        assertTrue(6 == h.numMessages(IMessage.INFO, IMessageHolder.ORGREATER));
-        assertTrue(6 == h.numMessages(IMessage.DEBUG, IMessageHolder.ORGREATER));
-        assertTrue(4 == h.numMessages(IMessage.WARNING, IMessageHolder.ORGREATER));
-        assertTrue(4 == h.numMessages(IMessage.ERROR, IMessageHolder.ORGREATER));
-        assertTrue(2 == h.numMessages(IMessage.FAIL, IMessageHolder.ORGREATER));
-        assertTrue(0 == h.numMessages(IMessage.ABORT, IMessageHolder.ORGREATER));
-        
-    } 
-    
-    public void testMessage() {
-        String input = "input";
-        Throwable thrown = null;
-        ISourceLocation sl = null;
-        Class<?> exClass = null;
-        String descriptor = "Message"; // for make(...)
-        IMessage.Kind kind = IMessage.INFO;
-
-        // -- kind variants
-        roundTrip(input, kind, thrown, sl, descriptor, exClass);
-        kind = IMessage.WARNING;
-        roundTrip(input, kind, thrown, sl, descriptor, exClass);
-        kind = IMessage.ERROR;
-        roundTrip(input, kind, thrown, sl, descriptor, exClass);
-        kind = IMessage.DEBUG;
-        roundTrip(input, kind, thrown, sl, descriptor, exClass);
-        kind = IMessage.FAIL;
-        roundTrip(input, kind, thrown, sl, descriptor, exClass);
-
-        // -- throwable
-        kind = IMessage.FAIL;
-        thrown = new AbortException();
-        input = null;
-        roundTrip(input, kind, thrown, sl, descriptor, exClass);
-
-        // -- source location
-        kind = IMessage.WARNING;
-        thrown = null;
-        input = "type not found";
-        File f = new File("some/file.java"); // XXX unchecked
-        sl = new SourceLocation(f, 0, 0, 0);
-        roundTrip(input, kind, thrown, sl, descriptor, exClass);
-        sl = new SourceLocation(f, 1, 1, 0);
-        roundTrip(input, kind, thrown, sl, descriptor, exClass);
-
-        // -- input error tests - null kind, null input (factory-dependent)
-        kind = null;
-        exClass = IllegalArgumentException.class;
-        roundTrip(input, kind, thrown, sl, descriptor, exClass);
-        input = null;
-        kind = IMessage.INFO;
-        roundTrip(input, kind, thrown, sl, descriptor, exClass);                        
-    }
-    
-    protected IMessage make(String message, IMessage.Kind kind) {
-        return new Message(message, kind, null, null);
-    }
-
-    /** make a Message per descriptor and input */
-    protected IMessage make(String input, IMessage.Kind kind,
-        Throwable thrown, ISourceLocation sourceLocation, 
-        String descriptor) { // XXX ignored for now
-            return new Message(input, kind, thrown, sourceLocation);
-    }
-
-    /**
-     * Simple round-trip on the message
-     */
-    protected void roundTrip(String input, IMessage.Kind kind,
-        Throwable thrown, ISourceLocation sourceLocation, 
-        String descriptor, Class<?> exClass) {
-        try {
-            IMessage m = make(input, kind, thrown, sourceLocation, descriptor);
-            if ((null == input) && (null != thrown)) {
-                input = thrown.getMessage();
-            }
-            roundTripCheck(m, input, kind, thrown, sourceLocation);
-        } catch (AssertionFailedError x) {
-            throw x;
-        } catch (Throwable t) {
-            assertTrue(null != exClass);
-            assertTrue(exClass.isAssignableFrom(t.getClass()));
-        }
-    }
-
-    protected void roundTripCheck(IMessage message, String input, IMessage.Kind kind,
-        Throwable thrown, ISourceLocation sourceLocation) {
-            IMessage m = message;
-            assertTrue("not null", null != m);
-            assertEquals(input, m.getMessage());
-            assertTrue(""+kind, kind == m.getKind());
-            assertTrue(""+thrown, equals(thrown, m.getThrown()));
-            assertTrue(""+sourceLocation, 
-                equals(sourceLocation, m.getSourceLocation()));
-            String err = new KindTest().testKindSet(message, kind);
-            if (null != err) {
-                assertTrue(err, false);
-            }
-    }
-    
-    protected static boolean equals(Object one, Object two) {
-        if (null == one) {
-            return (null == two);
-        } else if (null == two) {
-            return false;
-        } else {
-            return one.equals(two);
-        }
-    }
-}
-
-/** test correlation between message and enclosed kind */
-class KindTest {
-    /** order tracked in checkKindMethods() */
-    static final IMessage.Kind[] KINDS = new IMessage.Kind[] 
-            {  IMessage.ABORT, IMessage.DEBUG, IMessage.ERROR, 
-                IMessage.INFO, IMessage.WARNING, IMessage.FAIL };
-
-    static final List<IMessage.Kind> KINDLIST = Arrays.asList(KINDS);
-
-    /** used to clear instance BitSet */
-    static final BitSet UNSET = new BitSet(KINDS.length);
-
-
-    final BitSet expected = new BitSet(KINDS.length);
-    IMessage.Kind kind = IMessage.INFO;
-    
-    /** @return error if failed */
-    public String testKindSet(IMessage m, IMessage.Kind newKind) {
-        IMessage.Kind oldKind = this.kind;
-        String result = setKind(newKind);
-        if (null == result) {
-            result = checkKindSet(m, newKind);
-        }
-        if (null == result) {
-            result = checkExpectedKind(m);
-        }
-        return (null != result? result : setKind(oldKind));
-    }
-    
-    /** @return error if failed */
-    private String setKind(IMessage.Kind kind) {
-        this.kind = kind;
-        int index = KINDLIST.indexOf(kind);
-        if (-1 == index) {
-            return "unknown kind: " + kind;
-        }
-        expected.and(UNSET);
-        expected.set(index);
-        return null;
-    }
-    
-    /** @return error if failed */
-    String checkExpectedKind(IMessage m) {
-        StringBuffer result = new StringBuffer();
-        for (int i = 0; i < KINDS.length; i++) {
-            if (expected.get(i) != checkKindMethods(m, i)) {
-                String s = "expected " + expected.get(i)
-                    + " for is{Method} for " + KINDS[i];
-                result.append(s + "\n");
-            } 
-               }  
-        return (0 < result.length() ? result.toString() : null); 
-    }
-    
-    String checkKindSet(IMessage m, IMessage.Kind kind) {
-        if (kind != m.getKind()) {
-            return "expected kind " + kind + " got " + m.getKind();
-        }
-        return null;
-    }
-    
-    /** @return true if index matches isFoo() reporting */
-    boolean checkKindMethods(IMessage m, int index) {
-        switch (index) {
-            case (0) : return m.isAbort(); 
-            case (1) : return m.isDebug(); 
-            case (2) : return m.isError(); 
-            case (3) : return m.isInfo(); 
-            case (4) : return m.isWarning(); 
-            case (5) : return m.isFailed(); 
-            default : throw new IllegalArgumentException("index=" + index);
-                                
-        }
-    }
-}
diff --git a/bridge/testsrc/org/aspectj/bridge/VersionTest.java b/bridge/testsrc/org/aspectj/bridge/VersionTest.java
deleted file mode 100644 (file)
index cee4c84..0000000
+++ /dev/null
@@ -1,60 +0,0 @@
-/* *******************************************************************
- * Copyright (c) 1999-2001 Xerox Corporation, 
- *               2002 Palo Alto Research Center, Incorporated (PARC).
- * All rights reserved. 
- * This program and the accompanying materials are made available 
- * under the terms of the Eclipse Public License v1.0 
- * which accompanies this distribution and is available at 
- * http://www.eclipse.org/legal/epl-v10.html 
- *  
- * Contributors: 
- *     Xerox/PARC     initial implementation 
- * ******************************************************************/
-
-package org.aspectj.bridge;
-
-import java.text.SimpleDateFormat;
-import java.util.Date;
-import java.util.Locale;
-import java.util.TimeZone;
-
-import org.aspectj.util.LangUtil;
-
-import junit.framework.TestCase;
-import junit.textui.TestRunner;
-
-/**
- * 
- */
-public class VersionTest extends TestCase {
-
-       private static final String ME = "org.aspectj.bridge.VersionTest";
-
-       /** @param args ignored */
-       public static void main(String[] args) {
-               TestRunner.main(new String[] { ME });
-       }
-
-       /**
-        * Constructor for MessageTest.
-        * 
-        * @param name
-        */
-       public VersionTest(String name) {
-               super(name);
-       }
-
-       public void testVersion() {
-               if (LangUtil.is11VMOrGreater()) {
-                       return;
-               }
-               if (Version.time_text.equals("")) {
-                       return; // dev build, we can only test this on the build server.
-               }
-               Date date = new Date(Version.getTime());
-               SimpleDateFormat format = new SimpleDateFormat(Version.SIMPLE_DATE_FORMAT, Locale.getDefault());
-               format.setTimeZone(TimeZone.getTimeZone("GMT"));
-               String timeString = format.format(date);
-               assertEquals(Version.time_text, timeString);
-       }
-}
diff --git a/bridge/testsrc/org/aspectj/bridge/context/CompilationAndWeavingContextTest.java b/bridge/testsrc/org/aspectj/bridge/context/CompilationAndWeavingContextTest.java
deleted file mode 100644 (file)
index 825a52b..0000000
+++ /dev/null
@@ -1,67 +0,0 @@
-/* *******************************************************************
- * Copyright (c) 2005 Contributors.
- * All rights reserved. 
- * This program and the accompanying materials are made available 
- * under the terms of the Eclipse Public License v1.0 
- * which accompanies this distribution and is available at 
- * http://eclipse.org/legal/epl-v10.html 
- *  
- * Contributors: 
- *   Adrian Colyer                     Initial implementation
- * ******************************************************************/
-package org.aspectj.bridge.context;
-
-import junit.framework.TestCase;
-
-/**
- * @author colyer
- *
- */
-public class CompilationAndWeavingContextTest extends TestCase {
-
-       public void testEnteringPhase() {
-               CompilationAndWeavingContext.enteringPhase(1,"XYZ");
-               assertEquals("when fiddling XYZ\n",CompilationAndWeavingContext.getCurrentContext());
-       }
-       
-       public void testDoubleEntry() {
-               CompilationAndWeavingContext.enteringPhase(1,"XYZ");
-               CompilationAndWeavingContext.enteringPhase(2, "ABC");
-               assertEquals("when mucking about with ABC\nwhen fiddling XYZ\n",CompilationAndWeavingContext.getCurrentContext());              
-       }
-       
-       public void testEntryEntryExit() {
-               CompilationAndWeavingContext.enteringPhase(1,"XYZ");
-               ContextToken ct = CompilationAndWeavingContext.enteringPhase(2, "ABC");
-               CompilationAndWeavingContext.leavingPhase(ct);
-               assertEquals("when fiddling XYZ\n",CompilationAndWeavingContext.getCurrentContext());           
-       }
-       
-       public void testEntryExitTop() {
-               ContextToken ct = CompilationAndWeavingContext.enteringPhase(1,"XYZ");
-               CompilationAndWeavingContext.enteringPhase(2, "ABC");
-               CompilationAndWeavingContext.leavingPhase(ct);
-               assertEquals("",CompilationAndWeavingContext.getCurrentContext());              
-       }
-
-       
-       protected void setUp() throws Exception {
-               CompilationAndWeavingContext.reset();
-               CompilationAndWeavingContext.registerFormatter(1, new MyContextFormatter("fiddling "));
-               CompilationAndWeavingContext.registerFormatter(2, new MyContextFormatter("mucking about with "));
-       }
-       
-       private static class MyContextFormatter implements ContextFormatter {
-
-               private String prefix;
-               
-               public MyContextFormatter(String prefix) {
-                       this.prefix = prefix;
-               }
-               
-               public String formatEntry(int phaseId, Object data) {
-                       return prefix + data.toString();
-               }
-               
-       }
-}