You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@directory.apache.org by ak...@apache.org on 2005/02/03 08:18:54 UTC
svn commit: r151131 [5/9] - in
incubator/directory/asn1/branches/rewrite/ber: ./
src/java/org/apache/asn1/ber/ src/java/org/apache/asn1/ber/digester/
src/java/org/apache/asn1/ber/digester/rules/
src/java/org/apache/asn1/ber/primitives/ src/java/org/apache/asn1/tuples/
src/java/org/apache/asn1/util/ src/test/org/apache/asn1/ber/
src/test/org/apache/asn1/ber/primitives/
Added: incubator/directory/asn1/branches/rewrite/ber/src/java/org/apache/asn1/util/Nestable.java
URL: http://svn.apache.org/viewcvs/incubator/directory/asn1/branches/rewrite/ber/src/java/org/apache/asn1/util/Nestable.java?view=auto&rev=151131
==============================================================================
--- incubator/directory/asn1/branches/rewrite/ber/src/java/org/apache/asn1/util/Nestable.java (added)
+++ incubator/directory/asn1/branches/rewrite/ber/src/java/org/apache/asn1/util/Nestable.java Wed Feb 2 23:18:42 2005
@@ -0,0 +1,177 @@
+/*
+ * Copyright 2002-2004 The Apache Software Foundation.
+ *
+ * Licensed 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.asn1.util;
+
+
+import java.io.PrintStream;
+import java.io.PrintWriter;
+
+
+/**
+ * An interface to be implemented by {@link java.lang.Throwable} extensions
+ * which would like to be able to nest root exceptions inside themselves.
+ *
+ * @author <a href="mailto:dlr@collab.net">Daniel Rall</a>
+ * @author <a href="mailto:knielsen@apache.org">Kasper Nielsen</a>
+ * @author <a href="mailto:steven@caswell.name">Steven Caswell</a>
+ * @author Pete Gieser
+ * @version $Id: Nestable.java,v 1.11 2004/02/18 22:54:04 ggregory Exp $
+ * @since 1.0
+ */
+public interface Nestable
+{
+
+ /**
+ * Returns the reference to the exception or error that caused the exception
+ * implementing the <code>Nestable</code> to be thrown.
+ *
+ * @return throwable that caused the original exception
+ */
+ public Throwable getCause();
+
+
+ /**
+ * Returns the error message of this and any nested <code>Throwable</code>.
+ *
+ * @return the error message
+ */
+ public String getMessage();
+
+
+ /**
+ * Returns the error message of the <code>Throwable</code> in the chain of
+ * <code>Throwable</code>s at the specified index, numbered from 0.
+ *
+ * @param index the index of the <code>Throwable</code> in the chain of
+ * <code>Throwable</code>s
+ * @return the error message, or null if the <code>Throwable</code> at the
+ * specified index in the chain does not contain a message
+ * @throws IndexOutOfBoundsException if the <code>index</code> argument is
+ * negative or not less than the count of
+ * <code>Throwable</code>s in the chain
+ */
+ public String getMessage( int index );
+
+
+ /**
+ * Returns the error message of this and any nested <code>Throwable</code>s
+ * in an array of Strings, one element for each message. Any
+ * <code>Throwable</code> not containing a message is represented in the
+ * array by a null. This has the effect of cause the length of the returned
+ * array to be equal to the result of the {@link #getThrowableCount()}
+ * operation.
+ *
+ * @return the error messages
+ */
+ public String[] getMessages();
+
+
+ /**
+ * Returns the <code>Throwable</code> in the chain of
+ * <code>Throwable</code>s at the specified index, numbered from 0.
+ *
+ * @param index the index, numbered from 0, of the <code>Throwable</code> in
+ * the chain of <code>Throwable</code>s
+ * @return the <code>Throwable</code>
+ * @throws IndexOutOfBoundsException if the <code>index</code> argument is
+ * negative or not less than the count of
+ * <code>Throwable</code>s in the chain
+ */
+ public Throwable getThrowable( int index );
+
+
+ /**
+ * Returns the number of nested <code>Throwable</code>s represented by this
+ * <code>Nestable</code>, including this <code>Nestable</code>.
+ *
+ * @return the throwable count
+ */
+ public int getThrowableCount();
+
+
+ /**
+ * Returns this <code>Nestable</code> and any nested <code>Throwable</code>s
+ * in an array of <code>Throwable</code>s, one element for each
+ * <code>Throwable</code>.
+ *
+ * @return the <code>Throwable</code>s
+ */
+ public Throwable[] getThrowables();
+
+
+ /**
+ * Returns the index, numbered from 0, of the first occurrence of the
+ * specified type in the chain of <code>Throwable</code>s, or -1 if the
+ * specified type is not found in the chain.
+ *
+ * @param type <code>Class</code> to be found
+ * @return index of the first occurrence of the type in the chain, or -1 if
+ * the type is not found
+ */
+ public int indexOfThrowable( Class type );
+
+
+ /**
+ * Returns the index, numbered from 0, of the first <code>Throwable</code>
+ * that matches the specified type in the chain of <code>Throwable</code>s
+ * with an index greater than or equal to the specified index, or -1 if the
+ * type is not found.
+ *
+ * @param type <code>Class</code> to be found
+ * @param fromIndex the index, numbered from 0, of the starting position in
+ * the chain to be searched
+ * @return index of the first occurrence of the type in the chain, or -1 if
+ * the type is not found
+ * @throws IndexOutOfBoundsException if the <code>fromIndex</code> argument
+ * is negative or not less than the count
+ * of <code>Throwable</code>s in the
+ * chain
+ */
+ public int indexOfThrowable( Class type, int fromIndex );
+
+
+ /**
+ * 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 <code>PrintWriter</code> to use for output.
+ */
+ public void printStackTrace( PrintWriter out );
+
+
+ /**
+ * 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 <code>PrintStream</code> to use for output.
+ */
+ public 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
+ * <code>super.printStackTrace(out);</code> in most cases.
+ *
+ * @param out The writer to use.
+ */
+ public void printPartialStackTrace( PrintWriter out );
+
+}
Added: incubator/directory/asn1/branches/rewrite/ber/src/java/org/apache/asn1/util/NestableDelegate.java
URL: http://svn.apache.org/viewcvs/incubator/directory/asn1/branches/rewrite/ber/src/java/org/apache/asn1/util/NestableDelegate.java?view=auto&rev=151131
==============================================================================
--- incubator/directory/asn1/branches/rewrite/ber/src/java/org/apache/asn1/util/NestableDelegate.java (added)
+++ incubator/directory/asn1/branches/rewrite/ber/src/java/org/apache/asn1/util/NestableDelegate.java Wed Feb 2 23:18:42 2005
@@ -0,0 +1,427 @@
+/*
+ * Copyright 2002-2004 The Apache Software Foundation.
+ *
+ * Licensed 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.asn1.util;
+
+
+import java.io.PrintStream;
+import java.io.PrintWriter;
+import java.io.Serializable;
+import java.io.StringWriter;
+import java.util.*;
+
+
+/**
+ * <p>A shared implementation of the nestable exception functionality.</p>
+ * <p/>
+ * The code is shared between </p>
+ *
+ * @author <a href="mailto:Rafal.Krzewski@e-point.pl">Rafal Krzewski</a>
+ * @author <a href="mailto:dlr@collab.net">Daniel Rall</a>
+ * @author <a href="mailto:knielsen@apache.org">Kasper Nielsen</a>
+ * @author <a href="mailto:steven@caswell.name">Steven Caswell</a>
+ * @author Sean C. Sullivan
+ * @author Stephen Colebourne
+ * @version $Id: NestableDelegate.java,v 1.23 2004/02/18 22:54:04 ggregory Exp
+ * $
+ * @since 1.0
+ */
+public class NestableDelegate implements 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;
+
+ /**
+ * Whether to print the stack trace top-down. This public flag may be set by
+ * calling code, typically in initialisation.
+ *
+ * @since 2.0
+ */
+ public static boolean topDown = true;
+
+ /**
+ * Whether to trim the repeated stack trace. This public flag may be set by
+ * calling code, typically in initialisation.
+ *
+ * @since 2.0
+ */
+ public static boolean trimStackFrames = true;
+
+
+ /**
+ * Constructs a new <code>NestableDelegate</code> instance to manage the
+ * specified <code>Nestable</code>.
+ *
+ * @param nestable the Nestable implementation (<i>must</i> extend {@link
+ * java.lang.Throwable})
+ * @since 2.0
+ */
+ public NestableDelegate( Nestable nestable )
+ {
+ if ( nestable instanceof Throwable )
+ {
+ this.nestable = ( Throwable ) nestable;
+ }
+ else
+ {
+ throw new IllegalArgumentException( MUST_BE_THROWABLE );
+ }
+ }
+
+
+ /**
+ * Returns the error message of the <code>Throwable</code> in the chain of
+ * <code>Throwable</code>s at the specified index, numbered from 0.
+ *
+ * @param index the index of the <code>Throwable</code> in the chain of
+ * <code>Throwable</code>s
+ * @return the error message, or null if the <code>Throwable</code> at the
+ * specified index in the chain does not contain a message
+ * @throws IndexOutOfBoundsException if the <code>index</code> argument is
+ * negative or not less than the count of
+ * <code>Throwable</code>s in the chain
+ * @since 2.0
+ */
+ public String getMessage( int index )
+ {
+ Throwable t = this.getThrowable( index );
+ if ( Nestable.class.isInstance( t ) )
+ {
+ return ( ( Nestable ) t ).getMessage( 0 );
+ }
+ else
+ {
+ return t.getMessage();
+ }
+ }
+
+
+ /**
+ * Returns the full message contained by the <code>Nestable</code> and any
+ * nested <code>Throwable</code>s.
+ *
+ * @param baseMsg the base message to use when creating the full message.
+ * Should be generally be called via <code>nestableHelper.getMessage(super.getMessage())</code>,
+ * where <code>super</code> is an instance of {@link
+ * java.lang.Throwable}.
+ * @return The concatenated message for this and all nested
+ * <code>Throwable</code>s
+ * @since 2.0
+ */
+ public 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 );
+ }
+
+
+ /**
+ * Returns the error message of this and any nested <code>Throwable</code>s
+ * in an array of Strings, one element for each message. Any
+ * <code>Throwable</code> not containing a message is represented in the
+ * array by a null. This has the effect of cause the length of the returned
+ * array to be equal to the result of the {@link #getThrowableCount()}
+ * operation.
+ *
+ * @return the error messages
+ * @since 2.0
+ */
+ public String[] getMessages()
+ {
+ Throwable[] throwables = this.getThrowables();
+ String[] msgs = new String[throwables.length];
+ for ( int i = 0; i < throwables.length; i++ )
+ {
+ msgs[i] =
+ ( Nestable.class.isInstance( throwables[i] )
+ ? ( ( Nestable ) throwables[i] ).getMessage( 0 )
+ : throwables[i].getMessage() );
+ }
+ return msgs;
+ }
+
+
+ /**
+ * Returns the <code>Throwable</code> in the chain of
+ * <code>Throwable</code>s at the specified index, numbered from 0.
+ *
+ * @param index the index, numbered from 0, of the <code>Throwable</code> in
+ * the chain of <code>Throwable</code>s
+ * @return the <code>Throwable</code>
+ * @throws IndexOutOfBoundsException if the <code>index</code> argument is
+ * negative or not less than the count of
+ * <code>Throwable</code>s in the chain
+ * @since 2.0
+ */
+ public Throwable getThrowable( int index )
+ {
+ if ( index == 0 )
+ {
+ return this.nestable;
+ }
+ Throwable[] throwables = this.getThrowables();
+ return throwables[index];
+ }
+
+
+ /**
+ * Returns the number of <code>Throwable</code>s contained in the
+ * <code>Nestable</code> contained by this delegate.
+ *
+ * @return the throwable count
+ * @since 2.0
+ */
+ public int getThrowableCount()
+ {
+ return ExceptionUtils.getThrowableCount( this.nestable );
+ }
+
+
+ /**
+ * Returns this delegate's <code>Nestable</code> and any nested
+ * <code>Throwable</code>s in an array of <code>Throwable</code>s, one
+ * element for each <code>Throwable</code>.
+ *
+ * @return the <code>Throwable</code>s
+ * @since 2.0
+ */
+ public Throwable[] getThrowables()
+ {
+ return ExceptionUtils.getThrowables( this.nestable );
+ }
+
+
+ /**
+ * Returns the index, numbered from 0, of the first <code>Throwable</code>
+ * that matches the specified type in the chain of <code>Throwable</code>s
+ * held in this delegate's <code>Nestable</code> with an index greater than
+ * or equal to the specified index, or -1 if the type is not found.
+ *
+ * @param type <code>Class</code> to be found
+ * @param fromIndex the index, numbered from 0, of the starting position in
+ * the chain to be searched
+ * @return index of the first occurrence of the type in the chain, or -1 if
+ * the type is not found
+ * @throws IndexOutOfBoundsException if the <code>fromIndex</code> argument
+ * is negative or not less than the count
+ * of <code>Throwable</code>s in the
+ * chain
+ * @since 2.0
+ */
+ public int indexOfThrowable( Class type, int fromIndex )
+ {
+ if ( fromIndex < 0 )
+ {
+ throw new IndexOutOfBoundsException( "The start index was out of bounds: " + fromIndex );
+ }
+ Throwable[] throwables = ExceptionUtils.getThrowables( this.nestable );
+ if ( fromIndex >= throwables.length )
+ {
+ throw new IndexOutOfBoundsException( "The start index was out of bounds: "
+ + fromIndex + " >= " + throwables.length );
+ }
+ for ( int i = fromIndex; i < throwables.length; i++ )
+ {
+ if ( throwables[i].getClass().equals( type ) )
+ {
+ return i;
+ }
+ }
+ return -1;
+ }
+
+
+ /**
+ * 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 <code>PrintStream</code> 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. If the
+ * Throwable class has a <code>getCause</code> method (i.e. running on
+ * jre1.4 or higher), this method just uses Throwable's printStackTrace()
+ * method. Otherwise, generates the stack-trace, by taking into account the
+ * 'topDown' and 'trimStackFrames' parameters. The topDown and
+ * trimStackFrames are set to 'true' by default (produces jre1.4-like stack
+ * trace).
+ *
+ * @param out <code>PrintWriter</code> to use for output.
+ */
+ public void printStackTrace( PrintWriter out )
+ {
+ Throwable throwable = this.nestable;
+ // if running on jre1.4 or higher, use default printStackTrace
+ if ( ExceptionUtils.isThrowableNested() )
+ {
+ if ( throwable instanceof Nestable )
+ {
+ ( ( Nestable ) throwable ).printPartialStackTrace( out );
+ }
+ else
+ {
+ throwable.printStackTrace( out );
+ }
+ return;
+ }
+
+ // generating the nested stack trace
+ List stacks = new ArrayList();
+ while ( throwable != null )
+ {
+ String[] st = getStackFrames( throwable );
+ stacks.add( st );
+ throwable = ExceptionUtils.getCause( throwable );
+ }
+
+ // If NOT topDown, reverse the stack
+ String separatorLine = "Caused by: ";
+ if ( !topDown )
+ {
+ separatorLine = "Rethrown as: ";
+ Collections.reverse( stacks );
+ }
+
+ // Remove the repeated lines in the stack
+ if ( trimStackFrames )
+ {
+ trimStackFrames( stacks );
+ }
+
+ synchronized ( out )
+ {
+ for ( Iterator iter = stacks.iterator(); iter.hasNext(); )
+ {
+ String[] st = ( String[] ) iter.next();
+ for ( int i = 0, len = st.length; i < len; i++ )
+ {
+ out.println( st[i] );
+ }
+ if ( iter.hasNext() )
+ {
+ out.print( separatorLine );
+ }
+ }
+ }
+ }
+
+
+ /**
+ * Captures the stack trace associated with the specified
+ * <code>Throwable</code> object, decomposing it into a list of stack
+ * frames.
+ *
+ * @param t The <code>Throwable</code>.
+ * @return An array of strings describing each stack frame.
+ * @since 2.0
+ */
+ protected 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() );
+ }
+
+
+ /**
+ * Trims the stack frames. The first set is left untouched. The rest of the
+ * frames are truncated from the bottom by comparing with one just on top.
+ *
+ * @param stacks The list containing String[] elements
+ * @since 2.0
+ */
+ protected void trimStackFrames( List stacks )
+ {
+ for ( int size = stacks.size(), i = size - 1; i > 0; i-- )
+ {
+ String[] curr = ( String[] ) stacks.get( i );
+ String[] next = ( String[] ) stacks.get( i - 1 );
+
+ List currList = new ArrayList( Arrays.asList( curr ) );
+ List nextList = new ArrayList( Arrays.asList( next ) );
+ ExceptionUtils.removeCommonFrames( currList, nextList );
+
+ int trimmed = curr.length - currList.size();
+ if ( trimmed > 0 )
+ {
+ currList.add( "\t... " + trimmed + " more" );
+ stacks.set( i,
+ currList.toArray( new String[currList.size()] ) );
+ }
+ }
+ }
+}
Added: incubator/directory/asn1/branches/rewrite/ber/src/java/org/apache/asn1/util/NestableError.java
URL: http://svn.apache.org/viewcvs/incubator/directory/asn1/branches/rewrite/ber/src/java/org/apache/asn1/util/NestableError.java?view=auto&rev=151131
==============================================================================
--- incubator/directory/asn1/branches/rewrite/ber/src/java/org/apache/asn1/util/NestableError.java (added)
+++ incubator/directory/asn1/branches/rewrite/ber/src/java/org/apache/asn1/util/NestableError.java Wed Feb 2 23:18:42 2005
@@ -0,0 +1,196 @@
+/*
+ * Copyright 2002-2004 The Apache Software Foundation.
+ *
+ * Licensed 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.asn1.util;
+
+
+import java.io.PrintStream;
+import java.io.PrintWriter;
+
+
+/**
+ * The base class of all errors which can contain other exceptions.
+ *
+ * @author <a href="mailto:dlr@finemaltcoding.com">Daniel Rall</a>
+ * @version $Id: NestableError.java,v 1.8 2004/02/18 22:54:04 ggregory Exp $
+ * @since 1.0
+ */
+public class NestableError extends Error implements Nestable
+{
+
+ /**
+ * The helper instance which contains much of the code which we delegate
+ * to.
+ */
+ protected NestableDelegate delegate = new NestableDelegate( this );
+
+ /**
+ * Holds the reference to the exception or error that caused this exception
+ * to be thrown.
+ */
+ private Throwable cause = null;
+
+
+ /**
+ * Constructs a new <code>NestableError</code> without specified detail
+ * message.
+ */
+ public NestableError()
+ {
+ super();
+ }
+
+
+ /**
+ * Constructs a new <code>NestableError</code> with specified detail
+ * message.
+ *
+ * @param msg The error message.
+ */
+ public NestableError( String msg )
+ {
+ super( msg );
+ }
+
+
+ /**
+ * Constructs a new <code>NestableError</code> with specified nested
+ * <code>Throwable</code>.
+ *
+ * @param cause the exception or error that caused this exception to be
+ * thrown
+ */
+ public NestableError( Throwable cause )
+ {
+ super();
+ this.cause = cause;
+ }
+
+
+ /**
+ * Constructs a new <code>NestableError</code> with specified detail message
+ * and nested <code>Throwable</code>.
+ *
+ * @param msg the error message
+ * @param cause the exception or error that caused this exception to be
+ * thrown
+ */
+ public NestableError( String msg, Throwable cause )
+ {
+ super( msg );
+ this.cause = cause;
+ }
+
+
+ public Throwable getCause()
+ {
+ return cause;
+ }
+
+
+ /**
+ * Returns the detail message string of this throwable. If it was created
+ * with a null message, returns the following: (cause==null ? null :
+ * cause.toString()).
+ */
+ public String getMessage()
+ {
+ if ( super.getMessage() != null )
+ {
+ return super.getMessage();
+ }
+ else if ( cause != null )
+ {
+ return cause.toString();
+ }
+ else
+ {
+ return null;
+ }
+ }
+
+
+ public String getMessage( int index )
+ {
+ if ( index == 0 )
+ {
+ return super.getMessage();
+ }
+ else
+ {
+ return delegate.getMessage( index );
+ }
+ }
+
+
+ public String[] getMessages()
+ {
+ return delegate.getMessages();
+ }
+
+
+ public Throwable getThrowable( int index )
+ {
+ return delegate.getThrowable( index );
+ }
+
+
+ public int getThrowableCount()
+ {
+ return delegate.getThrowableCount();
+ }
+
+
+ public Throwable[] getThrowables()
+ {
+ return delegate.getThrowables();
+ }
+
+
+ public int indexOfThrowable( Class type )
+ {
+ return delegate.indexOfThrowable( type, 0 );
+ }
+
+
+ public int indexOfThrowable( Class type, int fromIndex )
+ {
+ return delegate.indexOfThrowable( type, fromIndex );
+ }
+
+
+ public void printStackTrace()
+ {
+ delegate.printStackTrace();
+ }
+
+
+ public void printStackTrace( PrintStream out )
+ {
+ delegate.printStackTrace( out );
+ }
+
+
+ public void printStackTrace( PrintWriter out )
+ {
+ delegate.printStackTrace( out );
+ }
+
+
+ public final void printPartialStackTrace( PrintWriter out )
+ {
+ super.printStackTrace( out );
+ }
+}
Added: incubator/directory/asn1/branches/rewrite/ber/src/java/org/apache/asn1/util/NestableException.java
URL: http://svn.apache.org/viewcvs/incubator/directory/asn1/branches/rewrite/ber/src/java/org/apache/asn1/util/NestableException.java?view=auto&rev=151131
==============================================================================
--- incubator/directory/asn1/branches/rewrite/ber/src/java/org/apache/asn1/util/NestableException.java (added)
+++ incubator/directory/asn1/branches/rewrite/ber/src/java/org/apache/asn1/util/NestableException.java Wed Feb 2 23:18:42 2005
@@ -0,0 +1,257 @@
+/*
+ * Copyright 2002-2004 The Apache Software Foundation.
+ *
+ * Licensed 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.asn1.util;
+
+
+import java.io.PrintStream;
+import java.io.PrintWriter;
+
+
+/**
+ * The base class of all exceptions which can contain other exceptions.
+ * <p/>
+ * It is intended to ease the debugging by carrying on the information about the
+ * exception which was caught and provoked throwing the current exception.
+ * Catching and rethrowing may occur multiple times, and provided that all
+ * exceptions except the first one are descendants of <code>NestedException</code>,
+ * when the exception is finally printed out using any of the <code>
+ * printStackTrace()</code> methods, the stack trace will contain the
+ * information about all exceptions thrown and caught on the way. <p> Running
+ * the following program
+ * <p><blockquote><pre>
+ * 1 import org.apache.commons.lang.exception.NestableException;
+ * 2
+ * 3 public class Test {
+ * 4 public static void main( String[] args ) {
+ * 5 try {
+ * 6 a();
+ * 7 } catch(Exception e) {
+ * 8 e.printStackTrace();
+ * 9 }
+ * 10 }
+ * 11
+ * 12 public static void a() throws Exception {
+ * 13 try {
+ * 14 b();
+ * 15 } catch(Exception e) {
+ * 16 throw new NestableException("foo", e);
+ * 17 }
+ * 18 }
+ * 19
+ * 20 public static void b() throws Exception {
+ * 21 try {
+ * 22 c();
+ * 23 } catch(Exception e) {
+ * 24 throw new NestableException("bar", e);
+ * 25 }
+ * 26 }
+ * 27
+ * 28 public static void c() throws Exception {
+ * 29 throw new Exception("baz");
+ * 30 }
+ * 31 }
+ * </pre></blockquote>
+ * <p>Yields the following stack trace:
+ * <p><blockquote><pre>
+ * org.apache.commons.lang.exception.NestableException: foo
+ * at Test.a(Test.java:16)
+ * at Test.main(Test.java:6)
+ * Caused by: org.apache.commons.lang.exception.NestableException: bar
+ * at Test.b(Test.java:24)
+ * at Test.a(Test.java:14)
+ * ... 1 more
+ * Caused by: java.lang.Exception: baz
+ * at Test.c(Test.java:29)
+ * at Test.b(Test.java:22)
+ * ... 2 more
+ * </pre></blockquote><br>
+ *
+ * @author <a href="mailto:Rafal.Krzewski@e-point.pl">Rafal Krzewski</a>
+ * @author <a href="mailto:dlr@collab.net">Daniel Rall</a>
+ * @author <a href="mailto:knielsen@apache.org">Kasper Nielsen</a>
+ * @author <a href="mailto:steven@caswell.name">Steven Caswell</a>
+ * @version $Id: NestableException.java,v 1.12 2004/08/04 18:41:09 ggregory Exp
+ * $
+ * @since 1.0
+ */
+public class NestableException extends Exception implements Nestable
+{
+
+ /**
+ * The helper instance which contains much of the code which we delegate
+ * to.
+ */
+ protected NestableDelegate delegate = new NestableDelegate( this );
+
+ /**
+ * Holds the reference to the exception or error that caused this exception
+ * to be thrown.
+ */
+ private Throwable cause = null;
+
+
+ /**
+ * Constructs a new <code>NestableException</code> without specified detail
+ * message.
+ */
+ public NestableException()
+ {
+ super();
+ }
+
+
+ /**
+ * Constructs a new <code>NestableException</code> with specified detail
+ * message.
+ *
+ * @param msg The error message.
+ */
+ public NestableException( String msg )
+ {
+ super( msg );
+ }
+
+
+ /**
+ * Constructs a new <code>NestableException</code> with specified nested
+ * <code>Throwable</code>.
+ *
+ * @param cause the exception or error that caused this exception to be
+ * thrown
+ */
+ public NestableException( Throwable cause )
+ {
+ super();
+ this.cause = cause;
+ }
+
+
+ /**
+ * Constructs a new <code>NestableException</code> with specified detail
+ * message and nested <code>Throwable</code>.
+ *
+ * @param msg the error message
+ * @param cause the exception or error that caused this exception to be
+ * thrown
+ */
+ public NestableException( String msg, Throwable cause )
+ {
+ super( msg );
+ this.cause = cause;
+ }
+
+
+ public Throwable getCause()
+ {
+ return cause;
+ }
+
+
+ /**
+ * Returns the detail message string of this throwable. If it was created
+ * with a null message, returns the following: (cause==null ? null :
+ * cause.toString()).
+ */
+ public String getMessage()
+ {
+ if ( super.getMessage() != null )
+ {
+ return super.getMessage();
+ }
+ else if ( cause != null )
+ {
+ return cause.toString();
+ }
+ else
+ {
+ return null;
+ }
+ }
+
+
+ public String getMessage( int index )
+ {
+ if ( index == 0 )
+ {
+ return super.getMessage();
+ }
+ else
+ {
+ return delegate.getMessage( index );
+ }
+ }
+
+
+ public String[] getMessages()
+ {
+ return delegate.getMessages();
+ }
+
+
+ public Throwable getThrowable( int index )
+ {
+ return delegate.getThrowable( index );
+ }
+
+
+ public int getThrowableCount()
+ {
+ return delegate.getThrowableCount();
+ }
+
+
+ public Throwable[] getThrowables()
+ {
+ return delegate.getThrowables();
+ }
+
+
+ public int indexOfThrowable( Class type )
+ {
+ return delegate.indexOfThrowable( type, 0 );
+ }
+
+
+ public int indexOfThrowable( Class type, int fromIndex )
+ {
+ return delegate.indexOfThrowable( type, fromIndex );
+ }
+
+
+ public void printStackTrace()
+ {
+ delegate.printStackTrace();
+ }
+
+
+ public void printStackTrace( PrintStream out )
+ {
+ delegate.printStackTrace( out );
+ }
+
+
+ public void printStackTrace( PrintWriter out )
+ {
+ delegate.printStackTrace( out );
+ }
+
+
+ public final void printPartialStackTrace( PrintWriter out )
+ {
+ super.printStackTrace( out );
+ }
+
+}
Added: incubator/directory/asn1/branches/rewrite/ber/src/java/org/apache/asn1/util/NestableRuntimeException.java
URL: http://svn.apache.org/viewcvs/incubator/directory/asn1/branches/rewrite/ber/src/java/org/apache/asn1/util/NestableRuntimeException.java?view=auto&rev=151131
==============================================================================
--- incubator/directory/asn1/branches/rewrite/ber/src/java/org/apache/asn1/util/NestableRuntimeException.java (added)
+++ incubator/directory/asn1/branches/rewrite/ber/src/java/org/apache/asn1/util/NestableRuntimeException.java Wed Feb 2 23:18:42 2005
@@ -0,0 +1,201 @@
+/*
+ * Copyright 2002-2004 The Apache Software Foundation.
+ *
+ * Licensed 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.asn1.util;
+
+
+import java.io.PrintStream;
+import java.io.PrintWriter;
+
+
+/**
+ * The base class of all runtime exceptions which can contain other exceptions.
+ *
+ * @author <a href="mailto:Rafal.Krzewski@e-point.pl">Rafal Krzewski</a>
+ * @author <a href="mailto:dlr@collab.net">Daniel Rall</a>
+ * @author <a href="mailto:knielsen@apache.org">Kasper Nielsen</a>
+ * @author <a href="mailto:steven@caswell.name">Steven Caswell</a>
+ * @version $Id: NestableRuntimeException.java,v 1.10 2004/02/18 22:54:04
+ * ggregory Exp $
+ * @since 1.0
+ */
+public class NestableRuntimeException extends RuntimeException implements Nestable
+{
+
+ /**
+ * The helper instance which contains much of the code which we delegate
+ * to.
+ */
+ protected NestableDelegate delegate = new NestableDelegate( this );
+
+ /**
+ * Holds the reference to the exception or error that caused this exception
+ * to be thrown.
+ */
+ private Throwable cause = null;
+
+
+ /**
+ * Constructs a new <code>NestableRuntimeException</code> without specified
+ * detail message.
+ */
+ public NestableRuntimeException()
+ {
+ super();
+ }
+
+
+ /**
+ * Constructs a new <code>NestableRuntimeException</code> with specified
+ * detail message.
+ *
+ * @param msg the error message
+ */
+ public NestableRuntimeException( String msg )
+ {
+ super( msg );
+ }
+
+
+ /**
+ * Constructs a new <code>NestableRuntimeException</code> with specified
+ * nested <code>Throwable</code>.
+ *
+ * @param cause the exception or error that caused this exception to be
+ * thrown
+ */
+ public NestableRuntimeException( Throwable cause )
+ {
+ super();
+ this.cause = cause;
+ }
+
+
+ /**
+ * Constructs a new <code>NestableRuntimeException</code> with specified
+ * detail message and nested <code>Throwable</code>.
+ *
+ * @param msg the error message
+ * @param cause the exception or error that caused this exception to be
+ * thrown
+ */
+ public NestableRuntimeException( String msg, Throwable cause )
+ {
+ super( msg );
+ this.cause = cause;
+ }
+
+
+ public Throwable getCause()
+ {
+ return cause;
+ }
+
+
+ /**
+ * Returns the detail message string of this throwable. If it was created
+ * with a null message, returns the following: (cause==null ? null :
+ * cause.toString()).
+ */
+ public String getMessage()
+ {
+ if ( super.getMessage() != null )
+ {
+ return super.getMessage();
+ }
+ else if ( cause != null )
+ {
+ return cause.toString();
+ }
+ else
+ {
+ return null;
+ }
+ }
+
+
+ public String getMessage( int index )
+ {
+ if ( index == 0 )
+ {
+ return super.getMessage();
+ }
+ else
+ {
+ return delegate.getMessage( index );
+ }
+ }
+
+
+ public String[] getMessages()
+ {
+ return delegate.getMessages();
+ }
+
+
+ public Throwable getThrowable( int index )
+ {
+ return delegate.getThrowable( index );
+ }
+
+
+ public int getThrowableCount()
+ {
+ return delegate.getThrowableCount();
+ }
+
+
+ public Throwable[] getThrowables()
+ {
+ return delegate.getThrowables();
+ }
+
+
+ public int indexOfThrowable( Class type )
+ {
+ return delegate.indexOfThrowable( type, 0 );
+ }
+
+
+ public int indexOfThrowable( Class type, int fromIndex )
+ {
+ return delegate.indexOfThrowable( type, fromIndex );
+ }
+
+
+ public void printStackTrace()
+ {
+ delegate.printStackTrace();
+ }
+
+
+ public void printStackTrace( PrintStream out )
+ {
+ delegate.printStackTrace( out );
+ }
+
+
+ public void printStackTrace( PrintWriter out )
+ {
+ delegate.printStackTrace( out );
+ }
+
+
+ public final void printPartialStackTrace( PrintWriter out )
+ {
+ super.printStackTrace( out );
+ }
+
+}
Added: incubator/directory/asn1/branches/rewrite/ber/src/java/org/apache/asn1/util/ObjectUtils.java
URL: http://svn.apache.org/viewcvs/incubator/directory/asn1/branches/rewrite/ber/src/java/org/apache/asn1/util/ObjectUtils.java?view=auto&rev=151131
==============================================================================
--- incubator/directory/asn1/branches/rewrite/ber/src/java/org/apache/asn1/util/ObjectUtils.java (added)
+++ incubator/directory/asn1/branches/rewrite/ber/src/java/org/apache/asn1/util/ObjectUtils.java Wed Feb 2 23:18:42 2005
@@ -0,0 +1,305 @@
+/*
+ * Copyright 2002-2004 The Apache Software Foundation.
+ *
+ * Licensed 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.asn1.util;
+
+
+import java.io.Serializable;
+
+
+/**
+ * <p>Operations on <code>Object</code>.</p>
+ * <p/>
+ * <p>This class tries to handle <code>null</code> input gracefully. An
+ * exception will generally not be thrown for a <code>null</code> input. Each
+ * method documents its behaviour in more detail.</p>
+ *
+ * @author <a href="mailto:nissim@nksystems.com">Nissim Karpenstein</a>
+ * @author <a href="mailto:janekdb@yahoo.co.uk">Janek Bogucki</a>
+ * @author <a href="mailto:dlr@finemaltcoding.com">Daniel Rall</a>
+ * @author Stephen Colebourne
+ * @author Gary Gregory
+ * @author Mario Winterer
+ * @version $Id: ObjectUtils.java,v 1.24 2004/06/01 21:08:48 scolebourne Exp $
+ * @since 1.0
+ */
+public class ObjectUtils
+{
+
+ /**
+ * <p>Singleton used as a <code>null</code> placeholder where
+ * <code>null</code> has another meaning.</p>
+ * <p/>
+ * <p>For example, in a <code>HashMap</code> the {@link
+ * java.util.HashMap#get(java.lang.Object)} method returns <code>null</code>
+ * if the <code>Map</code> contains <code>null</code> or if there is no
+ * matching key. The <code>Null</code> placeholder can be used to
+ * distinguish between these two cases.</p>
+ * <p/>
+ * <p>Another example is <code>Hashtable</code>, where <code>null</code>
+ * cannot be stored.</p>
+ * <p/>
+ * <p>This instance is Serializable.</p>
+ */
+ public static final Null NULL = new Null();
+
+
+ /**
+ * <p><code>ObjectUtils</code> instances should NOT be constructed in
+ * standard programming. Instead, the class should be used as
+ * <code>ObjectUtils.defaultIfNull("a","b");</code>.</p>
+ * <p/>
+ * <p>This constructor is public to permit tools that require a JavaBean
+ * instance to operate.</p>
+ */
+ public ObjectUtils()
+ {
+ }
+
+ // Defaulting
+ //-----------------------------------------------------------------------
+ /**
+ * <p>Returns a default value if the object passed is
+ * <code>null</code>.</p>
+ * <p/>
+ * <pre>
+ * ObjectUtils.defaultIfNull(null, null) = null
+ * ObjectUtils.defaultIfNull(null, "") = ""
+ * ObjectUtils.defaultIfNull(null, "zz") = "zz"
+ * ObjectUtils.defaultIfNull("abc", *) = "abc"
+ * ObjectUtils.defaultIfNull(Boolean.TRUE, *) = Boolean.TRUE
+ * </pre>
+ *
+ * @param object the <code>Object</code> to test, may be
+ * <code>null</code>
+ * @param defaultValue the default value to return, may be <code>null</code>
+ * @return <code>object</code> if it is not <code>null</code>, defaultValue
+ * otherwise
+ */
+ public static Object defaultIfNull( Object object, Object defaultValue )
+ {
+ return ( object != null ? object : defaultValue );
+ }
+
+
+ /**
+ * <p>Compares two objects for equality, where either one or both objects
+ * may be <code>null</code>.</p>
+ * <p/>
+ * <pre>
+ * ObjectUtils.equals(null, null) = true
+ * ObjectUtils.equals(null, "") = false
+ * ObjectUtils.equals("", null) = false
+ * ObjectUtils.equals("", "") = true
+ * ObjectUtils.equals(Boolean.TRUE, null) = false
+ * ObjectUtils.equals(Boolean.TRUE, "true") = false
+ * ObjectUtils.equals(Boolean.TRUE, Boolean.TRUE) = true
+ * ObjectUtils.equals(Boolean.TRUE, Boolean.FALSE) = false
+ * </pre>
+ *
+ * @param object1 the first object, may be <code>null</code>
+ * @param object2 the second object, may be <code>null</code>
+ * @return <code>true</code> if the values of both objects are the same
+ */
+ public static boolean equals( Object object1, Object object2 )
+ {
+ if ( object1 == object2 )
+ {
+ return true;
+ }
+ if ( ( object1 == null ) || ( object2 == null ) )
+ {
+ return false;
+ }
+ return object1.equals( object2 );
+ }
+
+
+ /**
+ * <p>Gets the hash code of an object returning zero when the object is
+ * <code>null</code>.</p>
+ * <p/>
+ * <pre>
+ * ObjectUtils.hashCode(null) = 0
+ * ObjectUtils.hashCode(obj) = obj.hashCode()
+ * </pre>
+ *
+ * @param obj the object to obtain the hash code of, may be
+ * <code>null</code>
+ * @return the hash code of the object, or zero if null
+ * @since 2.1
+ */
+ public static int hashCode( Object obj )
+ {
+ return ( ( obj == null ) ? 0 : obj.hashCode() );
+ }
+
+ // Identity ToString
+ //-----------------------------------------------------------------------
+ /**
+ * <p>Gets the toString that would be produced by <code>Object</code> if a
+ * class did not override toString itself. <code>null</code> will return
+ * <code>null</code>.</p>
+ * <p/>
+ * <pre>
+ * ObjectUtils.identityToString(null) = null
+ * ObjectUtils.identityToString("") = "java.lang.String@1e23"
+ * ObjectUtils.identityToString(Boolean.TRUE) = "java.lang.Boolean@7fa"
+ * </pre>
+ *
+ * @param object the object to create a toString for, may be
+ * <code>null</code>
+ * @return the default toString text, or <code>null</code> if
+ * <code>null</code> passed in
+ */
+ public static String identityToString( Object object )
+ {
+ if ( object == null )
+ {
+ return null;
+ }
+ return appendIdentityToString( null, object ).toString();
+ }
+
+
+ /**
+ * <p>Appends the toString that would be produced by <code>Object</code> if
+ * a class did not override toString itself. <code>null</code> will return
+ * <code>null</code>.</p>
+ * <p/>
+ * <pre>
+ * ObjectUtils.appendIdentityToString(*, null) = null
+ * ObjectUtils.appendIdentityToString(null, "") =
+ * "java.lang.String@1e23"
+ * ObjectUtils.appendIdentityToString(null, Boolean.TRUE) =
+ * "java.lang.Boolean@7fa"
+ * ObjectUtils.appendIdentityToString(buf, Boolean.TRUE) =
+ * buf.append("java.lang.Boolean@7fa")
+ * </pre>
+ *
+ * @param buffer the buffer to append to, may be <code>null</code>
+ * @param object the object to create a toString for, may be
+ * <code>null</code>
+ * @return the default toString text, or <code>null</code> if
+ * <code>null</code> passed in
+ * @since 2.0
+ */
+ public static StringBuffer appendIdentityToString( StringBuffer buffer, Object object )
+ {
+ if ( object == null )
+ {
+ return null;
+ }
+ if ( buffer == null )
+ {
+ buffer = new StringBuffer();
+ }
+ return buffer
+ .append( object.getClass().getName() )
+ .append( '@' )
+ .append( Integer.toHexString( System.identityHashCode( object ) ) );
+ }
+
+ // ToString
+ //-----------------------------------------------------------------------
+ /**
+ * <p>Gets the <code>toString</code> of an <code>Object</code> returning an
+ * empty string ("") if <code>null</code> input.</p>
+ * <p/>
+ * <pre>
+ * ObjectUtils.toString(null) = ""
+ * ObjectUtils.toString("") = ""
+ * ObjectUtils.toString("bat") = "bat"
+ * ObjectUtils.toString(Boolean.TRUE) = "true"
+ * </pre>
+ *
+ * @param obj the Object to <code>toString</code>, may be null
+ * @return the passed in Object's toString, or nullStr if <code>null</code>
+ * input
+ * @see String#valueOf(Object)
+ * @since 2.0
+ */
+ public static String toString( Object obj )
+ {
+ return ( obj == null ? "" : obj.toString() );
+ }
+
+
+ /**
+ * <p>Gets the <code>toString</code> of an <code>Object</code> returning a
+ * specified text if <code>null</code> input.</p>
+ * <p/>
+ * <pre>
+ * ObjectUtils.toString(null, null) = null
+ * ObjectUtils.toString(null, "null") = "null"
+ * ObjectUtils.toString("", "null") = ""
+ * ObjectUtils.toString("bat", "null") = "bat"
+ * ObjectUtils.toString(Boolean.TRUE, "null") = "true"
+ * </pre>
+ *
+ * @param obj the Object to <code>toString</code>, may be null
+ * @param nullStr the String to return if <code>null</code> input, may be
+ * null
+ * @return the passed in Object's toString, or nullStr if <code>null</code>
+ * input
+ * @see String#valueOf(Object)
+ * @since 2.0
+ */
+ public static String toString( Object obj, String nullStr )
+ {
+ return ( obj == null ? nullStr : obj.toString() );
+ }
+
+ // Null
+ //-----------------------------------------------------------------------
+ /**
+ * <p>Class used as a null placeholder where <code>null</code> has another
+ * meaning.</p>
+ * <p/>
+ * <p>For example, in a <code>HashMap</code> the {@link
+ * java.util.HashMap#get(java.lang.Object)} method returns <code>null</code>
+ * if the <code>Map</code> contains <code>null</code> or if there is no
+ * matching key. The <code>Null</code> placeholder can be used to
+ * distinguish between these two cases.</p>
+ * <p/>
+ * <p>Another example is <code>Hashtable</code>, where <code>null</code>
+ * cannot be stored.</p>
+ */
+ public static class Null implements Serializable
+ {
+ // declare serialization compatibility with Commons Lang 1.0
+ private static final long serialVersionUID = 7092611880189329093L;
+
+
+ /**
+ * Restricted constructor - singleton.
+ */
+ Null()
+ {
+ }
+
+
+ /**
+ * <p>Ensure singleton.</p>
+ *
+ * @return the singleton value
+ */
+ private Object readResolve()
+ {
+ return ObjectUtils.NULL;
+ }
+ }
+
+}
Added: incubator/directory/asn1/branches/rewrite/ber/src/java/org/apache/asn1/util/RandomStringUtils.java
URL: http://svn.apache.org/viewcvs/incubator/directory/asn1/branches/rewrite/ber/src/java/org/apache/asn1/util/RandomStringUtils.java?view=auto&rev=151131
==============================================================================
--- incubator/directory/asn1/branches/rewrite/ber/src/java/org/apache/asn1/util/RandomStringUtils.java (added)
+++ incubator/directory/asn1/branches/rewrite/ber/src/java/org/apache/asn1/util/RandomStringUtils.java Wed Feb 2 23:18:42 2005
@@ -0,0 +1,334 @@
+/*
+ * Copyright 2002-2004 The Apache Software Foundation.
+ *
+ * Licensed 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.asn1.util;
+
+
+import java.util.Random;
+
+
+/**
+ * <p>Operations for random <code>String</code>s.</p>
+ *
+ * @author GenerationJava Core library
+ * @author <a href="mailto:bayard@generationjava.com">Henri Yandell</a>
+ * @author <a href="mailto:steven@caswell.name">Steven Caswell</a>
+ * @author Stephen Colebourne
+ * @author Gary Gregory
+ * @author Phil Steitz
+ * @version $Id: RandomStringUtils.java,v 1.27 2004/02/18 22:59:49 ggregory Exp
+ * $
+ * @since 1.0
+ */
+public class RandomStringUtils
+{
+
+ /**
+ * <p>Random object used by random method. This has to be not local to the
+ * random method so as to not return the same value in the same
+ * millisecond.</p>
+ */
+ private static final Random RANDOM = new Random();
+
+
+ /**
+ * <p><code>RandomStringUtils</code> instances should NOT be constructed in
+ * standard programming. Instead, the class should be used as
+ * <code>RandomStringUtils.random(5);</code>.</p>
+ * <p/>
+ * <p>This constructor is public to permit tools that require a JavaBean
+ * instance to operate.</p>
+ */
+ public RandomStringUtils()
+ {
+ }
+
+ // Random
+ //-----------------------------------------------------------------------
+ /**
+ * <p>Creates a random string whose length is the number of characters
+ * specified.</p>
+ * <p/>
+ * <p>Characters will be chosen from the set of all characters.</p>
+ *
+ * @param count the length of random string to create
+ * @return the random string
+ */
+ public static String random( int count )
+ {
+ return random( count, false, false );
+ }
+
+
+ /**
+ * <p>Creates a random string whose length is the number of characters
+ * specified.</p>
+ * <p/>
+ * <p>Characters will be chosen from the set of characters whose ASCII value
+ * is between <code>32</code> and <code>126</code> (inclusive).</p>
+ *
+ * @param count the length of random string to create
+ * @return the random string
+ */
+ public static String randomAscii( int count )
+ {
+ return random( count, 32, 127, false, false );
+ }
+
+
+ /**
+ * <p>Creates a random string whose length is the number of characters
+ * specified.</p>
+ * <p/>
+ * <p>Characters will be chosen from the set of alphabetic characters.</p>
+ *
+ * @param count the length of random string to create
+ * @return the random string
+ */
+ public static String randomAlphabetic( int count )
+ {
+ return random( count, true, false );
+ }
+
+
+ /**
+ * <p>Creates a random string whose length is the number of characters
+ * specified.</p>
+ * <p/>
+ * <p>Characters will be chosen from the set of alpha-numeric
+ * characters.</p>
+ *
+ * @param count the length of random string to create
+ * @return the random string
+ */
+ public static String randomAlphanumeric( int count )
+ {
+ return random( count, true, true );
+ }
+
+
+ /**
+ * <p>Creates a random string whose length is the number of characters
+ * specified.</p>
+ * <p/>
+ * <p>Characters will be chosen from the set of numeric characters.</p>
+ *
+ * @param count the length of random string to create
+ * @return the random string
+ */
+ public static String randomNumeric( int count )
+ {
+ return random( count, false, true );
+ }
+
+
+ /**
+ * <p>Creates a random string whose length is the number of characters
+ * specified.</p>
+ * <p/>
+ * <p>Characters will be chosen from the set of alpha-numeric characters as
+ * indicated by the arguments.</p>
+ *
+ * @param count the length of random string to create
+ * @param letters if <code>true</code>, generated string will include
+ * alphabetic characters
+ * @param numbers if <code>true</code>, generated string will include
+ * numeric characters
+ * @return the random string
+ */
+ public static String random( int count, boolean letters, boolean numbers )
+ {
+ return random( count, 0, 0, letters, numbers );
+ }
+
+
+ /**
+ * <p>Creates a random string whose length is the number of characters
+ * specified.</p>
+ * <p/>
+ * <p>Characters will be chosen from the set of alpha-numeric characters as
+ * indicated by the arguments.</p>
+ *
+ * @param count the length of random string to create
+ * @param start the position in set of chars to start at
+ * @param end the position in set of chars to end before
+ * @param letters if <code>true</code>, generated string will include
+ * alphabetic characters
+ * @param numbers if <code>true</code>, generated string will include
+ * numeric characters
+ * @return the random string
+ */
+ public static String random( int count, int start, int end, boolean letters, boolean numbers )
+ {
+ return random( count, start, end, letters, numbers, null, RANDOM );
+ }
+
+
+ /**
+ * <p>Creates a random string based on a variety of options, using default
+ * source of randomness.</p>
+ * <p/>
+ * <p>This method has exactly the same semantics as {@link
+ * #random(int,int,int,boolean,boolean,char[],Random)}, but instead of using
+ * an externally supplied source of randomness, it uses the internal static
+ * {@link Random} instance.</p>
+ *
+ * @param count the length of random string to create
+ * @param start the position in set of chars to start at
+ * @param end the position in set of chars to end before
+ * @param letters only allow letters?
+ * @param numbers only allow numbers?
+ * @param chars the set of chars to choose randoms from. If
+ * <code>null</code>, then it will use the set of all chars.
+ * @return the random string
+ * @throws ArrayIndexOutOfBoundsException if there are not <code>(end -
+ * start) + 1</code> characters in
+ * the set array.
+ */
+ public static String random( int count, int start, int end, boolean letters, boolean numbers, char[] chars )
+ {
+ return random( count, start, end, letters, numbers, chars, RANDOM );
+ }
+
+
+ /**
+ * <p>Creates a random string based on a variety of options, using supplied
+ * source of randomness.</p>
+ * <p/>
+ * <p>If start and end are both <code>0</code>, start and end are set to
+ * <code>' '</code> and <code>'z'</code>, the ASCII printable characters,
+ * will be used, unless letters and numbers are both <code>false</code>, in
+ * which case, start and end are set to <code>0</code> and
+ * <code>Integer.MAX_VALUE</code>.
+ * <p/>
+ * <p>If set is not <code>null</code>, characters between start and end are
+ * chosen.</p>
+ * <p/>
+ * <p>This method accepts a user-supplied {@link Random} instance to use as
+ * a source of randomness. By seeding a single {@link Random} instance with
+ * a fixed seed and using it for each call, the same random sequence of
+ * strings can be generated repeatedly and predictably.</p>
+ *
+ * @param count the length of random string to create
+ * @param start the position in set of chars to start at
+ * @param end the position in set of chars to end before
+ * @param letters only allow letters?
+ * @param numbers only allow numbers?
+ * @param chars the set of chars to choose randoms from. If
+ * <code>null</code>, then it will use the set of all chars.
+ * @param random a source of randomness.
+ * @return the random string
+ * @throws ArrayIndexOutOfBoundsException if there are not <code>(end -
+ * start) + 1</code> characters in
+ * the set array.
+ * @throws IllegalArgumentException if <code>count</code> < 0.
+ * @since 2.0
+ */
+ public static String random( int count, int start, int end, boolean letters, boolean numbers,
+ char[] chars, Random random )
+ {
+ if ( count == 0 )
+ {
+ return "";
+ }
+ else if ( count < 0 )
+ {
+ throw new IllegalArgumentException( "Requested random string length " + count + " is less than 0." );
+ }
+ if ( ( start == 0 ) && ( end == 0 ) )
+ {
+ end = 'z' + 1;
+ start = ' ';
+ if ( !letters && !numbers )
+ {
+ start = 0;
+ end = Integer.MAX_VALUE;
+ }
+ }
+
+ StringBuffer buffer = new StringBuffer();
+ int gap = end - start;
+
+ while ( count-- != 0 )
+ {
+ char ch;
+ if ( chars == null )
+ {
+ ch = ( char ) ( random.nextInt( gap ) + start );
+ }
+ else
+ {
+ ch = chars[random.nextInt( gap ) + start];
+ }
+ if ( ( letters && numbers && Character.isLetterOrDigit( ch ) )
+ || ( letters && Character.isLetter( ch ) )
+ || ( numbers && Character.isDigit( ch ) )
+ || ( !letters && !numbers ) )
+ {
+ buffer.append( ch );
+ }
+ else
+ {
+ count++;
+ }
+ }
+ return buffer.toString();
+ }
+
+
+ /**
+ * <p>Creates a random string whose length is the number of characters
+ * specified.</p>
+ * <p/>
+ * <p>Characters will be chosen from the set of characters specified.</p>
+ *
+ * @param count the length of random string to create
+ * @param chars the String containing the set of characters to use, may be
+ * null
+ * @return the random string
+ * @throws IllegalArgumentException if <code>count</code> < 0.
+ */
+ public static String random( int count, String chars )
+ {
+ if ( chars == null )
+ {
+ return random( count, 0, 0, false, false, null, RANDOM );
+ }
+ return random( count, chars.toCharArray() );
+ }
+
+
+ /**
+ * <p>Creates a random string whose length is the number of characters
+ * specified.</p>
+ * <p/>
+ * <p>Characters will be chosen from the set of characters specified.</p>
+ *
+ * @param count the length of random string to create
+ * @param chars the character array containing the set of characters to use,
+ * may be null
+ * @return the random string
+ * @throws IllegalArgumentException if <code>count</code> < 0.
+ */
+ public static String random( int count, char[] chars )
+ {
+ if ( chars == null )
+ {
+ return random( count, 0, 0, false, false, null, RANDOM );
+ }
+ return random( count, 0, chars.length, false, false, chars, RANDOM );
+ }
+
+}
Added: incubator/directory/asn1/branches/rewrite/ber/src/java/org/apache/asn1/util/ReflectionToStringBuilder.java
URL: http://svn.apache.org/viewcvs/incubator/directory/asn1/branches/rewrite/ber/src/java/org/apache/asn1/util/ReflectionToStringBuilder.java?view=auto&rev=151131
==============================================================================
--- incubator/directory/asn1/branches/rewrite/ber/src/java/org/apache/asn1/util/ReflectionToStringBuilder.java (added)
+++ incubator/directory/asn1/branches/rewrite/ber/src/java/org/apache/asn1/util/ReflectionToStringBuilder.java Wed Feb 2 23:18:42 2005
@@ -0,0 +1,729 @@
+/*
+ * Copyright 2002-2004 The Apache Software Foundation.
+ *
+ * Licensed 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.asn1.util;
+
+
+import java.lang.reflect.AccessibleObject;
+import java.lang.reflect.Field;
+import java.lang.reflect.Modifier;
+import java.util.HashSet;
+import java.util.Set;
+
+
+/**
+ * <p/>
+ * Assists in implementing {@link Object#toString()}methods using reflection.
+ * </p>
+ * <p/>
+ * <p/>
+ * This class uses reflection to determine the fields to append. Because these
+ * fields are usually private, the class uses {@link java.lang.reflect.AccessibleObject#setAccessible(java.lang.reflect.AccessibleObject[],
+ * boolean)} to change the visibility of the fields. This will fail under a
+ * security manager, unless the appropriate permissions are set up correctly.
+ * </p>
+ * <p/>
+ * <p/>
+ * A typical invocation for this method would look like: </p>
+ * <p/>
+ * <pre>
+ * public String toString() {
+ * return ReflectionToStringBuilder.toString(this);
+ * }</pre>
+ * <p/>
+ * <p/>
+ * <p/>
+ * <p/>
+ * You can also use the builder to debug 3rd party objects: </p>
+ * <p/>
+ * <pre>
+ * System.out.println("An object: " + ReflectionToStringBuilder.toString(anObject));</pre>
+ * <p/>
+ * <p/>
+ * <p/>
+ * <p/>
+ * A subclass can control field output by overriding the methods: <ul>
+ * <li>{@link #accept(java.lang.reflect.Field)}</li> <li>{@link
+ * #getValue(java.lang.reflect.Field)}</li> </ul> </p>
+ * <p/>
+ * For example, this method does <i>not</i> include the <code>password</code>
+ * field in the returned <code>String</code>: </p>
+ * <p/>
+ * <pre>
+ * public String toString() {
+ * return (new ReflectionToStringBuilder(this) {
+ * protected boolean accept(Field f) {
+ * return super.accept(f) && !f.getName().equals("password");
+ * }
+ * }).toString();
+ * }</pre>
+ * <p/>
+ * <p/>
+ * <p/>
+ * <p/>
+ * The exact format of the <code>toString</code> is determined by the {@link
+ * ToStringStyle} passed into the constructor. </p>
+ *
+ * @author Gary Gregory
+ * @author Stephen Colebourne
+ * @author Pete Gieser
+ * @version $Id: ReflectionToStringBuilder.java,v 1.15 2003/12/02 19:11:58
+ * ggregory Exp $
+ * @since 2.0
+ */
+public class ReflectionToStringBuilder extends ToStringBuilder
+{
+ /**
+ * <p/>
+ * A registry of objects used by <code>reflectionToString</code> methods to
+ * detect cyclical object references and avoid infinite loops. </p>
+ */
+ private static ThreadLocal registry = new ThreadLocal()
+ {
+ protected synchronized Object initialValue()
+ {
+ // The HashSet implementation is not synchronized,
+ // which is just what we need here.
+ return new HashSet();
+ }
+ };
+
+
+ /**
+ * <p/>
+ * Returns the registry of objects being traversed by the
+ * <code>reflectionToString</code> methods in the current thread. </p>
+ *
+ * @return Set the registry of objects being traversed
+ */
+ static Set getRegistry()
+ {
+ return ( Set ) registry.get();
+ }
+
+
+ /**
+ * <p/>
+ * Returns <code>true</code> if the registry contains the given object. Used
+ * by the reflection methods to avoid infinite loops. </p>
+ *
+ * @param value The object to lookup in the registry.
+ * @return boolean <code>true</code> if the registry contains the given
+ * object.
+ */
+ static boolean isRegistered( Object value )
+ {
+ return getRegistry().contains( value );
+ }
+
+
+ /**
+ * <p/>
+ * Registers the given object. Used by the reflection methods to avoid
+ * infinite loops. </p>
+ *
+ * @param value The object to register.
+ */
+ static void register( Object value )
+ {
+ getRegistry().add( value );
+ }
+
+
+ /**
+ * <p/>
+ * This method uses reflection to build a suitable <code>toString</code>
+ * using the default <code>ToStringStyle</code>.
+ * <p/>
+ * <p/>
+ * It uses <code>AccessibleObject.setAccessible</code> to gain access to
+ * private fields. This means that it will throw a security exception if run
+ * under a security manager, if the permissions are not set up correctly. It
+ * is also not as efficient as testing explicitly. </p>
+ * <p/>
+ * <p/>
+ * Transient members will be not be included, as they are likely derived.
+ * Static fields will not be included. Superclass fields will be appended.
+ * </p>
+ *
+ * @param object the Object to be output
+ * @return the String result
+ * @throws IllegalArgumentException if the Object is <code>null</code>
+ */
+ public static String toString( Object object )
+ {
+ return toString( object, null, false, false, null );
+ }
+
+
+ /**
+ * <p/>
+ * This method uses reflection to build a suitable <code>toString</code>.
+ * </p>
+ * <p/>
+ * <p/>
+ * It uses <code>AccessibleObject.setAccessible</code> to gain access to
+ * private fields. This means that it will throw a security exception if run
+ * under a security manager, if the permissions are not set up correctly. It
+ * is also not as efficient as testing explicitly. </p>
+ * <p/>
+ * <p/>
+ * Transient members will be not be included, as they are likely derived.
+ * Static fields will not be included. Superclass fields will be appended.
+ * </p>
+ * <p/>
+ * <p/>
+ * If the style is <code>null</code>, the default <code>ToStringStyle</code>
+ * is used. </p>
+ *
+ * @param object the Object to be output
+ * @param style the style of the <code>toString</code> to create, may be
+ * <code>null</code>
+ * @return the String result
+ * @throws IllegalArgumentException if the Object or <code>ToStringStyle</code>
+ * is <code>null</code>
+ */
+ public static String toString( Object object, ToStringStyle style )
+ {
+ return toString( object, style, false, false, null );
+ }
+
+
+ /**
+ * <p/>
+ * This method uses reflection to build a suitable <code>toString</code>.
+ * </p>
+ * <p/>
+ * <p/>
+ * It uses <code>AccessibleObject.setAccessible</code> to gain access to
+ * private fields. This means that it will throw a security exception if run
+ * under a security manager, if the permissions are not set up correctly. It
+ * is also not as efficient as testing explicitly. </p>
+ * <p/>
+ * <p/>
+ * If the <code>outputTransients</code> is <code>true</code>, transient
+ * members will be output, otherwise they are ignored, as they are likely
+ * derived fields, and not part of the value of the Object. </p>
+ * <p/>
+ * <p/>
+ * Static fields will not be included. Superclass fields will be appended.
+ * </p>
+ * <p/>
+ * <p/>
+ * If the style is <code>null</code>, the default <code>ToStringStyle</code>
+ * is used. </p>
+ *
+ * @param object the Object to be output
+ * @param style the style of the <code>toString</code> to create,
+ * may be <code>null</code>
+ * @param outputTransients whether to include transient fields
+ * @return the String result
+ * @throws IllegalArgumentException if the Object is <code>null</code>
+ */
+ public static String toString( Object object, ToStringStyle style, boolean outputTransients )
+ {
+ return toString( object, style, outputTransients, false, null );
+ }
+
+
+ /**
+ * <p/>
+ * This method uses reflection to build a suitable <code>toString</code>.
+ * </p>
+ * <p/>
+ * <p/>
+ * It uses <code>AccessibleObject.setAccessible</code> to gain access to
+ * private fields. This means that it will throw a security exception if run
+ * under a security manager, if the permissions are not set up correctly. It
+ * is also not as efficient as testing explicitly. </p>
+ * <p/>
+ * <p/>
+ * If the <code>outputTransients</code> is <code>true</code>, transient
+ * fields will be output, otherwise they are ignored, as they are likely
+ * derived fields, and not part of the value of the Object. </p>
+ * <p/>
+ * <p/>
+ * If the <code>outputStatics</code> is <code>true</code>, static fields
+ * will be output, otherwise they are ignored. </p>
+ * <p/>
+ * <p/>
+ * Static fields will not be included. Superclass fields will be appended.
+ * </p>
+ * <p/>
+ * <p/>
+ * If the style is <code>null</code>, the default <code>ToStringStyle</code>
+ * is used. </p>
+ *
+ * @param object the Object to be output
+ * @param style the style of the <code>toString</code> to create,
+ * may be <code>null</code>
+ * @param outputTransients whether to include transient fields
+ * @param outputStatics whether to include transient fields
+ * @return the String result
+ * @throws IllegalArgumentException if the Object is <code>null</code>
+ */
+ public static String toString( Object object, ToStringStyle style, boolean outputTransients, boolean outputStatics )
+ {
+ return toString( object, style, outputTransients, outputStatics, null );
+ }
+
+
+ /**
+ * <p/>
+ * This method uses reflection to build a suitable <code>toString</code>.
+ * </p>
+ * <p/>
+ * <p/>
+ * It uses <code>AccessibleObject.setAccessible</code> to gain access to
+ * private fields. This means that it will throw a security exception if run
+ * under a security manager, if the permissions are not set up correctly. It
+ * is also not as efficient as testing explicitly. </p>
+ * <p/>
+ * <p/>
+ * If the <code>outputTransients</code> is <code>true</code>, transient
+ * fields will be output, otherwise they are ignored, as they are likely
+ * derived fields, and not part of the value of the Object. </p>
+ * <p/>
+ * <p/>
+ * If the <code>outputStatics</code> is <code>true</code>, static fields
+ * will be output, otherwise they are ignored. </p>
+ * <p/>
+ * <p/>
+ * Superclass fields will be appended up to and including the specified
+ * superclass. A null superclass is treated as <code>java.lang.Object</code>.
+ * </p>
+ * <p/>
+ * <p/>
+ * If the style is <code>null</code>, the default <code>ToStringStyle</code>
+ * is used. </p>
+ *
+ * @param object the Object to be output
+ * @param style the style of the <code>toString</code> to create,
+ * may be <code>null</code>
+ * @param outputTransients whether to include transient fields
+ * @param outputStatics whether to include static fields
+ * @param reflectUpToClass the superclass to reflect up to (inclusive), may
+ * be <code>null</code>
+ * @return the String result
+ * @throws IllegalArgumentException if the Object is <code>null</code>
+ */
+ public static String toString( Object object, ToStringStyle style, boolean outputTransients, boolean outputStatics,
+ Class reflectUpToClass )
+ {
+ return new ReflectionToStringBuilder( object, style, null, reflectUpToClass, outputTransients, outputStatics )
+ .toString();
+ }
+
+
+ /**
+ * <p/>
+ * Unregisters the given object. </p>
+ * <p/>
+ * <p/>
+ * Used by the reflection methods to avoid infinite loops. </p>
+ *
+ * @param value The object to unregister.
+ */
+ static void unregister( Object value )
+ {
+ getRegistry().remove( value );
+ }
+
+
+ /**
+ * Whether or not to append static fields.
+ */
+ private boolean appendStatics = false;
+
+ /**
+ * Whether or not to append transient fields.
+ */
+ private boolean appendTransients = false;
+
+ /**
+ * The last super class to stop appending fields for.
+ */
+ private Class upToClass = null;
+
+
+ /**
+ * <p/>
+ * Constructor. </p>
+ * <p/>
+ * <p/>
+ * This constructor outputs using the default style set with
+ * <code>setDefaultStyle</code>. </p>
+ *
+ * @param object the Object to build a <code>toString</code> for, must not
+ * be <code>null</code>
+ * @throws IllegalArgumentException if the Object passed in is <code>null</code>
+ */
+ public ReflectionToStringBuilder( Object object )
+ {
+ super( object );
+ }
+
+
+ /**
+ * <p/>
+ * Constructor. </p>
+ * <p/>
+ * <p/>
+ * If the style is <code>null</code>, the default style is used. </p>
+ *
+ * @param object the Object to build a <code>toString</code> for, must not
+ * be <code>null</code>
+ * @param style the style of the <code>toString</code> to create, may be
+ * <code>null</code>
+ * @throws IllegalArgumentException if the Object passed in is <code>null</code>
+ */
+ public ReflectionToStringBuilder( Object object, ToStringStyle style )
+ {
+ super( object, style );
+ }
+
+
+ /**
+ * <p/>
+ * Constructor. </p>
+ * <p/>
+ * <p/>
+ * If the style is <code>null</code>, the default style is used. </p>
+ * <p/>
+ * <p/>
+ * If the buffer is <code>null</code>, a new one is created. </p>
+ *
+ * @param object the Object to build a <code>toString</code> for
+ * @param style the style of the <code>toString</code> to create, may be
+ * <code>null</code>
+ * @param buffer the <code>StringBuffer</code> to populate, may be
+ * <code>null</code>
+ * @throws IllegalArgumentException if the Object passed in is <code>null</code>
+ */
+ public ReflectionToStringBuilder( Object object, ToStringStyle style, StringBuffer buffer )
+ {
+ super( object, style, buffer );
+ }
+
+
+ /**
+ * Constructor.
+ *
+ * @param object the Object to build a <code>toString</code> for
+ * @param style the style of the <code>toString</code> to create,
+ * may be <code>null</code>
+ * @param buffer the <code>StringBuffer</code> to populate, may be
+ * <code>null</code>
+ * @param reflectUpToClass the superclass to reflect up to (inclusive), may
+ * be <code>null</code>
+ * @param outputTransients whether to include transient fields
+ * @deprecated Use {@link #ReflectionToStringBuilder(Object,ToStringStyle,StringBuffer,Class,boolean,boolean)}.
+ */
+ public ReflectionToStringBuilder( Object object, ToStringStyle style, StringBuffer buffer, Class reflectUpToClass,
+ boolean outputTransients )
+ {
+ super( object, style, buffer );
+ this.setUpToClass( reflectUpToClass );
+ this.setAppendTransients( outputTransients );
+ }
+
+
+ /**
+ * Constructor.
+ *
+ * @param object the Object to build a <code>toString</code> for
+ * @param style the style of the <code>toString</code> to create,
+ * may be <code>null</code>
+ * @param buffer the <code>StringBuffer</code> to populate, may be
+ * <code>null</code>
+ * @param reflectUpToClass the superclass to reflect up to (inclusive), may
+ * be <code>null</code>
+ * @param outputTransients whether to include transient fields
+ * @param outputStatics whether to include static fields
+ */
+ public ReflectionToStringBuilder( Object object, ToStringStyle style, StringBuffer buffer, Class reflectUpToClass,
+ boolean outputTransients, boolean outputStatics )
+ {
+ super( object, style, buffer );
+ this.setUpToClass( reflectUpToClass );
+ this.setAppendTransients( outputTransients );
+ this.setAppendStatics( outputStatics );
+ }
+
+
+ /**
+ * Returns whether or not to append the given <code>Field</code>. <ul>
+ * <li>Transient fields are appended only if {@link #isAppendTransients()}
+ * returns <code>true</code>. <li>Static fields are appended only if {@link
+ * #isAppendStatics()} returns <code>true</code>. <li>Inner class fields are
+ * not appened.</li> </ul>
+ *
+ * @param field The Field to test.
+ * @return Whether or not to append the given <code>Field</code>.
+ */
+ protected boolean accept( Field field )
+ {
+ if ( field.getName().indexOf( '$' ) != -1 )
+ {
+ // Reject field from inner class.
+ return false;
+ }
+ if ( Modifier.isTransient( field.getModifiers() ) && !this.isAppendTransients() )
+ {
+ // transients.
+ return false;
+ }
+ if ( Modifier.isStatic( field.getModifiers() ) && !this.isAppendStatics() )
+ {
+ // transients.
+ return false;
+ }
+ return true;
+ }
+
+
+ /**
+ * <p/>
+ * Appends the fields and values defined by the given object of the given
+ * Class. </p>
+ * <p/>
+ * <p/>
+ * If a cycle is detected as an object is "toString()'ed", such an
+ * object is rendered as if <code>Object.toString()</code> had been called
+ * and not implemented by the object. </p>
+ *
+ * @param clazz The class of object parameter
+ */
+ protected void appendFieldsIn( Class clazz )
+ {
+ if ( isRegistered( this.getObject() ) )
+ {
+ // The object has already been appended, therefore we have an
+ // object cycle.
+ // Append a simple Object.toString style string. The field name is
+ // already appended at this point.
+ this.appendAsObjectToString( this.getObject() );
+ return;
+ }
+ try
+ {
+ this.registerObject();
+ if ( clazz.isArray() )
+ {
+ this.reflectionAppendArray( this.getObject() );
+ return;
+ }
+ Field[] fields = clazz.getDeclaredFields();
+ AccessibleObject.setAccessible( fields, true );
+ for ( int i = 0; i < fields.length; i++ )
+ {
+ Field field = fields[i];
+ String fieldName = field.getName();
+ if ( this.accept( field ) )
+ {
+ try
+ {
+ // Warning: Field.get(Object) creates wrappers objects
+ // for primitive types.
+ Object fieldValue = this.getValue( field );
+ if ( isRegistered( fieldValue ) && !field.getType().isPrimitive() )
+ {
+ // A known field value has already been appended,
+ // therefore we have an object cycle,
+ // append a simple Object.toString style string.
+ this.getStyle().appendFieldStart( this.getStringBuffer(), fieldName );
+ this.appendAsObjectToString( fieldValue );
+ // The recursion out of
+ // builder.append(fieldName, fieldValue);
+ // below will append the field
+ // end marker.
+ }
+ else
+ {
+ try
+ {
+ this.registerObject();
+ this.append( fieldName, fieldValue );
+ }
+ finally
+ {
+ this.unregisterObject();
+ }
+ }
+ }
+ catch ( IllegalAccessException ex )
+ {
+ //this can't happen. Would get a Security exception
+ // instead
+ //throw a runtime exception in case the impossible
+ // happens.
+ throw new InternalError( "Unexpected IllegalAccessException: " + ex.getMessage() );
+ }
+ }
+ }
+ }
+ finally
+ {
+ this.unregisterObject();
+ }
+ }
+
+
+ /**
+ * <p/>
+ * Gets the last super class to stop appending fields for. </p>
+ *
+ * @return The last super class to stop appending fields for.
+ */
+ public Class getUpToClass()
+ {
+ return this.upToClass;
+ }
+
+
+ /**
+ * <p/>
+ * Calls <code>java.lang.reflect.Field.get(Object)</code>. </p>
+ *
+ * @param field The Field to query.
+ * @return The Object from the given Field.
+ * @throws IllegalArgumentException see {@link java.lang.reflect.Field#get(Object)}
+ * @throws IllegalAccessException see {@link java.lang.reflect.Field#get(Object)}
+ * @see java.lang.reflect.Field#get(Object)
+ */
+ protected Object getValue( Field field ) throws IllegalArgumentException, IllegalAccessException
+ {
+ return field.get( this.getObject() );
+ }
+
+
+ /**
+ * <p/>
+ * Gets whether or not to append static fields. </p>
+ *
+ * @return Whether or not to append static fields.
+ */
+ public boolean isAppendStatics()
+ {
+ return this.appendStatics;
+ }
+
+
+ /**
+ * <p/>
+ * Gets whether or not to append transient fields. </p>
+ *
+ * @return Whether or not to append transient fields.
+ */
+ public boolean isAppendTransients()
+ {
+ return this.appendTransients;
+ }
+
+
+ /**
+ * <p/>
+ * Append to the <code>toString</code> an <code>Object</code> array. </p>
+ *
+ * @param array the array to add to the <code>toString</code>
+ * @return this
+ */
+ public ToStringBuilder reflectionAppendArray( Object array )
+ {
+ this.getStyle().reflectionAppendArrayDetail( this.getStringBuffer(), null, array );
+ return this;
+ }
+
+
+ /**
+ * <p/>
+ * Registers this builder's source object to avoid infinite loops when
+ * processing circular object references. </p>
+ */
+ void registerObject()
+ {
+ register( this.getObject() );
+ }
+
+
+ /**
+ * <p/>
+ * Sets whether or not to append static fields. </p>
+ *
+ * @param appendStatics Whether or not to append static fields.
+ */
+ public void setAppendStatics( boolean appendStatics )
+ {
+ this.appendStatics = appendStatics;
+ }
+
+
+ /**
+ * <p/>
+ * Sets whether or not to append transient fields. </p>
+ *
+ * @param appendTransients Whether or not to append transient fields.
+ */
+ public void setAppendTransients( boolean appendTransients )
+ {
+ this.appendTransients = appendTransients;
+ }
+
+
+ /**
+ * <p/>
+ * Sets the last super class to stop appending fields for. </p>
+ *
+ * @param clazz The last super class to stop appending fields for.
+ */
+ public void setUpToClass( Class clazz )
+ {
+ this.upToClass = clazz;
+ }
+
+
+ /**
+ * <p/>
+ * Gets the String built by this builder. </p>
+ *
+ * @return the built string
+ */
+ public String toString()
+ {
+ if ( this.getObject() == null )
+ {
+ return this.getStyle().getNullText();
+ }
+ Class clazz = this.getObject().getClass();
+ this.appendFieldsIn( clazz );
+ while ( clazz.getSuperclass() != null && clazz != this.getUpToClass() )
+ {
+ clazz = clazz.getSuperclass();
+ this.appendFieldsIn( clazz );
+ }
+ return super.toString();
+ }
+
+
+ /**
+ * <p/>
+ * Unregisters this builder's source object to avoid infinite loops when
+ * processing circular object references. </p>
+ */
+ void unregisterObject()
+ {
+ unregister( this.getObject() );
+ }
+}