Index: java/org/apache/commons/httpclient/ExceptionUtils.java
===================================================================
RCS file: java/org/apache/commons/httpclient/ExceptionUtils.java
diff -N java/org/apache/commons/httpclient/ExceptionUtils.java
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ java/org/apache/commons/httpclient/ExceptionUtils.java 13 May 2003 03:18:06 -0000
@@ -0,0 +1,285 @@
+/* ====================================================================
+ * The Apache Software License, Version 1.1
+ *
+ * Copyright (c) 2002-2003 The Apache Software Foundation. All rights
+ * reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ *
+ * 3. The end-user documentation included with the redistribution, if
+ * any, must include the following acknowlegement:
+ * "This product includes software developed by the
+ * Apache Software Foundation (http://www.apache.org/)."
+ * Alternately, this acknowlegement may appear in the software itself,
+ * if and wherever such third-party acknowlegements normally appear.
+ *
+ * 4. The names "The Jakarta Project", "Commons", and "Apache Software
+ * Foundation" must not be used to endorse or promote products derived
+ * from this software without prior written permission. For written
+ * permission, please contact apache@apache.org.
+ *
+ * 5. Products derived from this software may not be called "Apache"
+ * nor may "Apache" appear in their names without prior written
+ * permission of the Apache Software Foundation.
+ *
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
+ * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ * ====================================================================
+ *
+ * This software consists of voluntary contributions made by many
+ * individuals on behalf of the Apache Software Foundation. For more
+ * information on the Apache Software Foundation, please see
+ *
ExceptionUtils provides utilities for manipulating
+ * Throwable objects.
ExceptionUtils. Protected to
+ * discourage instantiation.
+ */
+ protected ExceptionUtils() {
+ }
+
+ /**
+ * Introspects the specified Throwable to obtain the cause.
The method searches for methods with specific names that return a
+ * Throwable object. This will pick up most wrapping exceptions,
+ * including those from JDK 1.4, and
+ * {@link org.apache.commons.lang.exception.NestableException NestableException}.
+ * The method names can be added to using {@link #addCauseMethodName(String)}.
+ * The default list searched for are:
getCause()
+ * getNextException()
+ * getTargetException()
+ * getException()
+ * getSourceException()
+ * getRootCause()
+ * getCausedByException()
+ * getNested()
+ * In the absence of any such method, the object is inspected for a
+ * detail field assignable to a Throwable.
If none of the above is found, returns null.
Throwable.
+ * @throws NullPointerException if the throwable is null
+ */
+ public static Throwable getCause(Throwable throwable) {
+ return getCause(throwable, CAUSE_METHOD_NAMES);
+ }
+
+ /**
+ * Introspects the specified Throwable to obtain the cause
+ * using a supplied array of method names.
Throwable.
+ * @throws NullPointerException if the method names array is null or contains null
+ * @throws NullPointerException if the throwable is null
+ */
+ public static Throwable getCause(Throwable throwable, String[] methodNames) {
+ Throwable cause = getCauseUsingWellKnownTypes(throwable);
+ if (cause == null) {
+ for (int i = 0; i < methodNames.length; i++) {
+ cause = getCauseUsingMethodName(throwable, methodNames[i]);
+ if (cause != null) {
+ break;
+ }
+ }
+
+ if (cause == null) {
+ cause = getCauseUsingFieldName(throwable, "detail");
+ }
+ }
+ return cause;
+ }
+
+ /**
+ * Uses instanceof checks to examine the exception,
+ * looking for well known types which could contain chained or
+ * wrapped exceptions.
null if not
+ * found.
+ */
+ private static Throwable getCauseUsingWellKnownTypes(Throwable throwable) {
+ if (throwable instanceof Nestable) {
+ return ((Nestable) throwable).getCause();
+ } else if (throwable instanceof SQLException) {
+ return ((SQLException) throwable).getNextException();
+ } else if (throwable instanceof InvocationTargetException) {
+ return ((InvocationTargetException) throwable).getTargetException();
+ } else {
+ return null;
+ }
+ }
+
+ /**
+ * Find a throwable by method name.
+ * + * @param throwable the exception to examine + * @param methodName the name of the method to find and invoke + * @return The wrapped exception, ornull if not
+ * found.
+ */
+ private static Throwable getCauseUsingMethodName(Throwable throwable, String methodName) {
+ Method method = null;
+ try {
+ method = throwable.getClass().getMethod(methodName, null);
+ } catch (NoSuchMethodException ignored) {
+ } catch (SecurityException ignored) {
+ }
+
+ if (method != null && Throwable.class.isAssignableFrom(method.getReturnType())) {
+ try {
+ return (Throwable) method.invoke(throwable, new Object[0]);
+ } catch (IllegalAccessException ignored) {
+ } catch (IllegalArgumentException ignored) {
+ } catch (InvocationTargetException ignored) {
+ }
+ }
+ return null;
+ }
+
+ /**
+ * Find a throwable by field name.
+ * + * @param throwable the exception to examine + * @param fieldName the name of the attribute to examine + * @return The wrapped exception, ornull if not
+ * found.
+ */
+ private static Throwable getCauseUsingFieldName(Throwable throwable, String fieldName) {
+ Field field = null;
+ try {
+ field = throwable.getClass().getField(fieldName);
+ } catch (NoSuchFieldException ignored) {
+ } catch (SecurityException ignored) {
+ }
+
+ if (field != null && Throwable.class.isAssignableFrom(field.getType())) {
+ try {
+ return (Throwable) field.get(throwable);
+ } catch (IllegalAccessException ignored) {
+ } catch (IllegalArgumentException ignored) {
+ }
+ }
+ return null;
+ }
+
+ /**
+ * A convenient way of extracting the stack trace from an
+ * exception.
+ *
+ * @param t The Throwable.
+ * @return The stack trace as generated by the exception's
+ * printStackTrace(PrintWriter) method.
+ */
+ public static String getStackTrace(Throwable t) {
+ StringWriter sw = new StringWriter();
+ PrintWriter pw = new PrintWriter(sw, true);
+ t.printStackTrace(pw);
+ return sw.getBuffer().toString();
+ }
+
+ /**
+ * Captures the stack trace associated with the specified
+ * Throwable object, decomposing it into a list of
+ * stack frames.
+ *
+ * @param t The Throwable.
+ * @return An array of strings describing each stack frame.
+ */
+ public static String[] getStackFrames(Throwable t) {
+ return getStackFrames(getStackTrace(t));
+ }
+
+ /**
+ * Functionality shared between the
+ * getStackFrames(Throwable) methods of this and the
+ * {@link org.apache.commons.lang.exception.NestableDelegate}
+ * classes.
+ */
+ static String[] getStackFrames(String stackTrace) {
+ String linebreak = System.getProperty("line.separator");
+ StringTokenizer frames = new StringTokenizer(stackTrace, linebreak);
+ List list = new LinkedList();
+ while (frames.hasMoreTokens()) {
+ list.add(frames.nextToken());
+ }
+ return (String[]) list.toArray(new String[] {
+ });
+ }
+
+}
Index: java/org/apache/commons/httpclient/HeaderElement.java
===================================================================
RCS file: /home/cvspublic/jakarta-commons/httpclient/src/java/org/apache/commons/httpclient/HeaderElement.java,v
retrieving revision 1.18
diff -u -r1.18 HeaderElement.java
--- java/org/apache/commons/httpclient/HeaderElement.java 14 Apr 2003 04:06:55 -0000 1.18
+++ java/org/apache/commons/httpclient/HeaderElement.java 13 May 2003 03:18:07 -0000
@@ -287,9 +287,8 @@
while (HeaderElement.hasOddNumberOfQuotationMarks(nextToken)) {
nextToken += "," + tokenizer.nextToken();
}
- } catch (NoSuchElementException exception) {
- throw new HttpException(
- "Bad header format: wrong number of quotation marks");
+ } catch (NoSuchElementException e) {
+ throw new HttpException("Bad header format: wrong number of quotation marks", e);
}
// FIXME: Refactor out into a private method named ?
@@ -321,9 +320,8 @@
nextToken += "," + tokenizer.nextToken();
}
}
- } catch (NoSuchElementException exception) {
- throw new HttpException
- ("Bad header format: parsing with wrong header elements");
+ } catch (NoSuchElementException e) {
+ throw new HttpException("Bad header format: parsing with wrong header elements", e);
}
String tmp = nextToken.trim();
Index: java/org/apache/commons/httpclient/HttpConnection.java
===================================================================
RCS file: /home/cvspublic/jakarta-commons/httpclient/src/java/org/apache/commons/httpclient/HttpConnection.java,v
retrieving revision 1.66
diff -u -r1.66 HttpConnection.java
--- java/org/apache/commons/httpclient/HttpConnection.java 12 May 2003 02:42:42 -0000 1.66
+++ java/org/apache/commons/httpclient/HttpConnection.java 13 May 2003 03:18:13 -0000
@@ -1312,7 +1312,7 @@
"Output exception occurred on a used connection. Will treat as recoverable.",
ioe
);
- return new HttpRecoverableException(ioe.toString());
+ return new HttpRecoverableException(ioe.toString(), ioe);
} else {
return ioe;
}
Index: java/org/apache/commons/httpclient/HttpException.java
===================================================================
RCS file: /home/cvspublic/jakarta-commons/httpclient/src/java/org/apache/commons/httpclient/HttpException.java,v
retrieving revision 1.13
diff -u -r1.13 HttpException.java
--- java/org/apache/commons/httpclient/HttpException.java 28 Jan 2003 04:40:20 -0000 1.13
+++ java/org/apache/commons/httpclient/HttpException.java 13 May 2003 03:18:15 -0000
@@ -83,6 +83,7 @@
*
*
* @author Unascribed
+ * @author Adrian Sutton
* @version $Revision: 1.13 $ $Date: 2003/01/28 04:40:20 $
*/
public class HttpException extends URIException {
@@ -101,5 +102,26 @@
*/
public HttpException(String message) {
super(message);
+ }
+
+ /**
+ * Creates a new HttpException with the specified cause.
+ *
+ * @param cause the original exception that caused this one to be
+ * thrown.
+ */
+ public HttpException(Throwable cause) {
+ super(cause);
+ }
+
+ /**
+ * Creates a new HttpException with the specified message and cause.
+ *
+ * @param message the exception message.
+ * @param cause the original exception that caused this one to be
+ * thrown.
+ */
+ public HttpException(String message, Throwable cause) {
+ super(message, cause);
}
}
Index: java/org/apache/commons/httpclient/HttpMethodBase.java
===================================================================
RCS file: /home/cvspublic/jakarta-commons/httpclient/src/java/org/apache/commons/httpclient/HttpMethodBase.java,v
retrieving revision 1.146
diff -u -r1.146 HttpMethodBase.java
--- java/org/apache/commons/httpclient/HttpMethodBase.java 12 May 2003 19:33:42 -0000 1.146
+++ java/org/apache/commons/httpclient/HttpMethodBase.java 13 May 2003 03:18:21 -0000
@@ -1209,7 +1209,8 @@
} catch (URIException e) {
LOG.warn("Error getting URI host", e);
throw new HttpException("Invalid Redirect URI from: "
- + currentUri.getEscapedURI() + " to: " + redirectUri.getEscapedURI()
+ + currentUri.getEscapedURI() + " to: " + redirectUri.getEscapedURI(),
+ e
);
}
@@ -1898,7 +1899,7 @@
readResponseBody(state, conn);
processResponseBody(state, conn);
} catch (IOException e) {
- throw new HttpRecoverableException(e.toString());
+ throw new HttpRecoverableException(e);
}
}
Index: java/org/apache/commons/httpclient/HttpRecoverableException.java
===================================================================
RCS file: /home/cvspublic/jakarta-commons/httpclient/src/java/org/apache/commons/httpclient/HttpRecoverableException.java,v
retrieving revision 1.7
diff -u -r1.7 HttpRecoverableException.java
--- java/org/apache/commons/httpclient/HttpRecoverableException.java 28 Jan 2003 22:25:21 -0000 1.7
+++ java/org/apache/commons/httpclient/HttpRecoverableException.java 13 May 2003 03:18:22 -0000
@@ -70,6 +70,7 @@
* may be retried.
*
* @author Unascribed
+ * @author Adrian Sutton
* @version $Revision: 1.7 $ $Date: 2003/01/28 22:25:21 $
*/
public class HttpRecoverableException extends HttpException {
@@ -89,5 +90,28 @@
*/
public HttpRecoverableException(String message) {
super(message);
+ }
+
+ /**
+ * Creates a new HttpRecoverableException with the specificied
+ * cause.
+ *
+ * @param cause the original exception that caused this one to be
+ * thrown.
+ */
+ public HttpRecoverableException(Throwable cause) {
+ super(cause);
+ }
+
+ /**
+ * Creates a new HttpRecoverableException with the specified message
+ * and cause.
+ *
+ * @param message the exception message.
+ * @param cause the original exception that caused this one to be
+ * thrown.
+ */
+ public HttpRecoverableException(String message, Throwable cause) {
+ super(message, cause);
}
}
Index: java/org/apache/commons/httpclient/NTLM.java
===================================================================
RCS file: /home/cvspublic/jakarta-commons/httpclient/src/java/org/apache/commons/httpclient/NTLM.java,v
retrieving revision 1.12
diff -u -r1.12 NTLM.java
--- java/org/apache/commons/httpclient/NTLM.java 11 Feb 2003 03:41:14 -0000 1.12
+++ java/org/apache/commons/httpclient/NTLM.java 13 May 2003 03:18:32 -0000
@@ -173,12 +173,11 @@
ecipher.init(Cipher.ENCRYPT_MODE, new SecretKeySpec(key, "DES"));
return ecipher;
} catch (NoSuchAlgorithmException e) {
- throw new HttpException("DES encryption is not available.");
+ throw new HttpException("DES encryption is not available.", e);
} catch (InvalidKeyException e) {
- throw new HttpException("Invalid key for DES encryption.");
+ throw new HttpException("Invalid key for DES encryption.", e);
} catch (NoSuchPaddingException e) {
- throw new HttpException(
- "NoPadding option for DES is not available.");
+ throw new HttpException("NoPadding option for DES is not available.", e);
}
}
@@ -224,10 +223,9 @@
byte[] enc = ecipher.doFinal(bytes);
return enc;
} catch (IllegalBlockSizeException e) {
- throw new HttpException("Invalid block size for DES encryption.");
+ throw new HttpException("Invalid block size for DES encryption.", e);
} catch (BadPaddingException e) {
- throw new HttpException(
- "Data not padded correctly for DES encryption.");
+ throw new HttpException("Data not padded correctly for DES encryption.", e);
}
}
Index: java/org/apache/commons/httpclient/Nestable.java
===================================================================
RCS file: java/org/apache/commons/httpclient/Nestable.java
diff -N java/org/apache/commons/httpclient/Nestable.java
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ java/org/apache/commons/httpclient/Nestable.java 13 May 2003 03:18:32 -0000
@@ -0,0 +1,117 @@
+/* ====================================================================
+ * The Apache Software License, Version 1.1
+ *
+ * Copyright (c) 2002-2003 The Apache Software Foundation. All rights
+ * reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ *
+ * 3. The end-user documentation included with the redistribution, if
+ * any, must include the following acknowlegement:
+ * "This product includes software developed by the
+ * Apache Software Foundation (http://www.apache.org/)."
+ * Alternately, this acknowlegement may appear in the software itself,
+ * if and wherever such third-party acknowlegements normally appear.
+ *
+ * 4. The names "The Jakarta Project", "Commons", and "Apache Software
+ * Foundation" must not be used to endorse or promote products derived
+ * from this software without prior written permission. For written
+ * permission, please contact apache@apache.org.
+ *
+ * 5. Products derived from this software may not be called "Apache"
+ * nor may "Apache" appear in their names without prior written
+ * permission of the Apache Software Foundation.
+ *
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
+ * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ * ====================================================================
+ *
+ * This software consists of voluntary contributions made by many
+ * individuals on behalf of the Apache Software Foundation. For more
+ * information on the Apache Software Foundation, please see
+ * Nestable to be thrown.
+ */
+ Throwable getCause();
+
+ /**
+ * Returns the error message of this and any nested
+ * Throwable.
+ *
+ * @return the error message
+ */
+ String getMessage();
+
+ /**
+ * Prints the stack trace of this exception to the specified print
+ * writer. Includes inforamation from the exception--if
+ * any--which caused this exception.
+ *
+ * @param out PrintWriter to use for output.
+ */
+ void printStackTrace(PrintWriter out);
+
+ /**
+ * Prints the stack trace of this exception to the specified print
+ * stream. Includes inforamation from the exception--if
+ * any--which caused this exception.
+ *
+ * @param out PrintStream to use for output.
+ */
+ void printStackTrace(PrintStream out);
+
+ /**
+ * Prints the stack trace for this exception only--root cause not
+ * included--using the provided writer. Used by {@link
+ * org.apache.commons.lang.exception.NestableDelegate} to write
+ * individual stack traces to a buffer. The implementation of
+ * this method should call
+ * super.printStackTrace(out); in most cases.
+ *
+ * @param out The writer to use.
+ */
+ void printPartialStackTrace(PrintWriter out);
+}
Index: java/org/apache/commons/httpclient/NestableDelegate.java
===================================================================
RCS file: java/org/apache/commons/httpclient/NestableDelegate.java
diff -N java/org/apache/commons/httpclient/NestableDelegate.java
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ java/org/apache/commons/httpclient/NestableDelegate.java 13 May 2003 03:18:33 -0000
@@ -0,0 +1,217 @@
+/* ====================================================================
+ * The Apache Software License, Version 1.1
+ *
+ * Copyright (c) 2002-2003 The Apache Software Foundation. All rights
+ * reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ *
+ * 3. The end-user documentation included with the redistribution, if
+ * any, must include the following acknowlegement:
+ * "This product includes software developed by the
+ * Apache Software Foundation (http://www.apache.org/)."
+ * Alternately, this acknowlegement may appear in the software itself,
+ * if and wherever such third-party acknowlegements normally appear.
+ *
+ * 4. The names "The Jakarta Project", "Commons", and "Apache Software
+ * Foundation" must not be used to endorse or promote products derived
+ * from this software without prior written permission. For written
+ * permission, please contact apache@apache.org.
+ *
+ * 5. Products derived from this software may not be called "Apache"
+ * nor may "Apache" appear in their names without prior written
+ * permission of the Apache Software Foundation.
+ *
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
+ * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ * ====================================================================
+ *
+ * This software consists of voluntary contributions made by many
+ * individuals on behalf of the Apache Software Foundation. For more
+ * information on the Apache Software Foundation, please see
+ * NestableDelegate is a shared implementation of the nestable
+ * exception functionality.
+ *
+ * The code is shared between
+ * {@link org.apache.commons.lang.exception.NestableError NestableError},
+ * {@link org.apache.commons.lang.exception.NestableException NestableException} and
+ * {@link org.apache.commons.lang.exception.NestableRuntimeException NestableRuntimeException}.
+ *
+ * @author Rafal Krzewski
+ * @author Daniel Rall
+ * @author Kasper Nielsen
+ * @author Steven Caswell
+ * @author Sean C. Sullivan
+ * @author Stephen Colebourne
+ * @since 2.0 beta1
+ * @version $Id: $
+ */
+class NestableDelegate implements java.io.Serializable {
+
+ /**
+ * Constructor error message.
+ */
+ private transient static final String MUST_BE_THROWABLE =
+ "The Nestable implementation passed to the NestableDelegate(Nestable) "
+ + "constructor must extend java.lang.Throwable";
+
+ /**
+ * Holds the reference to the exception or error that we're
+ * wrapping (which must be a {@link
+ * org.apache.commons.lang.exception.Nestable} implementation).
+ */
+ private Throwable nestable = null;
+
+ /**
+ * Constructs a new NestableDelegate instance to manage the
+ * specified Nestable.
+ *
+ * @param nestable the Nestable implementation (must extend
+ * {@link java.lang.Throwable})
+ */
+ NestableDelegate(Nestable nestable) {
+ if (nestable instanceof Throwable) {
+ this.nestable = (Throwable) nestable;
+ } else {
+ throw new IllegalArgumentException(MUST_BE_THROWABLE);
+ }
+ }
+
+ /**
+ * Returns the full message contained by the Nestable
+ * and any nested Throwables.
+ *
+ * @param baseMsg the base message to use when creating the full
+ * message. Should be generally be called via
+ * nestableHelper.getMessage(super.getMessage()),
+ * where super is an instance of {@link
+ * java.lang.Throwable}.
+ * @return The concatenated message for this and all nested
+ * Throwables
+ */
+ String getMessage(String baseMsg) {
+ StringBuffer msg = new StringBuffer();
+ if (baseMsg != null) {
+ msg.append(baseMsg);
+ }
+
+ Throwable nestedCause = ExceptionUtils.getCause(this.nestable);
+ if (nestedCause != null) {
+ String causeMsg = nestedCause.getMessage();
+ if (causeMsg != null) {
+ if (baseMsg != null) {
+ msg.append(": ");
+ }
+ msg.append(causeMsg);
+ }
+
+ }
+ return (msg.length() > 0 ? msg.toString() : null);
+ }
+
+ /**
+ * Prints the stack trace of this exception the the standar error
+ * stream.
+ */
+ public void printStackTrace() {
+ printStackTrace(System.err);
+ }
+
+ /**
+ * Prints the stack trace of this exception to the specified
+ * stream.
+ *
+ * @param out PrintStream to use for output.
+ * @see #printStackTrace(PrintWriter)
+ */
+ public void printStackTrace(PrintStream out) {
+ synchronized (out) {
+ PrintWriter pw = new PrintWriter(out, false);
+ printStackTrace(pw);
+ // Flush the PrintWriter before it's GC'ed.
+ pw.flush();
+ }
+ }
+
+ /**
+ * Prints the stack trace of this exception to the specified
+ * writer.
+ *
+ * @param out PrintWriter to use for output.
+ */
+ public void printStackTrace(PrintWriter out) {
+ synchronized (out) {
+ String[] st = getStackFrames(this.nestable);
+ Throwable nestedCause = ExceptionUtils.getCause(this.nestable);
+ if (nestedCause != null) {
+ if (nestedCause instanceof Nestable) {
+ // Recurse until a non-Nestable is encountered.
+ ((Nestable) nestedCause).printStackTrace(out);
+ } else {
+ String[] nst = getStackFrames(nestedCause);
+ for (int i = 0; i < nst.length; i++) {
+ out.println(nst[i]);
+ }
+ }
+ out.print("rethrown as ");
+ }
+
+ // Output desired frames from stack trace.
+ for (int i = 0; i < st.length; i++) {
+ out.println(st[i]);
+ }
+ }
+ }
+
+ /**
+ * Captures the stack trace associated with the specified
+ * Throwable object, decomposing it into a list of
+ * stack frames.
+ *
+ * @param t The Throwable.
+ * @return An array of strings describing each stack frame.
+ */
+ private String[] getStackFrames(Throwable t) {
+ StringWriter sw = new StringWriter();
+ PrintWriter pw = new PrintWriter(sw, true);
+
+ // Avoid infinite loop between decompose() and printStackTrace().
+ if (t instanceof Nestable) {
+ ((Nestable) t).printPartialStackTrace(pw);
+ } else {
+ t.printStackTrace(pw);
+ }
+ return ExceptionUtils.getStackFrames(sw.getBuffer().toString());
+ }
+}
Index: java/org/apache/commons/httpclient/StatusLine.java
===================================================================
RCS file: /home/cvspublic/jakarta-commons/httpclient/src/java/org/apache/commons/httpclient/StatusLine.java,v
retrieving revision 1.9
diff -u -r1.9 StatusLine.java
--- java/org/apache/commons/httpclient/StatusLine.java 1 Apr 2003 00:25:24 -0000 1.9
+++ java/org/apache/commons/httpclient/StatusLine.java 13 May 2003 03:18:35 -0000
@@ -149,8 +149,8 @@
this.statusCode = Integer.parseInt(statusLine.substring(at, to));
} catch (NumberFormatException e) {
throw new HttpException(
- "Unable to parse status code from status line: '"
- + statusLine + "'");
+ "Unable to parse status code from status line: '" + statusLine + "'",
+ e);
}
//handle the Reason-Phrase
@@ -162,8 +162,7 @@
this.reasonPhrase = "";
}
} catch (StringIndexOutOfBoundsException e) {
- throw new HttpException("Status text not specified: '"
- + statusLine + "'");
+ throw new HttpException("Status text not specified: '" + statusLine + "'", e);
}
}
Index: java/org/apache/commons/httpclient/URI.java
===================================================================
RCS file: /home/cvspublic/jakarta-commons/httpclient/src/java/org/apache/commons/httpclient/URI.java,v
retrieving revision 1.34
diff -u -r1.34 URI.java
--- java/org/apache/commons/httpclient/URI.java 5 Mar 2003 03:47:25 -0000 1.34
+++ java/org/apache/commons/httpclient/URI.java 13 May 2003 03:18:43 -0000
@@ -73,7 +73,7 @@
import java.util.Hashtable;
import java.net.URL;
import java.security.AccessController;
-import sun.security.action.GetPropertyAction;
+import java.security.PrivilegedAction;
/**
* The interface for the URI(Uniform Resource Identifiers) version of RFC 2396.
@@ -617,9 +617,13 @@
defaultDocumentCharset = defaultDocumentCharsetByLocale;
}
// in order to support platform encoding
- defaultDocumentCharsetByPlatform =
- (String) AccessController.doPrivileged(
- new GetPropertyAction("file.encoding"));
+ defaultDocumentCharsetByPlatform = (String) AccessController.doPrivileged(
+ new PrivilegedAction() {
+ public Object run() {
+ return System.getProperty("file.encoding");
+ }
+ }
+ );
if (defaultDocumentCharset == null) {
// set the default document charset
defaultDocumentCharset = defaultDocumentCharsetByPlatform;
@@ -1664,7 +1668,7 @@
try {
octets = original.getBytes(charset);
} catch (UnsupportedEncodingException error) {
- throw new URIException(URIException.UNSUPPORTED_ENCODING, charset);
+ throw new URIException(URIException.UNSUPPORTED_ENCODING, charset, error);
}
StringBuffer buf = new StringBuffer(octets.length);
for (int i = 0; i < octets.length; i++) {
@@ -1752,7 +1756,7 @@
result = new String(octets, 0, oi, charset);
} catch (UnsupportedEncodingException error) {
throw new URIException(URIException.UNSUPPORTED_ENCODING,
- "not supported " + charset + " encoding");
+ "not supported " + charset + " encoding", error);
}
return result;
@@ -2214,7 +2218,7 @@
_port = Integer.parseInt(original.substring(from));
} catch (NumberFormatException error) {
throw new URIException(URIException.PARSING,
- "invalid port number");
+ "invalid port number", error);
}
}
// set a server-based naming authority
Index: java/org/apache/commons/httpclient/URIException.java
===================================================================
RCS file: /home/cvspublic/jakarta-commons/httpclient/src/java/org/apache/commons/httpclient/URIException.java,v
retrieving revision 1.8
diff -u -r1.8 URIException.java
--- java/org/apache/commons/httpclient/URIException.java 31 Jan 2003 00:33:36 -0000 1.8
+++ java/org/apache/commons/httpclient/URIException.java 13 May 2003 03:18:43 -0000
@@ -64,6 +64,8 @@
package org.apache.commons.httpclient;
import java.io.IOException;
+import java.io.PrintStream;
+import java.io.PrintWriter;
/**
* The URI parsing and escape encoding exception.
@@ -73,9 +75,10 @@
*
*
* @author Sung-Gu
+ * @author Adrian Sutton
* @version $Revision: 1.8 $ $Date: 2002/03/14 15:14:01
*/
-public class URIException extends IOException {
+public class URIException extends IOException implements Nestable {
// ----------------------------------------------------------- constructors
@@ -85,7 +88,6 @@
public URIException() {
}
-
/**
* The constructor with a reason code argument.
*
@@ -95,7 +97,6 @@
setReasonCode(reasonCode);
}
-
/**
* The constructor with a reason string and its code arguments.
*
@@ -103,23 +104,55 @@
* @param reason the reason
*/
public URIException(int reasonCode, String reason) {
- super(reason); // for backward compatibility of Throwable
+ super(reason);
this.reason = reason;
setReasonCode(reasonCode);
}
-
/**
* The constructor with a reason string argument.
*
* @param reason the reason
*/
public URIException(String reason) {
- super(reason); // for backward compatibility of Throwable
+ super(reason);
this.reason = reason;
setReasonCode(UNKNOWN);
}
+ /**
+ * The constructor with a cause argument.
+ *
+ * @param cause the original exception that caused this exception.
+ */
+ public URIException(Throwable cause) {
+ super();
+ this.cause = cause;
+ }
+
+ /**
+ * The constructor with a reason string and throwable cause.
+ *
+ * @param reason the reason the exception was thrown.
+ * @param cause the original exception that caused this exception.
+ */
+ public URIException(String reason, Throwable cause) {
+ this(reason);
+ this.cause = cause;
+ }
+
+ /**
+ * The constructor with a reason code, string and throwable cause.
+ *
+ * @param reasonCode the reason code.
+ * @param reason the reason this exception was thrown.
+ * @param cause the original exception that caused this exception.
+ */
+ public URIException(int reasonCode, String reason, Throwable cause) {
+ this(reasonCode, reason);
+ this.cause = cause;
+ }
+
// -------------------------------------------------------------- constants
/**
@@ -164,6 +197,16 @@
*/
protected String reason;
+ /**
+ * The original exception that caused this one.
+ */
+ private Throwable cause;
+
+ /**
+ * The delegate for handling printing stack traces, etc.
+ */
+ private NestableDelegate delegate = new NestableDelegate(this);
+
// ---------------------------------------------------------------- methods
/**
@@ -185,7 +228,6 @@
this.reasonCode = reasonCode;
}
-
/**
* Get the reason message.
*
@@ -195,7 +237,6 @@
return reason;
}
-
/**
* Set the reason message.
*
@@ -205,6 +246,78 @@
this.reason = reason;
}
+ /**
+ * Returns the original exception that caused this
+ * exception to be thrown.
+ *
+ * @return the Throwable that caused this exception.
+ */
+ public Throwable getCause() {
+ return cause;
+ }
+
+ /**
+ * Sets the cause of this exception.
+ *
+ * @param cause the original exception that caused this one.
+ */
+ public void setCause(Throwable cause) {
+ this.cause = cause;
+ }
+
+ /**
+ * Prints the stack trace for this exception only--root cause not
+ * included--using the provided writer. Used by {@link
+ * org.apache.commons.lang.exception.NestableDelegate} to write
+ * individual stack traces to a buffer. The implementation of
+ * this method should call
+ * super.printStackTrace(out); in most cases.
+ *
+ * @param out The writer to use.
+ */
+ public void printPartialStackTrace(PrintWriter out) {
+ super.printStackTrace();
+ }
+
+ /**
+ * Returns the error message of this and any nested
+ * Throwable.
+ *
+ * @return the error message
+ */
+ public String getMessage() {
+ return delegate.getMessage(super.getMessage());
+ }
+
+ /**
+ * Prints the stack trace of this exception to System.err.
+ * Includes information from the exception--if any--which caused this exception.
+ */
+ public void printStackTrace() {
+ delegate.printStackTrace();
+ }
+
+ /**
+ * Prints the stack trace of this exception to the specified print
+ * stream. Includes information from the exception--if
+ * any--which caused this exception.
+ *
+ * @param out PrintStream to use for output.
+ */
+ public void printStackTrace(PrintStream out) {
+ delegate.printStackTrace(out);
+ }
+
+ /**
+ * Prints the stack trace of this exception to the specified print
+ * writer. Includes information from the exception--if
+ * any--which caused this exception.
+ *
+ * @param out PrintWriter to use for output.
+ */
+ public void printStackTrace(PrintWriter out) {
+ delegate.printStackTrace(out);
+ }
}
Index: java/org/apache/commons/httpclient/auth/AuthenticationException.java
===================================================================
RCS file: /home/cvspublic/jakarta-commons/httpclient/src/java/org/apache/commons/httpclient/auth/AuthenticationException.java,v
retrieving revision 1.2
diff -u -r1.2 AuthenticationException.java
--- java/org/apache/commons/httpclient/auth/AuthenticationException.java 6 Apr 2003 22:31:53 -0000 1.2
+++ java/org/apache/commons/httpclient/auth/AuthenticationException.java 13 May 2003 03:18:47 -0000
@@ -86,5 +86,19 @@
*/
public AuthenticationException(String message) {
super(message);
+ }
+
+ /**
+ * @see HttpException#HttpException(Throwable)
+ */
+ public AuthenticationException(Throwable cause) {
+ super(cause);
+ }
+
+ /**
+ * @see HttpException#HttpException(String, Throwable)
+ */
+ public AuthenticationException(String message, Throwable cause) {
+ super(message, cause);
}
}
Index: java/org/apache/commons/httpclient/auth/BasicScheme.java
===================================================================
RCS file: /home/cvspublic/jakarta-commons/httpclient/src/java/org/apache/commons/httpclient/auth/BasicScheme.java,v
retrieving revision 1.3
diff -u -r1.3 BasicScheme.java
--- java/org/apache/commons/httpclient/auth/BasicScheme.java 6 Apr 2003 22:31:53 -0000 1.3
+++ java/org/apache/commons/httpclient/auth/BasicScheme.java 13 May 2003 03:18:47 -0000
@@ -135,7 +135,7 @@
} catch (ClassCastException e) {
throw new AuthenticationException(
"Credentials cannot be used for basic authentication: "
- + credentials.toString());
+ + credentials.toString(), e);
}
return BasicScheme.authenticate(usernamepassword);
}
Index: java/org/apache/commons/httpclient/auth/DigestScheme.java
===================================================================
RCS file: /home/cvspublic/jakarta-commons/httpclient/src/java/org/apache/commons/httpclient/auth/DigestScheme.java,v
retrieving revision 1.3
diff -u -r1.3 DigestScheme.java
--- java/org/apache/commons/httpclient/auth/DigestScheme.java 6 Apr 2003 22:31:53 -0000 1.3
+++ java/org/apache/commons/httpclient/auth/DigestScheme.java 13 May 2003 03:18:48 -0000
@@ -154,7 +154,7 @@
} catch (ClassCastException e) {
throw new AuthenticationException(
"Credentials cannot be used for basic authentication: "
- + credentials.toString());
+ + credentials.toString(), e);
}
this.getParameters().put("cnonce", createCnonce());
this.getParameters().put("methodname", method);
@@ -230,7 +230,7 @@
} catch (Exception e) {
throw new AuthenticationException(
"Unsupported algorithm in HTTP Digest authentication: "
- + digAlg);
+ + digAlg, e);
}
// Calculating digest according to rfc 2617
@@ -346,7 +346,7 @@
} catch (Exception e) {
throw new AuthenticationException(
"Unsupported algorithm in HTTP Digest authentication: "
- + digAlg);
+ + digAlg, e);
}
cnonce = Long.toString(System.currentTimeMillis());
Index: java/org/apache/commons/httpclient/auth/MalformedChallengeException.java
===================================================================
RCS file: /home/cvspublic/jakarta-commons/httpclient/src/java/org/apache/commons/httpclient/auth/MalformedChallengeException.java,v
retrieving revision 1.2
diff -u -r1.2 MalformedChallengeException.java
--- java/org/apache/commons/httpclient/auth/MalformedChallengeException.java 6 Apr 2003 22:31:53 -0000 1.2
+++ java/org/apache/commons/httpclient/auth/MalformedChallengeException.java 13 May 2003 03:18:49 -0000
@@ -88,4 +88,19 @@
public MalformedChallengeException(String message) {
super(message);
}
+
+ /**
+ * @see HttpException#HttpException(Throwable)
+ */
+ public MalformedChallengeException(Throwable cause) {
+ super(cause);
+ }
+
+ /**
+ * @see HttpException#HttpException(String, Throwable)
+ */
+ public MalformedChallengeException(String message, Throwable cause) {
+ super(message, cause);
+ }
+
}
Index: java/org/apache/commons/httpclient/auth/NTLMScheme.java
===================================================================
RCS file: /home/cvspublic/jakarta-commons/httpclient/src/java/org/apache/commons/httpclient/auth/NTLMScheme.java,v
retrieving revision 1.4
diff -u -r1.4 NTLMScheme.java
--- java/org/apache/commons/httpclient/auth/NTLMScheme.java 22 Apr 2003 17:00:25 -0000 1.4
+++ java/org/apache/commons/httpclient/auth/NTLMScheme.java 13 May 2003 03:18:50 -0000
@@ -196,7 +196,7 @@
credentials.getUserName(), credentials.getPassword(),
credentials.getHost(), credentials.getDomain());
} catch (HttpException e) {
- throw new AuthenticationException(e.getMessage());
+ throw new AuthenticationException(e);
}
return "NTLM " + s;
}
@@ -223,7 +223,7 @@
} catch (ClassCastException e) {
throw new AuthenticationException(
"Credentials cannot be used for basic authentication: "
- + credentials.toString());
+ + credentials.toString(), e);
}
return NTLMScheme.authenticate(ntcredentials, this.ntlmchallenge);
}
Index: java/org/apache/commons/httpclient/cookie/CookieSpecBase.java
===================================================================
RCS file: /home/cvspublic/jakarta-commons/httpclient/src/java/org/apache/commons/httpclient/cookie/CookieSpecBase.java,v
retrieving revision 1.14
diff -u -r1.14 CookieSpecBase.java
--- java/org/apache/commons/httpclient/cookie/CookieSpecBase.java 17 Apr 2003 03:00:31 -0000 1.14
+++ java/org/apache/commons/httpclient/cookie/CookieSpecBase.java 13 May 2003 03:18:53 -0000
@@ -171,7 +171,7 @@
try {
headerElements = HeaderElement.parse(header);
} catch (HttpException e) {
- throw new MalformedCookieException(e.getMessage());
+ throw new MalformedCookieException(e);
}
String defaultPath = path;
@@ -312,8 +312,7 @@
try {
age = Integer.parseInt(paramValue);
} catch (NumberFormatException e) {
- throw new MalformedCookieException ("Invalid max-age "
- + "attribute: " + e.getMessage());
+ throw new MalformedCookieException ("Invalid max-age attribute.", e);
}
cookie.setExpiryDate(
new Date(System.currentTimeMillis() + age * 1000L));
@@ -347,7 +346,7 @@
LOG.debug("Error parsing cookie date", dpe);
throw new MalformedCookieException(
"Unable to parse expiration date parameter: "
- + paramValue);
+ + paramValue, dpe);
}
} else {
if (LOG.isDebugEnabled()) {
Index: java/org/apache/commons/httpclient/cookie/MalformedCookieException.java
===================================================================
RCS file: /home/cvspublic/jakarta-commons/httpclient/src/java/org/apache/commons/httpclient/cookie/MalformedCookieException.java,v
retrieving revision 1.4
diff -u -r1.4 MalformedCookieException.java
--- java/org/apache/commons/httpclient/cookie/MalformedCookieException.java 27 Jan 2003 15:25:47 -0000 1.4
+++ java/org/apache/commons/httpclient/cookie/MalformedCookieException.java 13 May 2003 03:18:53 -0000
@@ -88,4 +88,19 @@
public MalformedCookieException(String message) {
super(message);
}
+
+ /**
+ * @see HttpException#HttpException(Throwable)
+ */
+ public MalformedCookieException(Throwable cause) {
+ super(cause);
+ }
+
+ /**
+ * @see HttpException#HttpException(String, Throwable)
+ */
+ public MalformedCookieException(String message, Throwable cause) {
+ super(message, cause);
+ }
+
}
Index: java/org/apache/commons/httpclient/cookie/NetscapeDraftSpec.java
===================================================================
RCS file: /home/cvspublic/jakarta-commons/httpclient/src/java/org/apache/commons/httpclient/cookie/NetscapeDraftSpec.java,v
retrieving revision 1.7
diff -u -r1.7 NetscapeDraftSpec.java
--- java/org/apache/commons/httpclient/cookie/NetscapeDraftSpec.java 28 Jan 2003 04:40:23 -0000 1.7
+++ java/org/apache/commons/httpclient/cookie/NetscapeDraftSpec.java 13 May 2003 03:18:54 -0000
@@ -131,8 +131,7 @@
Date date = expiryFormat.parse(paramValue);
cookie.setExpiryDate(date);
} catch (ParseException e) {
- throw new MalformedCookieException("Invalid expires "
- + "attribute: " + e.getMessage());
+ throw new MalformedCookieException("Invalid expires attribute.", e);
}
} else {
super.parseAttribute(attribute, cookie);
Index: java/org/apache/commons/httpclient/cookie/RFC2109Spec.java
===================================================================
RCS file: /home/cvspublic/jakarta-commons/httpclient/src/java/org/apache/commons/httpclient/cookie/RFC2109Spec.java,v
retrieving revision 1.13
diff -u -r1.13 RFC2109Spec.java
--- java/org/apache/commons/httpclient/cookie/RFC2109Spec.java 7 Mar 2003 18:23:46 -0000 1.13
+++ java/org/apache/commons/httpclient/cookie/RFC2109Spec.java 13 May 2003 03:18:54 -0000
@@ -122,8 +122,7 @@
try {
cookie.setVersion(Integer.parseInt(paramValue));
} catch (NumberFormatException e) {
- throw new MalformedCookieException("Invalid version: "
- + e.getMessage());
+ throw new MalformedCookieException("Invalid version", e);
}
} else {
Index: java/org/apache/commons/httpclient/util/URIUtil.java
===================================================================
RCS file: /home/cvspublic/jakarta-commons/httpclient/src/java/org/apache/commons/httpclient/util/URIUtil.java,v
retrieving revision 1.20
diff -u -r1.20 URIUtil.java
--- java/org/apache/commons/httpclient/util/URIUtil.java 19 Apr 2003 22:29:32 -0000 1.20
+++ java/org/apache/commons/httpclient/util/URIUtil.java 13 May 2003 03:19:11 -0000
@@ -671,7 +671,7 @@
return new String(target.getBytes(fromCharset), toCharset);
} catch (UnsupportedEncodingException error) {
throw new URIException(URIException.UNSUPPORTED_ENCODING,
- error.getMessage());
+ error.getMessage(), error);
}
}
Index: test/org/apache/commons/httpclient/TestHttpException.java
===================================================================
RCS file: test/org/apache/commons/httpclient/TestHttpException.java
diff -N test/org/apache/commons/httpclient/TestHttpException.java
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ test/org/apache/commons/httpclient/TestHttpException.java 13 May 2003 03:19:23 -0000
@@ -0,0 +1,176 @@
+/*
+ * $Header: $
+ * $Revision: $
+ * $Date: $
+ *
+ * ====================================================================
+ *
+ * The Apache Software License, Version 1.1
+ *
+ * Copyright (c) 1999-2003 The Apache Software Foundation. All rights
+ * reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ *
+ * 3. The end-user documentation included with the redistribution, if
+ * any, must include the following acknowlegement:
+ * "This product includes software developed by the
+ * Apache Software Foundation (http://www.apache.org/)."
+ * Alternately, this acknowlegement may appear in the software itself,
+ * if and wherever such third-party acknowlegements normally appear.
+ *
+ * 4. The names "The Jakarta Project", "Commons", and "Apache Software
+ * Foundation" must not be used to endorse or promote products derived
+ * from this software without prior written permission. For written
+ * permission, please contact apache@apache.org.
+ *
+ * 5. Products derived from this software may not be called "Apache"
+ * nor may "Apache" appear in their names without prior written
+ * permission of the Apache Group.
+ *
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
+ * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ * ====================================================================
+ *
+ * This software consists of voluntary contributions made by many
+ * individuals on behalf of the Apache Software Foundation. For more
+ * information on the Apache Software Foundation, please see
+ *