Start line:  
End line:  

Snippet Preview

Snippet HTML Code

Stack Overflow Questions
  /* -*- mode: Java; c-basic-offset: 2; indent-tabs-mode: nil -*-
   *
   * Copyright (c) 2011 Edugility LLC.
   *
   * Permission is hereby granted, free of charge, to any person
   * obtaining a copy of this software and associated documentation
   * files (the "Software"), to deal in the Software without
   * restriction, including without limitation the rights to use, copy,
   * modify, merge, publish, distribute, sublicense and/or sell copies
  * of the Software, and to permit persons to whom the Software is
  * furnished to do so, subject to the following conditions:
  * 
  * The above copyright notice and this permission notice shall be
  * included in all copies or substantial portions of the Software.
  * 
  * THIS SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
  * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
  * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
  * NONINFRINGEMENT.  IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
  * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
  * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
  * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
  * DEALINGS IN THE SOFTWARE.
  *
  * The original copy of this license is available at
  * http://www.opensource.org/license/mit-license.html.
  */
 package com.edugility.throwables;
 
 
 import java.util.List;
 
An java.lang.Exception (and an implementation of the java.util.Collection interface) that also holds a modifiable list of other java.lang.Throwables that are not connected to the direct java.lang.Throwable.getCause(), but are affiliated nonetheless. Instances of this class are particularly useful when dealing with java.lang.Throwables in finally blocks.

A ThrowableChain always contains itself, so the return value of its size() method is always at least 1.

Author(s):
Laird Nelson
Version:
1.0-SNAPSHOT
Since:
1.0-SNAPSHOT
 
 public class ThrowableChain extends Exception implements Collection<Throwable> {

  
A serial version identifier uniquely identifying the version of this class. See the documentation for the Serializable class for details.
 
   private static final long serialVersionUID = 1L;

  
The java.util.List containing additional java.lang.Throwables. This field is never null and never empty and always contains this ThrowableChain itself as its first element.
 
   private final CopyOnWriteArrayList<Throwablelist;

  
Creates a new ThrowableChain.
 
   public ThrowableChain() {
     this(nullnull);
   }

  
Creates a new ThrowableChain with the supplied message and cause.

Parameters:
message the message; may be null
cause the cause; may be null
 
   public ThrowableChain(final String messagefinal Throwable cause) {
     super(message);
     this. = new CopyOnWriteArrayList<Throwable>();
     this..add(this);
     if (cause != null) {
       this.initCause(cause);
     }
   }

  
Creates a new ThrowableChain with the supplied message.

Parameters:
message the message; may be null
  public ThrowableChain(final String message) {
    this(messagenull);
  }

  
Creates a new ThrowableChain with the supplied cause and cause.

Parameters:
cause the cause; may be null
  public ThrowableChain(final Throwable cause) {
    this(nullcause);
  }

  
Adds the supplied java.lang.Throwable to this ThrowableChain if it is non-null and not this ThrowableChain (a ThrowableChain cannot add itself to itself, because it already contains itself), or initializes this ThrowableChain's cause with the supplied java.lang.Throwable if the cause has not yet been initialized.

If this ThrowableChain's cause is null, then this ThrowableChain's cause is initialized to the supplied java.lang.Throwable. Otherwise, the supplied java.lang.Throwable is added to this ThrowableChain's asList().

Under no circumstances are the supplied java.lang.Throwable's cause or any transitive causes added to this ThrowableChain's asList().

If the supplied java.lang.Throwable is already contained in this ThrowableChain's list of affiliated Throwables, then no action is taken.

Parameters:
throwable the java.lang.Throwable to add; may be null in which case no action will be taken
Returns:
true if the supplied java.lang.Throwable was actually added; false in all other cases
  public final boolean add(final Throwable throwable) {
    boolean returnValue = false;
    assert this. != null;
    if (throwable != null && throwable != this) {
      final Throwable cause = this.getCause();
      if (throwable != cause) {
        if (cause == null) {
          this.initCause(throwable);
        } else {
          returnValue = this..addIfAbsent(throwable);
        }
      }
    }
    return returnValue;
  }

  
Adds every non-null element contained by the supplied java.util.Collection of java.lang.Throwables to this ThrowableChain.

Parameters:
c the java.util.Collection of java.lang.Throwables; may be null in which case no action is taken
Returns:
true if at least one element was actually added
  public final boolean addAll(final Collection<? extends Throwablec) {
    boolean returnValue = false;
    if (c != null && !c.isEmpty()) {
      for (final Throwable t : c) {
        if (t != null) {
          returnValue = returnValue || this.add(t);
        }
      }
    }
    return returnValue;
  }

  
Removes the first instance of the supplied java.lang.Throwable from this ThrowableChain's list of affiliated java.lang.Throwables, provided that it is not null or this ThrowableChain itself.

Parameters:
throwable the affiliated java.lang.Throwable to remove provided it meets the conditions described
Returns:
true if this ThrowableChain actually removed the supplied java.lang.Throwable; false otherwise
Throws:
java.lang.UnsupportedOperationException if throwable is this ThrowableChain
  public final boolean remove(final Object throwable) {
    if (throwable == this) {
      throw new UnsupportedOperationException(new IllegalArgumentException("Cannot remove this ThrowableChain from itself"));
    }
    return this..remove(throwable);
  }

  
Causes this ThrowableChain to keep all of the elements found in the supplied java.util.Collection and to discard the rest.

Parameters:
c the java.util.Collection containing the elements to retain; must not be null or java.util.Collection.isEmpty(); must contain this ThrowableChain (because it is impossible for a ThrowableChain to discard itself)
Returns:
true if the contents of this ThrowableChain were actually affected by this method invocation
Throws:
java.lang.UnsupportedOperationException if c is null or empty, or if it does not contain this ThrowableChain (a ThrowableChain must always contain itself as an element)
See also:
size()
  public final boolean retainAll(final Collection<?> c) {
    if (c == null || c.isEmpty()) {
      throw new UnsupportedOperationException(new IllegalArgumentException("Cannot call retainAll() with a null or empty Collection"));
    }
    if (!c.contains(this)) {
      throw new UnsupportedOperationException(new IllegalArgumentException("Cannot effectively remove this ThrowableChain"));
    }
    return this..retainAll(c);
  }

  
Removes all elements contained by the supplied java.util.Collection found in this ThrowableChain.

Parameters:
c the java.util.Collection; may be null but, if non-null, must not java.util.Collection.contains(java.lang.Object) this ThrowableChain
Returns:
true if this ThrowableChain was changed as a result of an invocation of this method
Throws:
java.lang.UnsupportedOperationException if the supplied java.util.Collection is non-null and contains this ThrowableChain
  public final boolean removeAll(final Collection<?> c) {
    if (c == null || c.isEmpty()) {
      return false;
    } else if (c.contains(this)) {
      throw new UnsupportedOperationException(new IllegalArgumentException("Cannot call removeAll() with a Collection that contains this ThrowableChain"));
    } else {
      return this..removeAll(c);
    }
  }
  
  
  public final void clear() {
    throw new UnsupportedOperationException("clear is unsupported because a ThrowableChain always has itself as its first element");
  }

  
Returns true if this ThrowableChain contains the supplied java.lang.Object.

Parameters:
o the java.lang.Object to look for; may be null
Returns:
true if this ThrowableChain contains the supplied java.lang.Object
  public final boolean contains(final Object o) {
    return o == this || (o != null && this..contains(o));
  }

  
Returns true if all the elements of the supplied java.util.Collection are contained by this ThrowableChain.

Parameters:
stuff the java.util.Collection to test; may be null
Returns:
true if all the elements of the supplied java.util.Collection are contained by this ThrowableChain
  public final boolean containsAll(final Collection<?> stuff) {
    boolean returnValue = stuff == this;
    if (!returnValue && stuff != null && !stuff.isEmpty()) {
      returnValue = this..containsAll(stuff);
    }
    return returnValue;
  }

  
Returns false.

Returns:
false in all cases
  public final boolean isEmpty() {
    return false;
  }

  
Returns a new java.lang.Object array of this ThrowableChain's contents. This method never returns null.

Returns:
a new java.lang.Object array of this ThrowableChain's contents; never null
See also:
java.util.Collection.toArray()
  public final Object[] toArray() {
    return this..toArray();
  }

  
Attempts to fill and return the supplied array with the contents of this ThrowableChain. If the contents of this ThrowableChain will not fit into the supplied array, a new array will be allocated.

This method never returns null.

Parameters:
a the array to fill and return if possible; must not be null
Returns:
the contents of this ThrowableChain as an array; never null
Throws:
java.lang.NullPointerException if a is null
See also:
java.util.Collection.toArray(java.lang.Object[])
  public final <T> T[] toArray(final T[] a) {
    return this..toArray(a);
  }

  
Returns a new unmodifiable view of this ThrowableChain. The returned java.util.List is non-null, is non-java.util.Collection.isEmpty(), safe for iteration by multiple threads without synchronization or locking, contains this ThrowableChain itself as the first element, and is behaviorally identical to the java.util.List instances returned by the java.util.Collections.unmodifiableList(java.util.List) method.

Returns:
a read-only java.util.List view of this ThrowableChain and the underlying list of affiliated java.lang.Throwables; never null
  public final List<ThrowableasList() {
    return Collections.unmodifiableList(this.);
  }

  
Returns a new java.util.List of this ThrowableChain's affiliate java.lang.Throwables. The returned java.util.List is guaranteed to be non-null, to be safe for iteration by multiple threads without synchronization or locking, to be behaviorally identical to the java.util.List instances returned by the java.util.Collections.unmodifiableList(java.util.List) and to not contain this ThrowableChain.

Returns:
an immutable java.util.List of this ThrowableChain's affiliates; never null
  public final List<ThrowablegetAffiliatedThrowables() {
    final int size = this.size();
    if (size < 1) {
      // Protect against bad size() overrides.
      throw new IllegalStateException(String.format("this.size() < 1: %d"size));
    } else if (size == 1) {
      return Collections.emptyList();
    } else {
      return Collections.unmodifiableList(this..subList(1, size));
    }
  }

  
Returns the size of this ThrowableChain. A ThrowableChain always has a size of at least 1.

Returns:
the size of this ThrowableChain—a positive integer greater than or equal to 1
  public int size() {
    return this..size();
  }

  
Returns an java.util.Iterator that can be used to iterate over all contained Throwables.

This method never returns null.

The java.util.Iterator returned does not iterate over any given java.lang.Throwable's causal chain.

Returns:
an java.util.Iterator; never null; the first element of the java.util.Iterator will always be this ThrowableChain
See also:
asList()
  public final Iterator<Throwableiterator() {
    return this.asList().iterator();
  }

  

Prints the stack trace of this ThrowableChain and then of every Throwable contained by it. Each stack trace is preceded by the following text (quoted here; the quotation marks are not part of the text): "d. " d in the preceding text fragment is substituted with the ordinal position, starting with 1, of the java.lang.Throwable in question.

Parameters:
s the java.io.PrintStream to print to; must not be null
  public void printStackTrace(final PrintStream s) {
    if (s != null) {
      final int size = this.size();
      if (size < 1) {
        throw new IllegalStateException(String.format("this.size() < 1: %d"size));
      } else if (size == 1) {
        // Just us
        super.printStackTrace(s);
      } else {
        synchronized (s) {
          int i = 1;
          for (final Throwable t : this) {
            if (t == this) {
              s.print(i++ + ". ");
              super.printStackTrace(s);
            } else if (t != null) {
              s.print(i++ + ". ");
              t.printStackTrace(s);
            }
          }
        }
      }
    }
  }

  

Prints the stack trace of this ThrowableChain and then of every Throwable contained by it. Each stack trace is preceded by the following text (quoted here; the quotation marks are not part of the text): "d. " d in the preceding text fragment is substituted with the ordinal position, starting with 1, of the java.lang.Throwable in question.

Parameters:
w the java.io.PrintWriter to print to; must not be null
  public void printStackTrace(final PrintWriter w) {
    if (w != null) {
      final int size = this.size();
      if (size < 1) {
        throw new IllegalStateException(String.format("this.size() < 1: %d"size));
      } else if (size == 1) {
        // Just us
        super.printStackTrace(w);
      } else {
        synchronized (w) {
          int i = 1;
          for (final Throwable t : this) {          
            if (t == this) {
              w.print(i++ + ". ");
              super.printStackTrace(w);
            } else if (t != null) {
              w.print(i++ + ". ");
              t.printStackTrace(w);
            }
          }
        }
      }
    }
  }
New to GrepCode? Check out our FAQ X