You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@commons.apache.org by jo...@apache.org on 2009/08/09 19:46:13 UTC
svn commit: r802566 - in /commons/proper/lang/trunk/src:
java/org/apache/commons/lang/exception/
test/org/apache/commons/lang/exception/
Author: joehni
Date: Sun Aug 9 17:46:13 2009
New Revision: 802566
URL: http://svn.apache.org/viewvc?rev=802566&view=rev
Log:
Add ExceptionContext package (LANG-497, contributed by Derek Ashmore).
Added:
commons/proper/lang/trunk/src/java/org/apache/commons/lang/exception/ContextedException.java (with props)
commons/proper/lang/trunk/src/java/org/apache/commons/lang/exception/ContextedRuntimeException.java (with props)
commons/proper/lang/trunk/src/java/org/apache/commons/lang/exception/DefaultExceptionContext.java (with props)
commons/proper/lang/trunk/src/java/org/apache/commons/lang/exception/ExceptionContext.java (with props)
commons/proper/lang/trunk/src/test/org/apache/commons/lang/exception/ContextedExceptionTest.java (with props)
commons/proper/lang/trunk/src/test/org/apache/commons/lang/exception/ContextedRuntimeExceptionTest.java (with props)
commons/proper/lang/trunk/src/test/org/apache/commons/lang/exception/DefaultExceptionContextTest.java (with props)
Modified:
commons/proper/lang/trunk/src/java/org/apache/commons/lang/exception/ExceptionUtils.java
commons/proper/lang/trunk/src/java/org/apache/commons/lang/exception/package.html
Added: commons/proper/lang/trunk/src/java/org/apache/commons/lang/exception/ContextedException.java
URL: http://svn.apache.org/viewvc/commons/proper/lang/trunk/src/java/org/apache/commons/lang/exception/ContextedException.java?rev=802566&view=auto
==============================================================================
--- commons/proper/lang/trunk/src/java/org/apache/commons/lang/exception/ContextedException.java (added)
+++ commons/proper/lang/trunk/src/java/org/apache/commons/lang/exception/ContextedException.java Sun Aug 9 17:46:13 2009
@@ -0,0 +1,184 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.commons.lang.exception;
+
+import java.io.Serializable;
+import java.util.Set;
+
+/**
+ * Provides an easier and safer way for developers to provide context when
+ * generating checked exceptions. Often, additional information, besides what's
+ * embedded in the exception cause, is needed for developers to debug and correct
+ * a bug. Often, this additional information can reduce the time it takes
+ * to replicate and fix a bug.
+ *
+ * <p>ContextedException is easier as developers don't need to be concerned
+ * with formatting the exception message to include additional information
+ * with the exception. Additional information is automatically included
+ * in the message and printed stack trace. This often thins out exception
+ * handling code.</p>
+ *
+ * <p>ContextedException is safer as the additional code needed to embed additional
+ * information in a normal exception tends to be tested less and is more vulnerable
+ * to errors such as null pointer exceptions.</p>
+ *
+ * <p>An unchecked version of this exception is provided by ContextedRuntimeException.</p>
+ *
+ * <p>To use this class write code as follows:</p>
+ *
+ * <pre>
+ * try {
+ *
+ * ...
+ *
+ * } catch (Throwable e) {
+ * throw new ContextedException("Error posting account transaction", e)
+ * .addLabeledValue("accountNumber", accountNumber)
+ * .addLabeledValue("amountPosted", amountPosted)
+ * .addLabeledValue("previousBalance", previousBalance)
+ * }
+ * }
+ * </pre>
+ *
+ * <p>The output in a printStacktrace() (which often is written to a log) would look something like the following:
+ * <pre>
+ * org.apache.commons.lang.exception.ContextedException: java.lang.Exception: Error posting account transaction
+ * Exception Context:
+ * [accountNumber=null]
+ * [amountPosted=100.00]
+ * [previousBalance=-2.17]
+ *
+ * ---------------------------------
+ * at org.apache.commons.lang.exception.ContextedExceptionTest.testAddLabeledValue(ContextedExceptionTest.java:88)
+ * ..... (rest of trace)
+ * </pre>
+ *
+ * @see ContextedRuntimeException
+ * @author D. Ashmore
+ * @since 3.0
+ *
+ */
+public class ContextedException extends Exception implements ExceptionContext {
+
+ private static final long serialVersionUID = 8940917952810290164L;
+ private ExceptionContext exceptionContext = new DefaultExceptionContext();
+
+ /**
+ * Instantiates ContextedException without message or cause.
+ * <p>DefaultExceptionContext used to store and format context information.</p>
+ */
+ public ContextedException() {
+ }
+
+ /**
+ * Instantiates ContextedException with message, but without cause.
+ * <p>DefaultExceptionContext used to store and format context information.</p>
+ * @param message The exception message
+ */
+ public ContextedException(String message) {
+ super(message);
+ }
+
+ /**
+ * Instantiates ContextedException with cause, but without message.
+ * <p>DefaultExceptionContext used to store and format context information.</p>
+ * @param cause Exception creating need for ContextedException
+ */
+ public ContextedException(Throwable cause) {
+ super(cause);
+ }
+
+ /**
+ * Instantiates ContextedException with cause and message.
+ * <p>DefaultExceptionContext used to store and format context information.</p>
+ * @param message The exception message
+ * @param cause Exception creating need for ContextedException
+ */
+ public ContextedException(String message, Throwable cause) {
+ super(message, cause);
+ }
+
+ /**
+ * Instantiates ContextedException with cause, message, and ExceptionContext.
+ * @param message The exception message
+ * @param cause Exception creating need for ContextedException
+ * @param context Context used to store additional information
+ * @since 3.0
+ */
+ public ContextedException(String message, Throwable cause, ExceptionContext context) {
+ super(message, cause);
+ if (context != null) {
+ this.exceptionContext = context;
+ }
+ }
+
+ /**
+ * Adds information helpful to a developer in diagnosing and correcting
+ * the problem. For the information to be meaningful, the value passed
+ * should have a reasonable toString() implementation.
+ *
+ * <p>Note: If the value provided isn't Serializable, one solution would be
+ * to provide its toString() if it has a meaningful implementation or
+ * individual properties of the value object instead.</p>
+ * @param label a textual label associated with information
+ * @param value information needed to understand exception. May be <code>null</code>.
+ * @return this
+ * @since 3.0
+ */
+ public ContextedException addLabeledValue(String label, Serializable value) {
+ this.exceptionContext.addLabeledValue(label, value);
+
+ return this;
+ }
+
+ /**
+ * Convenience method to retrieve a value from the underlying ExceptionContext.
+ * @param label a textual label associated with information
+ * @return value information needed to understand exception. May be <code>null</code>.
+ * @since 3.0
+ */
+ public Serializable getLabeledValue(String label) {
+ return this.exceptionContext.getLabeledValue(label);
+ }
+
+ /**
+ * Convenience method to retrieve currently defined labels from the underlying ExceptionContext.
+ * @return labelSet
+ * @since 3.0
+ */
+ public Set<String> getLabelSet() {
+ return this.exceptionContext.getLabelSet();
+ }
+
+ /**
+ * Provides message pertaining to exception.
+ * @see java.lang.Throwable#getMessage()
+ * @return message
+ * @since 3.0
+ */
+ @Override
+ public String getMessage(){
+ return getFormattedExceptionMessage(super.getMessage());
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public String getFormattedExceptionMessage(String baseMessage) {
+ return this.exceptionContext.getFormattedExceptionMessage(baseMessage);
+ }
+}
Propchange: commons/proper/lang/trunk/src/java/org/apache/commons/lang/exception/ContextedException.java
------------------------------------------------------------------------------
svn:eol-style = native
Propchange: commons/proper/lang/trunk/src/java/org/apache/commons/lang/exception/ContextedException.java
------------------------------------------------------------------------------
svn:keywords = Author Date Id HeadURL Revision
Added: commons/proper/lang/trunk/src/java/org/apache/commons/lang/exception/ContextedRuntimeException.java
URL: http://svn.apache.org/viewvc/commons/proper/lang/trunk/src/java/org/apache/commons/lang/exception/ContextedRuntimeException.java?rev=802566&view=auto
==============================================================================
--- commons/proper/lang/trunk/src/java/org/apache/commons/lang/exception/ContextedRuntimeException.java (added)
+++ commons/proper/lang/trunk/src/java/org/apache/commons/lang/exception/ContextedRuntimeException.java Sun Aug 9 17:46:13 2009
@@ -0,0 +1,138 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.commons.lang.exception;
+
+import java.io.Serializable;
+import java.util.Set;
+
+/**
+ * Provides an unchecked version of ContextedException
+ * @see ContextedException
+ * @author D. Ashmore
+ * @author Jörg Schaible
+ * @since 3.0
+ *
+ */
+public class ContextedRuntimeException extends RuntimeException implements ExceptionContext {
+
+ private static final long serialVersionUID = 1459691936045811817L;
+ private ExceptionContext exceptionContext = new DefaultExceptionContext();
+
+ /**
+ * Instantiates ContextedRuntimeException without message or cause.
+ * <p>DefaultExceptionContext used to store and format context information.</p>
+ *
+ */
+ public ContextedRuntimeException() {
+ }
+
+ /**
+ * Instantiates ContextedRuntimeException with message, but without cause.
+ * <p>DefaultExceptionContext used to store and format context information.</p>
+ * @param message The exception message
+ * @since 3.0
+ */
+ public ContextedRuntimeException(String message) {
+ super(message);
+ }
+
+ /**
+ * Instantiates ContextedRuntimeException with cause, but without message.
+ * <p>DefaultExceptionContext used to store and format context information.</p>
+ * @param cause Exception creating need for ContextedRuntimeException
+ * @since 3.0
+ */
+ public ContextedRuntimeException(Throwable cause) {
+ super(cause);
+ }
+
+ /**
+ * Instantiates ContextedRuntimeException with cause and message.
+ * <p>DefaultExceptionContext used to store and format context information.</p>
+ * @param message The exception message
+ * @param cause Exception creating need for ContextedException
+ * @since 3.0
+ */
+ public ContextedRuntimeException(String message, Throwable cause) {
+ this(message, cause, cause instanceof ExceptionContext ? (ExceptionContext)cause : null);
+ }
+
+ /**
+ * Instantiates ContextedRuntimeException with cause, message, and ExceptionContext.
+ * @param message The exception message
+ * @param cause Exception creating need for ContextedRuntimeException
+ * @param context Context used to store additional information
+ * @since 3.0
+ */
+ public ContextedRuntimeException(String message, Throwable cause, ExceptionContext context) {
+ super(message, cause);
+ if (context != null) {
+ this.exceptionContext = context;
+ }
+ }
+
+ /**
+ * Adds information helpful to a developer in diagnosing and correcting
+ * the problem.
+ * @see ContextedException#addLabeledValue(String, Serializable)
+ * @param label a textual label associated with information
+ * @param value information needed to understand exception. May be <code>null</code>.
+ * @return this
+ * @since 3.0
+ */
+ public ContextedRuntimeException addLabeledValue(String label, Serializable value) {
+ this.exceptionContext.addLabeledValue(label, value);
+ return this;
+ }
+
+ /**
+ * Convenience method to retrieve a value from the underlying ExceptionContext.
+ * @param label a textual label associated with information
+ * @return value information needed to understand exception. May be <code>null</code>.
+ * @since 3.0
+ */
+ public Serializable getLabeledValue(String label) {
+ return this.exceptionContext.getLabeledValue(label);
+ }
+
+ /**
+ * Convenience method to retrieve currently defined labels from the underlying ExceptionContext.
+ * @return labelSet
+ * @since 3.0
+ */
+ public Set<String> getLabelSet() {
+ return this.exceptionContext.getLabelSet();
+ }
+
+ /**
+ * Provides message pertaining to exception.
+ * @see java.lang.Throwable#getMessage()
+ * @return message
+ * @since 3.0
+ */
+ @Override
+ public String getMessage(){
+ return getFormattedExceptionMessage(super.getMessage());
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public String getFormattedExceptionMessage(String baseMessage) {
+ return this.exceptionContext.getFormattedExceptionMessage(baseMessage);
+ }
+}
Propchange: commons/proper/lang/trunk/src/java/org/apache/commons/lang/exception/ContextedRuntimeException.java
------------------------------------------------------------------------------
svn:eol-style = native
Propchange: commons/proper/lang/trunk/src/java/org/apache/commons/lang/exception/ContextedRuntimeException.java
------------------------------------------------------------------------------
svn:keywords = Author Date Id HeadURL Revision
Added: commons/proper/lang/trunk/src/java/org/apache/commons/lang/exception/DefaultExceptionContext.java
URL: http://svn.apache.org/viewvc/commons/proper/lang/trunk/src/java/org/apache/commons/lang/exception/DefaultExceptionContext.java?rev=802566&view=auto
==============================================================================
--- commons/proper/lang/trunk/src/java/org/apache/commons/lang/exception/DefaultExceptionContext.java (added)
+++ commons/proper/lang/trunk/src/java/org/apache/commons/lang/exception/DefaultExceptionContext.java Sun Aug 9 17:46:13 2009
@@ -0,0 +1,129 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.commons.lang.exception;
+
+import java.io.Serializable;
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+
+import org.apache.commons.lang.SystemUtils;
+
+/**
+ * Provides context feature for exceptions. Used by both checked and unchecked version of the contexted exceptions.
+ * @see ContextedRuntimeException
+ * @author D. Ashmore
+ * @since 3.0
+ */
+public class DefaultExceptionContext implements ExceptionContext {
+
+ private static final long serialVersionUID = 293747957535772807L;
+
+ /*
+ * This value list could really be obtained from the Map, however, some
+ * callers want to control the order of the list as it appears in the
+ * Message. The list allows that. name/value pairs will appear in
+ * the order that they're provided. D. Ashmore
+ */
+ private List<String> contextKeyList = new ArrayList<String>();
+ private Map<String, Serializable> contextValueMap = new HashMap<String, Serializable>();
+
+ /**
+ * Adds information helpful to a developer in diagnosing and correcting
+ * the problem.
+ * @see ContextedException#addLabeledValue(String, Serializable)
+ * @param label a textual label associated with information
+ * @param value information needed to understand exception. May be null.
+ * @return this
+ * @since 3.0
+ */
+ public ExceptionContext addLabeledValue(String label, Serializable value) {
+ this.contextKeyList.add(label);
+ this.contextValueMap.put(label, value);
+
+ return this;
+ }
+
+ /**
+ * Retrieves the value for a given label.
+ * @param label a textual label associated with information
+ * @return value information needed to understand exception. May be null.
+ * @since 3.0
+ */
+ public Serializable getLabeledValue(String label) {
+ return this.contextValueMap.get(label);
+ }
+
+ /**
+ * Retrieves currently defined labels.
+ * @return labelSet
+ * @since 3.0
+ */
+ public Set<String> getLabelSet() {
+ return this.contextValueMap.keySet();
+ }
+
+ /**
+ * Centralized message logic for both checked and unchecked version of
+ * context exceptions
+ * @param baseMessage message retained by super class
+ * @return message -- exception message
+ * @since 3.0
+ */
+ public String getFormattedExceptionMessage(String baseMessage){
+ StringBuffer buffer = new StringBuffer(256);
+ if (baseMessage != null) {
+ buffer.append(baseMessage);
+ }
+
+ if (contextKeyList.size() > 0) {
+ buffer.append(SystemUtils.LINE_SEPARATOR);
+ buffer.append("Exception Context:");
+ buffer.append(SystemUtils.LINE_SEPARATOR);
+ buffer.append("\t");
+
+ Object value;
+ String valueStr;
+ for (String label: this.contextKeyList) {
+ buffer.append("[");
+ buffer.append(label);
+ buffer.append("=");
+ value = this.contextValueMap.get(label);
+ if (value == null) {
+ buffer.append("null");
+ }
+ else {
+ try {valueStr = value.toString();}
+ catch (Throwable t) {
+ valueStr = "Excepted on toString(): " +
+ ExceptionUtils.getStackTrace(t);
+ }
+ buffer.append(valueStr);
+ }
+ buffer.append("]");
+ buffer.append(SystemUtils.LINE_SEPARATOR);
+ buffer.append("\t");
+ }
+ buffer.append(SystemUtils.LINE_SEPARATOR);
+ buffer.append("\t---------------------------------");
+ }
+ return buffer.toString();
+ }
+
+}
\ No newline at end of file
Propchange: commons/proper/lang/trunk/src/java/org/apache/commons/lang/exception/DefaultExceptionContext.java
------------------------------------------------------------------------------
svn:eol-style = native
Propchange: commons/proper/lang/trunk/src/java/org/apache/commons/lang/exception/DefaultExceptionContext.java
------------------------------------------------------------------------------
svn:keywords = Author Date Id HeadURL Revision
Added: commons/proper/lang/trunk/src/java/org/apache/commons/lang/exception/ExceptionContext.java
URL: http://svn.apache.org/viewvc/commons/proper/lang/trunk/src/java/org/apache/commons/lang/exception/ExceptionContext.java?rev=802566&view=auto
==============================================================================
--- commons/proper/lang/trunk/src/java/org/apache/commons/lang/exception/ExceptionContext.java (added)
+++ commons/proper/lang/trunk/src/java/org/apache/commons/lang/exception/ExceptionContext.java Sun Aug 9 17:46:13 2009
@@ -0,0 +1,69 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.commons.lang.exception;
+
+import java.io.Serializable;
+import java.util.Collections;
+import java.util.Set;
+
+
+/**
+ * Provides context information for exceptions. It is available as separate interface to allow
+ * it usage independently from the {@link ContextedException} and
+ * {@link ContextedRuntimeException}.
+ *
+ * @see ContextedException
+ * @see ContextedRuntimeException
+ * @author D. Ashmore
+ * @since 3.0
+ */
+public interface ExceptionContext extends Serializable {
+
+ /**
+ * Adds a context item along with a label.
+ * @param label label of item
+ * @param value value of item
+ * @return context itself to allow method chaining
+ * @since 3.0
+ */
+ public ExceptionContext addLabeledValue(String label, Serializable value);
+
+ /**
+ * Provides context information associated with the given label.
+ * @param label label of item
+ * @return value value associated with label
+ * @since 3.0
+ */
+ public Serializable getLabeledValue(String label);
+
+ /**
+ * Provides a set of labels that are currently in the context.
+ * @return labelSet labels currently used by the context
+ * @since 3.0
+ */
+ public Set<String> getLabelSet();
+
+ /**
+ * Implementors provide the given base message with context label/value item
+ * information appended.
+ * @param baseMessage exception message <b>without</b> context information appended
+ * @return formattedMessage exception message <b>with</b> context information appended
+ * @since 3.0
+ */
+ public String getFormattedExceptionMessage(String baseMessage);
+
+}
\ No newline at end of file
Propchange: commons/proper/lang/trunk/src/java/org/apache/commons/lang/exception/ExceptionContext.java
------------------------------------------------------------------------------
svn:eol-style = native
Propchange: commons/proper/lang/trunk/src/java/org/apache/commons/lang/exception/ExceptionContext.java
------------------------------------------------------------------------------
svn:keywords = Author Date Id HeadURL Revision
Modified: commons/proper/lang/trunk/src/java/org/apache/commons/lang/exception/ExceptionUtils.java
URL: http://svn.apache.org/viewvc/commons/proper/lang/trunk/src/java/org/apache/commons/lang/exception/ExceptionUtils.java?rev=802566&r1=802565&r2=802566&view=diff
==============================================================================
--- commons/proper/lang/trunk/src/java/org/apache/commons/lang/exception/ExceptionUtils.java (original)
+++ commons/proper/lang/trunk/src/java/org/apache/commons/lang/exception/ExceptionUtils.java Sun Aug 9 17:46:13 2009
@@ -18,6 +18,7 @@
import java.io.PrintStream;
import java.io.PrintWriter;
+import java.io.Serializable;
import java.io.StringWriter;
import java.lang.reflect.Field;
import java.lang.reflect.InvocationTargetException;
@@ -25,7 +26,9 @@
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.Arrays;
+import java.util.Collections;
import java.util.List;
+import java.util.Set;
import java.util.StringTokenizer;
import net.jcip.annotations.GuardedBy;
@@ -91,6 +94,31 @@
*/
private static final Method THROWABLE_INITCAUSE_METHOD;
+ /**
+ * An empty {@link ExceptionContext}.
+ * @since 3.0
+ */
+ public static final ExceptionContext EMPTY_CONTEXT = new ExceptionContext() {
+
+ private static final long serialVersionUID = 1L;
+
+ public ExceptionContext addLabeledValue(String label, Serializable value) {
+ throw new UnsupportedOperationException();
+ }
+
+ public Serializable getLabeledValue(String label) {
+ return null;
+ }
+
+ public Set<String> getLabelSet() {
+ return Collections.<String>emptySet();
+ }
+
+ public String getFormattedExceptionMessage(String baseMessage) {
+ return baseMessage;
+ }
+
+ };
static {
Method causeMethod;
try {
Modified: commons/proper/lang/trunk/src/java/org/apache/commons/lang/exception/package.html
URL: http://svn.apache.org/viewvc/commons/proper/lang/trunk/src/java/org/apache/commons/lang/exception/package.html?rev=802566&r1=802565&r2=802566&view=diff
==============================================================================
--- commons/proper/lang/trunk/src/java/org/apache/commons/lang/exception/package.html (original)
+++ commons/proper/lang/trunk/src/java/org/apache/commons/lang/exception/package.html Sun Aug 9 17:46:13 2009
@@ -16,10 +16,10 @@
-->
<html>
<body>
-Provides JDK 1.4 style Nested Exception functionality for those on prior Java
-versions.
-<p>Includes a static utility to create version independent Nested
-Exception which can handle JDK 1.4 Exceptions as well as others. </p>
+Provides functionality for Exceptions.
+<p>Contains the concept of an exception with context i.e. such an exception
+will contain a map with keys and values. This provides an easy way to pass valuable
+state information at exception time in useful form to a calling process.</p>
<p>Lastly, {@link org.apache.commons.lang.exception.ExceptionUtils}
also contains <code>Throwable</code> manipulation and examination routines.</p>
@since 1.0
Added: commons/proper/lang/trunk/src/test/org/apache/commons/lang/exception/ContextedExceptionTest.java
URL: http://svn.apache.org/viewvc/commons/proper/lang/trunk/src/test/org/apache/commons/lang/exception/ContextedExceptionTest.java?rev=802566&view=auto
==============================================================================
--- commons/proper/lang/trunk/src/test/org/apache/commons/lang/exception/ContextedExceptionTest.java (added)
+++ commons/proper/lang/trunk/src/test/org/apache/commons/lang/exception/ContextedExceptionTest.java Sun Aug 9 17:46:13 2009
@@ -0,0 +1,151 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.commons.lang.exception;
+
+import java.io.Serializable;
+import java.util.Date;
+
+import junit.framework.TestCase;
+
+import org.apache.commons.lang.StringUtils;
+
+/**
+ * JUnit tests for ContextedException.
+ * @author D. Ashmore
+ *
+ */
+public class ContextedExceptionTest extends TestCase {
+
+ private static final String TEST_MESSAGE_2 = "This is monotonous";
+ private static final String TEST_MESSAGE = "Test Message";
+ private ContextedException contextedException;
+
+ public ContextedExceptionTest(String name) {
+ super(name);
+ }
+
+ public void testContextedException() {
+ contextedException = new ContextedException();
+ String message = contextedException.getMessage();
+ String trace = ExceptionUtils.getStackTrace(contextedException);
+ assertTrue(trace.indexOf("ContextedException")>=0);
+ assertTrue(StringUtils.isEmpty(message));
+ }
+
+ public void testContextedExceptionString() {
+ contextedException = new ContextedException(TEST_MESSAGE);
+ assertEquals(TEST_MESSAGE, contextedException.getMessage());
+
+ String trace = ExceptionUtils.getStackTrace(contextedException);
+ assertTrue(trace.indexOf(TEST_MESSAGE)>=0);
+ }
+
+ public void testContextedExceptionThrowable() {
+ contextedException = new ContextedException(new Exception(TEST_MESSAGE));
+ String message = contextedException.getMessage();
+ String trace = ExceptionUtils.getStackTrace(contextedException);
+ assertTrue(trace.indexOf("ContextedException")>=0);
+ assertTrue(trace.indexOf(TEST_MESSAGE)>=0);
+ assertTrue(message.indexOf(TEST_MESSAGE)>=0);
+ }
+
+ public void testContextedExceptionStringThrowable() {
+ contextedException = new ContextedException(TEST_MESSAGE_2, new Exception(TEST_MESSAGE));
+ String message = contextedException.getMessage();
+ String trace = ExceptionUtils.getStackTrace(contextedException);
+ assertTrue(trace.indexOf("ContextedException")>=0);
+ assertTrue(trace.indexOf(TEST_MESSAGE)>=0);
+ assertTrue(trace.indexOf(TEST_MESSAGE_2)>=0);
+ assertTrue(message.indexOf(TEST_MESSAGE_2)>=0);
+ }
+
+ public void testContextedExceptionStringThrowableContext() {
+ contextedException = new ContextedException(TEST_MESSAGE_2, new Exception(TEST_MESSAGE), new DefaultExceptionContext());
+ String message = contextedException.getMessage();
+ String trace = ExceptionUtils.getStackTrace(contextedException);
+ assertTrue(trace.indexOf("ContextedException")>=0);
+ assertTrue(trace.indexOf(TEST_MESSAGE)>=0);
+ assertTrue(trace.indexOf(TEST_MESSAGE_2)>=0);
+ assertTrue(message.indexOf(TEST_MESSAGE_2)>=0);
+ }
+
+ public void testAddLabeledValue() {
+ contextedException = new ContextedException(new Exception(TEST_MESSAGE))
+ .addLabeledValue("test1", null)
+ .addLabeledValue("test2", "some value")
+ .addLabeledValue("test Date", new Date())
+ .addLabeledValue("test Nbr", new Integer(5))
+ .addLabeledValue("test Poorly written obj", new ObjectWithFaultyToString());
+
+ String message = contextedException.getMessage();
+ assertTrue(message.indexOf(TEST_MESSAGE)>=0);
+ assertTrue(message.indexOf("test1")>=0);
+ assertTrue(message.indexOf("test2")>=0);
+ assertTrue(message.indexOf("test Date")>=0);
+ assertTrue(message.indexOf("test Nbr")>=0);
+ assertTrue(message.indexOf("test Poorly written obj")>=0);
+ assertTrue(message.indexOf("some value")>=0);
+ assertTrue(message.indexOf("5")>=0);
+ assertTrue(message.indexOf("Crap")>=0);
+
+ String contextMessage = contextedException.getFormattedExceptionMessage("");
+ assertTrue(contextMessage.indexOf(TEST_MESSAGE) == -1);
+ assertTrue(message.contains(contextMessage));
+
+ assertTrue(contextedException.getLabeledValue("test1") == null);
+ assertTrue(contextedException.getLabeledValue("test2").equals("some value"));
+ assertTrue(contextedException.getLabeledValue("crap") == null);
+ assertTrue(contextedException.getLabeledValue("test Poorly written obj") instanceof ObjectWithFaultyToString);
+
+ assertTrue(contextedException.getLabelSet().size() == 5);
+ assertTrue(contextedException.getLabelSet().contains("test1"));
+ assertTrue(contextedException.getLabelSet().contains("test2"));
+ assertTrue(contextedException.getLabelSet().contains("test Date"));
+ assertTrue(contextedException.getLabelSet().contains("test Nbr"));
+ assertTrue(contextedException.getLabelSet().contains("test Poorly written obj"));
+
+ assertTrue(!contextedException.getLabelSet().contains("crap"));
+ }
+
+ public void testNullExceptionPassing() {
+ contextedException = new ContextedException(TEST_MESSAGE_2, new Exception(TEST_MESSAGE), null)
+ .addLabeledValue("test1", null)
+ .addLabeledValue("test2", "some value")
+ .addLabeledValue("test Date", new Date())
+ .addLabeledValue("test Nbr", new Integer(5))
+ .addLabeledValue("test Poorly written obj", new ObjectWithFaultyToString());
+
+ String message = contextedException.getMessage();
+ assertTrue(message != null);
+ }
+
+ public void testGetMessage() {
+ testAddLabeledValue();
+ }
+
+ static class ObjectWithFaultyToString implements Serializable {
+
+ private static final long serialVersionUID = 3495843995332310458L;
+
+ @Override
+ public String toString() {
+ throw new RuntimeException("Crap");
+ }
+
+ }
+
+}
Propchange: commons/proper/lang/trunk/src/test/org/apache/commons/lang/exception/ContextedExceptionTest.java
------------------------------------------------------------------------------
svn:eol-style = native
Propchange: commons/proper/lang/trunk/src/test/org/apache/commons/lang/exception/ContextedExceptionTest.java
------------------------------------------------------------------------------
svn:keywords = Author Date Id HeadURL Revision
Added: commons/proper/lang/trunk/src/test/org/apache/commons/lang/exception/ContextedRuntimeExceptionTest.java
URL: http://svn.apache.org/viewvc/commons/proper/lang/trunk/src/test/org/apache/commons/lang/exception/ContextedRuntimeExceptionTest.java?rev=802566&view=auto
==============================================================================
--- commons/proper/lang/trunk/src/test/org/apache/commons/lang/exception/ContextedRuntimeExceptionTest.java (added)
+++ commons/proper/lang/trunk/src/test/org/apache/commons/lang/exception/ContextedRuntimeExceptionTest.java Sun Aug 9 17:46:13 2009
@@ -0,0 +1,141 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.commons.lang.exception;
+
+import java.util.Date;
+
+import junit.framework.TestCase;
+
+import org.apache.commons.lang.StringUtils;
+import org.apache.commons.lang.exception.ContextedExceptionTest.ObjectWithFaultyToString;
+
+/**
+ * JUnit tests for ContextedRuntimeException.
+ * @author D. Ashmore
+ *
+ */
+public class ContextedRuntimeExceptionTest extends TestCase {
+
+ private static final String TEST_MESSAGE_2 = "This is monotonous";
+ private static final String TEST_MESSAGE = "Test Message";
+ private ContextedRuntimeException contextedRuntimeException;
+
+ public ContextedRuntimeExceptionTest(String name) {
+ super(name);
+ }
+
+ public void testContextedException() {
+ contextedRuntimeException = new ContextedRuntimeException();
+ String message = contextedRuntimeException.getMessage();
+ String trace = ExceptionUtils.getStackTrace(contextedRuntimeException);
+ assertTrue(trace.indexOf("ContextedException")>=0);
+ assertTrue(StringUtils.isEmpty(message));
+ }
+
+ public void testContextedExceptionString() {
+ contextedRuntimeException = new ContextedRuntimeException(TEST_MESSAGE);
+ assertEquals(TEST_MESSAGE, contextedRuntimeException.getMessage());
+
+ String trace = ExceptionUtils.getStackTrace(contextedRuntimeException);
+ assertTrue(trace.indexOf(TEST_MESSAGE)>=0);
+ }
+
+ public void testContextedExceptionThrowable() {
+ contextedRuntimeException = new ContextedRuntimeException(new Exception(TEST_MESSAGE));
+ String message = contextedRuntimeException.getMessage();
+ String trace = ExceptionUtils.getStackTrace(contextedRuntimeException);
+ assertTrue(trace.indexOf("ContextedException")>=0);
+ assertTrue(trace.indexOf(TEST_MESSAGE)>=0);
+ assertTrue(message.indexOf(TEST_MESSAGE)>=0);
+ }
+
+ public void testContextedExceptionStringThrowable() {
+ contextedRuntimeException = new ContextedRuntimeException(TEST_MESSAGE_2, new Exception(TEST_MESSAGE));
+ String message = contextedRuntimeException.getMessage();
+ String trace = ExceptionUtils.getStackTrace(contextedRuntimeException);
+ assertTrue(trace.indexOf("ContextedException")>=0);
+ assertTrue(trace.indexOf(TEST_MESSAGE)>=0);
+ assertTrue(trace.indexOf(TEST_MESSAGE_2)>=0);
+ assertTrue(message.indexOf(TEST_MESSAGE_2)>=0);
+ }
+
+ public void testContextedExceptionStringThrowableContext() {
+ contextedRuntimeException = new ContextedRuntimeException(TEST_MESSAGE_2, new Exception(TEST_MESSAGE), new DefaultExceptionContext());
+ String message = contextedRuntimeException.getMessage();
+ String trace = ExceptionUtils.getStackTrace(contextedRuntimeException);
+ assertTrue(trace.indexOf("ContextedException")>=0);
+ assertTrue(trace.indexOf(TEST_MESSAGE)>=0);
+ assertTrue(trace.indexOf(TEST_MESSAGE_2)>=0);
+ assertTrue(message.indexOf(TEST_MESSAGE_2)>=0);
+ }
+
+ public void testAddLabeledValue() {
+ contextedRuntimeException = new ContextedRuntimeException(new Exception(TEST_MESSAGE))
+ .addLabeledValue("test1", null)
+ .addLabeledValue("test2", "some value")
+ .addLabeledValue("test Date", new Date())
+ .addLabeledValue("test Nbr", new Integer(5))
+ .addLabeledValue("test Poorly written obj", new ObjectWithFaultyToString());
+
+ String message = contextedRuntimeException.getMessage();
+ assertTrue(message.indexOf(TEST_MESSAGE)>=0);
+ assertTrue(message.indexOf("test1")>=0);
+ assertTrue(message.indexOf("test2")>=0);
+ assertTrue(message.indexOf("test Date")>=0);
+ assertTrue(message.indexOf("test Nbr")>=0);
+ assertTrue(message.indexOf("test Poorly written obj")>=0);
+ assertTrue(message.indexOf("some value")>=0);
+ assertTrue(message.indexOf("5")>=0);
+ assertTrue(message.indexOf("Crap")>=0);
+
+ String contextMessage = contextedRuntimeException.getFormattedExceptionMessage("");
+ assertTrue(contextMessage.indexOf(TEST_MESSAGE) == -1);
+ assertTrue(message.contains(contextMessage));
+
+ assertTrue(contextedRuntimeException.getLabeledValue("test1") == null);
+ assertTrue(contextedRuntimeException.getLabeledValue("test2").equals("some value"));
+ assertTrue(contextedRuntimeException.getLabeledValue("crap") == null);
+ assertTrue(contextedRuntimeException.getLabeledValue("test Poorly written obj") instanceof ObjectWithFaultyToString);
+
+ assertTrue(contextedRuntimeException.getLabelSet().size() == 5);
+ assertTrue(contextedRuntimeException.getLabelSet().contains("test1"));
+ assertTrue(contextedRuntimeException.getLabelSet().contains("test2"));
+ assertTrue(contextedRuntimeException.getLabelSet().contains("test Date"));
+ assertTrue(contextedRuntimeException.getLabelSet().contains("test Nbr"));
+ assertTrue(contextedRuntimeException.getLabelSet().contains("test Poorly written obj"));
+
+ assertTrue(!contextedRuntimeException.getLabelSet().contains("crap"));
+ }
+
+ public void testNullExceptionPassing() {
+ contextedRuntimeException = new ContextedRuntimeException(TEST_MESSAGE_2, new Exception(TEST_MESSAGE), null)
+ .addLabeledValue("test1", null)
+ .addLabeledValue("test2", "some value")
+ .addLabeledValue("test Date", new Date())
+ .addLabeledValue("test Nbr", new Integer(5))
+ .addLabeledValue("test Poorly written obj", new ObjectWithFaultyToString());
+
+ String message = contextedRuntimeException.getMessage();
+ assertTrue(message != null);
+ }
+
+ public void testGetMessage() {
+ testAddLabeledValue();
+ }
+
+
+}
Propchange: commons/proper/lang/trunk/src/test/org/apache/commons/lang/exception/ContextedRuntimeExceptionTest.java
------------------------------------------------------------------------------
svn:eol-style = native
Propchange: commons/proper/lang/trunk/src/test/org/apache/commons/lang/exception/ContextedRuntimeExceptionTest.java
------------------------------------------------------------------------------
svn:keywords = Author Date Id HeadURL Revision
Added: commons/proper/lang/trunk/src/test/org/apache/commons/lang/exception/DefaultExceptionContextTest.java
URL: http://svn.apache.org/viewvc/commons/proper/lang/trunk/src/test/org/apache/commons/lang/exception/DefaultExceptionContextTest.java?rev=802566&view=auto
==============================================================================
--- commons/proper/lang/trunk/src/test/org/apache/commons/lang/exception/DefaultExceptionContextTest.java (added)
+++ commons/proper/lang/trunk/src/test/org/apache/commons/lang/exception/DefaultExceptionContextTest.java Sun Aug 9 17:46:13 2009
@@ -0,0 +1,86 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.commons.lang.exception;
+
+import java.util.Date;
+
+import org.apache.commons.lang.exception.ContextedExceptionTest.ObjectWithFaultyToString;
+
+import junit.framework.TestCase;
+
+/**
+ * JUnit tests for DefaultExceptionContext
+ * @author D. Ashmore
+ *
+ */
+public class DefaultExceptionContextTest extends TestCase {
+
+ private ExceptionContext defaultExceptionContext;
+
+ public DefaultExceptionContextTest(String name) {
+ super(name);
+ }
+
+ public void setUp() {
+ defaultExceptionContext = new DefaultExceptionContext()
+ .addLabeledValue("test1", null)
+ .addLabeledValue("test2", "some value")
+ .addLabeledValue("test Date", new Date())
+ .addLabeledValue("test Nbr", new Integer(5))
+ .addLabeledValue("test Poorly written obj", new ObjectWithFaultyToString());
+ }
+
+ public void testAddLabeledValue() {
+
+ String message = defaultExceptionContext.getFormattedExceptionMessage("This is an error");
+ assertTrue(message.indexOf("This is an error")>=0);
+ assertTrue(message.indexOf("test1")>=0);
+ assertTrue(message.indexOf("test2")>=0);
+ assertTrue(message.indexOf("test Date")>=0);
+ assertTrue(message.indexOf("test Nbr")>=0);
+ assertTrue(message.indexOf("test Poorly written obj")>=0);
+ assertTrue(message.indexOf("some value")>=0);
+ assertTrue(message.indexOf("5")>=0);
+ assertTrue(message.indexOf("Crap")>=0);
+
+ //contextedException.printStackTrace();
+ }
+
+ public void testFormattedExceptionMessageNull() {
+ defaultExceptionContext = new DefaultExceptionContext();
+ defaultExceptionContext.getFormattedExceptionMessage(null);
+ }
+
+ public void testGetLabeledValue() {
+ assertTrue(defaultExceptionContext.getLabeledValue("test1") == null);
+ assertTrue(defaultExceptionContext.getLabeledValue("test2").equals("some value"));
+ assertTrue(defaultExceptionContext.getLabeledValue("crap") == null);
+ assertTrue(defaultExceptionContext.getLabeledValue("test Poorly written obj") instanceof ObjectWithFaultyToString);
+ }
+
+ public void testGetLabelSet() {
+ assertTrue(defaultExceptionContext.getLabelSet().size() == 5);
+ assertTrue(defaultExceptionContext.getLabelSet().contains("test1"));
+ assertTrue(defaultExceptionContext.getLabelSet().contains("test2"));
+ assertTrue(defaultExceptionContext.getLabelSet().contains("test Date"));
+ assertTrue(defaultExceptionContext.getLabelSet().contains("test Nbr"));
+ assertTrue(defaultExceptionContext.getLabelSet().contains("test Poorly written obj"));
+
+ assertTrue(!defaultExceptionContext.getLabelSet().contains("crap"));
+ }
+
+}
Propchange: commons/proper/lang/trunk/src/test/org/apache/commons/lang/exception/DefaultExceptionContextTest.java
------------------------------------------------------------------------------
svn:eol-style = native
Propchange: commons/proper/lang/trunk/src/test/org/apache/commons/lang/exception/DefaultExceptionContextTest.java
------------------------------------------------------------------------------
svn:keywords = Author Date Id HeadURL Revision