]> source.dussan.org Git - aspectj.git/commitdiff
generics
authoraclement <aclement>
Wed, 14 Jul 2010 23:19:53 +0000 (23:19 +0000)
committeraclement <aclement>
Wed, 14 Jul 2010 23:19:53 +0000 (23:19 +0000)
bridge/src/org/aspectj/bridge/AbortException.java
bridge/src/org/aspectj/bridge/CountingMessageHandler.java
bridge/src/org/aspectj/bridge/IMessage.java
bridge/src/org/aspectj/bridge/IMessageHolder.java
bridge/src/org/aspectj/bridge/Message.java
bridge/src/org/aspectj/bridge/MessageHandler.java
bridge/src/org/aspectj/bridge/MessageUtil.java
bridge/src/org/aspectj/bridge/ReflectionFactory.java
bridge/src/org/aspectj/bridge/SourceLocation.java

index 7c4ed13af734c16730381126180f45eb29b9de5d..acde7cd28bf161ea30f4b58a59265a61dbcb14eb 100644 (file)
@@ -18,23 +18,23 @@ 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) {
+ * 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>
+ * }
+ * </pre>
+ * 
+ * @author PARC
+ * @author Andy Clement
  */
 public class AbortException extends RuntimeException { // XXX move porters out, handle proxy better
 
@@ -42,189 +42,185 @@ public class AbortException extends RuntimeException { // XXX move porters out,
 
        private boolean isSilent = false;
 
-    /** used when message text is null */
-    public static final String NO_MESSAGE_TEXT 
-        = "AbortException (no message)";
-    
-    private static final ArrayList porters = new ArrayList();
-    
-    /**
-     * 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 = (AbortException) 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.
+       /** 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;
-       }
-
-    /**
+               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);
+               printStackTrace(System.out);
        }
 
-    /**
-     * Print the stack trace of any enclosed thrown
-     * or this otherwise.
+       /**
+        * 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);
-        }            
-    }
+               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;
        }
index 52d759678fe168669600b9ba5464b501956daafd..4ce55087675c8776cb4aeffda37442686a81a5a9 100644 (file)
@@ -15,148 +15,143 @@ package org.aspectj.bridge;
 
 import java.util.Enumeration;
 import java.util.Hashtable;
-import java.util.Iterator;
 
 import org.aspectj.util.LangUtil;
 
-/** 
- * Wrap an IMessageHandler to count messages handled.
- * Messages being ignored by the delegate IMessageHandler are not counted.
+/**
+ * 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 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();
-        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 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 enu = counters.elements(); enu.hasMoreElements();) {
-                               result += ((IntHolder) enu.nextElement()).count;                                
+
+       /** @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);
+                               }
                        }
-        } else if (!orGreater) {
-            result = numMessages(kind);
-        } else {
-            for (Iterator iter = IMessage.KINDS.iterator(); iter.hasNext();) {
-                IMessage.Kind k = (IMessage.Kind) iter.next();
-                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 = (IntHolder) 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 = (IntHolder) 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();
-    }
+               }
+               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();
+       }
 
 }
index 4f47282955f42dbf55b7f48dc3a9660737a70ef1..a32a631e6926b002f9ca81590f6874c161d61219 100644 (file)
@@ -90,11 +90,9 @@ public interface IMessage {
        /** @return source location associated with this message, or null if none */
        ISourceLocation getSourceLocation();
 
-       public static final class Kind implements Comparable {
-               public static final Comparator COMPARATOR = new Comparator() {
-                       public int compare(Object o1, Object o2) {
-                               Kind one = (Kind) o1;
-                               Kind two = (Kind) o2;
+       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) {
@@ -115,7 +113,7 @@ public interface IMessage {
                        return (0 >= COMPARATOR.compare(this, kind));
                }
 
-               public int compareTo(Object other) {
+               public int compareTo(IMessage.Kind other) {
                        return COMPARATOR.compare(this, other);
                }
 
@@ -148,5 +146,5 @@ public interface IMessage {
         * 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 getExtraSourceLocations();
+       public List<ISourceLocation> getExtraSourceLocations();
 }
index 324c5f039fb50857dfe8fb9a9f911324dd72af37..fdf2a67792655f296a0707ab0e302cfdd8ec644f 100644 (file)
@@ -18,53 +18,49 @@ 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
+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).
+       /**
+        * 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
+        * @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.
+        * 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 
+        * @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.
+        * 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 
+        * @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 getUnmodifiableListView();
-    
-    /**
-     * Clear any messages.
-     * @throws UnsupportedOperationException if message list is read-only
-     */
-    void clearMessages() throws UnsupportedOperationException;
+
+       /** @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;
 }
index 91ccad4c1b76d7adc5a60f1be64001ba5dab6176..a4f17072bf528d92a67c8ace9ca5459d05f22009 100644 (file)
  *     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.
+ * 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/*SourceLocation*/ 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));
-    }
-        
+       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 message, handling null values for message and kind
-        * if thrown is not null.
+        * 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.
+        * @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) {
+       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.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.EMPTY_LIST;
+               if (otherLocs != null) {
+                       this.extraSourceLocations = Collections.unmodifiableList(Arrays.asList(otherLocs));
+               } else {
+                       this.extraSourceLocations = Collections.emptyList();
                }
                if (null == this.kind) {
-                        throw new IllegalArgumentException("null 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;
-    }
-       
+
+       /**
+        * 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);
-    }
+       /**
+        * @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 getExtraSourceLocations() {
+
+       public List<ISourceLocation> getExtraSourceLocations() {
                return extraSourceLocations;
        }
 
@@ -192,7 +183,7 @@ public class Message implements IMessage {
        public int getSourceStart() {
                return sourceStart;
        }
-       
+
        public int getSourceEnd() {
                return sourceEnd;
        }
index dc6fb34aeb5f7b29afca7e354ac8f916ce6fdb3d..6fd8539cc0645ec62e45ce91efe4134cacb0f0b1 100644 (file)
 
 package org.aspectj.bridge;
 
-
 import java.util.ArrayList;
 import java.util.Collections;
-import java.util.Iterator;
 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.
+ * 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 messages;
-    /** kinds of messages to be ignored */
-    protected final ArrayList 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();
-        ignoring = new ArrayList();
-        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();
-        }
-    }
+       /** 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
+       // ---------------------- 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.
+        * 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;
-    }
+               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)
+       /**
+        * @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
 
+       // ---------------------- 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);
-        }
-    }
+       /**
+        * 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);
-        }
-    }
+       /**
+        * 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 (Iterator iter = messages.iterator(); iter.hasNext();) {
-                if (kind == ((IMessage) iter.next()).getKind()) {
-                    return true;
-                }
-            }
-        } else {
-            for (Iterator iter = messages.iterator(); iter.hasNext();) {
-                IMessage m = (IMessage) iter.next();
-                if (kind.isSameOrLessThan(m.getKind())) {
-                    return true;
-                }
-            }
-        }
-       return false;
+               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;
        }
 
-    /** 
-     * @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 (Iterator iter = messages.iterator(); iter.hasNext();) {
-                if (kind == ((IMessage) iter.next()).getKind()) {
-                    result++;
-                }
-            }
-        } else {
-            for (Iterator iter = messages.iterator(); iter.hasNext();) {
-                IMessage m = (IMessage) iter.next();
-                if (kind.isSameOrLessThan(m.getKind())) {
-                    result++;
-                }
-            }
-        }       
-        return result;
-    }
-    
-    /**
+       /**
         * @see org.aspectj.bridge.IMessageHolder#getUnmodifiableListView()
         */
-       public List 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 (IMessage[]) messages.toArray(IMessage.RA_IMessage);
-       }
-        ArrayList result = new ArrayList();
-        if (!orGreater) {
-            for (Iterator iter = messages.iterator(); iter.hasNext();) {
-                IMessage m = (IMessage) iter.next();
-                if (kind == m.getKind()) {
-                    result.add(m);
-                }
-            }
-        } else {
-            for (Iterator iter = messages.iterator(); iter.hasNext();) {
-                IMessage m = (IMessage) iter.next();                
-                if (kind.isSameOrLessThan(m.getKind())) {
-                    result.add(m);
-                }
-            }
-        }       
-        if (0 == result.size()) {
-            return IMessage.RA_IMessage;
-        }
-        return (IMessage[]) 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;
-        }
+       /**
+        * 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;
+               }
+
+       }
 
 }
index e9f23031e06480aa7fe6513646933b3e7ceadf02..6d85ea6f9a71f24f8b5dcb0a6b9534f41a4363e5 100644 (file)
 
 package org.aspectj.bridge;
 
-import java.io.*;
-import java.util.*;
+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.*;
+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));
-    }
+
+       // ------ 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)
+        * @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 (Iterator iter = IMessage.KINDS.iterator(); iter.hasNext();) {
-            IMessage.Kind kind = (IMessage.Kind) iter.next();
-            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 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) {
-                
-            }
+               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 getMessages(IMessageHolder holder, 
-            IMessage.Kind kind, boolean orGreater, String infix) { // XXX untested
-        if (null == holder) {
-            return Collections.EMPTY_LIST;
-        }
-        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.EMPTY_LIST;
-        }
-        return Collections.unmodifiableList(Arrays.asList(messages));
-    }
+               };
+               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)
+        * @see MessageHandler#getMessages(Kind)
         */
-       public static List getMessages(List messages, IMessage.Kind kind) {
-       if (null == messages) {
-            return Collections.EMPTY_LIST;
-       }
-       if (null == kind) {
-            return messages;
-       }
-        ArrayList result = new ArrayList();
-        for (Iterator iter = messages.iterator(); iter.hasNext();) {
-            IMessage element = (IMessage) iter.next();
-            if (kind == element.getKind()) {
-                result.add(element);
-            }
-        }
-        if (0 == result.size()) {
-            return Collections.EMPTY_LIST;
-        }
-        return result;
+       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 (Iterator iter = IMessage.KINDS.iterator(); iter.hasNext();) {
-                               IMessage.Kind k = (IMessage.Kind) iter.next();
-                       if (kind.equals(k.toString())) {
-                    return k;
-                }
-               }
-        }
+               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 result = (accumulate ? new ArrayList() : null);
-        for (Iterator iter = messages.iterator(); iter.hasNext();) {
-                       Object o = iter.next();
-            LangUtil.throwIaxIfFalse(o instanceof IMessage, "expected IMessage, got " + o);
-            IMessage m = (IMessage) o;
-            if (visitor.handleMessage(m)) {
-                if (accumulate) {
-                    result.add(m);
-                }
-            } else if (abortOnFail) {
-                break;
-            }                  
-               }
-        if (!accumulate || (0 == result.size())) {
-            return IMessage.RA_IMessage;
-        } else {
-            return (IMessage[]) 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);
-        }
+
+       /**
+        * 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)
-       {
+       }
+
+       // ------------------ 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 iter = message.getExtraSourceLocations().iterator(); iter.hasNext();) {
-                   ISourceLocation element = (ISourceLocation) 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();    
+               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();
        }
-    
-    
-    
-    
-    
-    
-    /**
-     * 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 (Iterator iter = IMessage.KINDS.iterator(); iter.hasNext();) {
-                       IMessage.Kind kind = (IMessage.Kind) iter.next();
+       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());
-            }
+                       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);
+                               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 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;
-    }
+               }
+               return result;
+       }
 }
index 78a716c3a72e04141fb4f50dbf5f3ba2c7adbabe..8eb65b3a032d5b897b2ff249c79836b092ecb01f 100644 (file)
@@ -20,87 +20,84 @@ 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;
-    }
+       public static final String OLD_AJC = "bridge.tools.impl.OldAjc";
+       public static final String ECLIPSE = "org.aspectj.ajdt.ajc.AjdtCommand";
 
-    /**
-     * @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(){}
+       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() {
+       }
 }
index e72673fde863d89b7b9e27c8de4a51a0f41a99fd..739dd52abfc681dc53af5d213cff06c6eaf7bca0 100644 (file)
@@ -26,7 +26,7 @@ import org.aspectj.util.LangUtil;
  * @see org.aspectj.tools.ide.SourceLine
  * @see org.aspectj.testing.harness.ErrorLine
  */
-public class SourceLocation implements ISourceLocation, java.io.Serializable {
+public class SourceLocation implements ISourceLocation {
 
        private static final long serialVersionUID = -5434765814401009794L;