You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@directory.apache.org by tr...@apache.org on 2006/01/20 14:48:55 UTC
svn commit: r370807 [17/22] - in /directory/sandbox/trustin/mina-spi: ./
core/src/main/java/org/apache/mina/common/
core/src/main/java/org/apache/mina/common/support/
core/src/main/java/org/apache/mina/common/support/discovery/
core/src/main/java/org/a...
Added: directory/sandbox/trustin/mina-spi/core/src/main/java/org/apache/mina/common/support/lang/exception/NestableDelegate.java
URL: http://svn.apache.org/viewcvs/directory/sandbox/trustin/mina-spi/core/src/main/java/org/apache/mina/common/support/lang/exception/NestableDelegate.java?rev=370807&view=auto
==============================================================================
--- directory/sandbox/trustin/mina-spi/core/src/main/java/org/apache/mina/common/support/lang/exception/NestableDelegate.java (added)
+++ directory/sandbox/trustin/mina-spi/core/src/main/java/org/apache/mina/common/support/lang/exception/NestableDelegate.java Fri Jan 20 05:47:50 2006
@@ -0,0 +1,410 @@
+/*
+ * Copyright 2002-2005 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.mina.common.support.lang.exception;
+
+import java.io.PrintStream;
+import java.io.PrintWriter;
+import java.io.Serializable;
+import java.io.StringWriter;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Collections;
+import java.util.Iterator;
+import java.util.List;
+
+/**
+ * <p>A shared implementation of the nestable exception functionality.</p>
+ * <p>
+ * The code is shared between
+ * {@link org.apache.mina.common.support.lang.exception.NestableError NestableError},
+ * {@link org.apache.mina.common.support.lang.exception.NestableException NestableException} and
+ * {@link org.apache.mina.common.support.lang.exception.NestableRuntimeException NestableRuntimeException}.
+ * </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
+ * @since 1.0
+ * @version $Id$
+ */
+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.mina.common.support.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.
+ * This exists for backwards compatability, setting it to false will return
+ * the library to v1.0 behaviour (but will affect all users of the library
+ * in the classloader).
+ * @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.
+ * This exists for backwards compatability, setting it to false will return
+ * the library to v1.0 behaviour (but will affect all users of the library
+ * in the classloader).
+ * @since 2.0
+ */
+ public static boolean trimStackFrames = true;
+
+ /**
+ * Whether to match subclasses via indexOf.
+ * This public flag may be set by calling code, typically in initialisation.
+ * This exists for backwards compatability, setting it to false will return
+ * the library to v2.0 behaviour (but will affect all users of the library
+ * in the classloader).
+ * @since 2.1
+ */
+ public static boolean matchSubclasses = 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, or a subclass, in the chain of <code>Throwable</code>s
+ * with an index greater than or equal to the specified index.
+ * The method returns -1 if the specified type is not found in the chain.
+ * <p>
+ * NOTE: From v2.1, we have clarified the <code>Nestable</code> interface
+ * such that this method matches subclasses.
+ * If you want to NOT match subclasses, please use
+ * {@link ExceptionUtils#indexOfThrowable(Throwable, Class, int)}
+ * (which is avaiable in all versions of lang).
+ * An alternative is to use the public static flag {@link #matchSubclasses}
+ * on <code>NestableDelegate</code>, however this is not recommended.
+ *
+ * @param type the type to find, subclasses match, null returns -1
+ * @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 (type == null) {
+ return -1;
+ }
+ 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);
+ }
+ if (matchSubclasses) {
+ for (int i = fromIndex; i < throwables.length; i++) {
+ if (type.isAssignableFrom(throwables[i].getClass())) {
+ return i;
+ }
+ }
+ } else {
+ for (int i = fromIndex; i < throwables.length; i++) {
+ if (type.equals(throwables[i].getClass())) {
+ 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()])
+ );
+ }
+ }
+ }
+}
Propchange: directory/sandbox/trustin/mina-spi/core/src/main/java/org/apache/mina/common/support/lang/exception/NestableDelegate.java
------------------------------------------------------------------------------
svn:keywords = HeadURL Id LastChangedBy LastChangedDate LastChangedRevision
Added: directory/sandbox/trustin/mina-spi/core/src/main/java/org/apache/mina/common/support/lang/exception/NestableError.java
URL: http://svn.apache.org/viewcvs/directory/sandbox/trustin/mina-spi/core/src/main/java/org/apache/mina/common/support/lang/exception/NestableError.java?rev=370807&view=auto
==============================================================================
--- directory/sandbox/trustin/mina-spi/core/src/main/java/org/apache/mina/common/support/lang/exception/NestableError.java (added)
+++ directory/sandbox/trustin/mina-spi/core/src/main/java/org/apache/mina/common/support/lang/exception/NestableError.java Fri Jan 20 05:47:50 2006
@@ -0,0 +1,154 @@
+/*
+ * Copyright 2002-2005 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.mina.common.support.lang.exception;
+
+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>
+ * @see org.apache.mina.common.support.lang.exception.NestableException
+ * @since 1.0
+ * @version $Id$
+ */
+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()).
+ *
+ * @return String message string of the throwable
+ */
+ 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);
+ }
+}
Propchange: directory/sandbox/trustin/mina-spi/core/src/main/java/org/apache/mina/common/support/lang/exception/NestableError.java
------------------------------------------------------------------------------
svn:keywords = HeadURL Id LastChangedBy LastChangedDate LastChangedRevision
Added: directory/sandbox/trustin/mina-spi/core/src/main/java/org/apache/mina/common/support/lang/exception/NestableException.java
URL: http://svn.apache.org/viewcvs/directory/sandbox/trustin/mina-spi/core/src/main/java/org/apache/mina/common/support/lang/exception/NestableException.java?rev=370807&view=auto
==============================================================================
--- directory/sandbox/trustin/mina-spi/core/src/main/java/org/apache/mina/common/support/lang/exception/NestableException.java (added)
+++ directory/sandbox/trustin/mina-spi/core/src/main/java/org/apache/mina/common/support/lang/exception/NestableException.java Fri Jan 20 05:47:50 2006
@@ -0,0 +1,215 @@
+/*
+ * Copyright 2002-2005 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.mina.common.support.lang.exception;
+
+import java.io.PrintStream;
+import java.io.PrintWriter;
+
+/**
+ * The base class of all exceptions which can contain other exceptions.
+ *
+ * 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.mina.common.support.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.mina.common.support.lang.exception.NestableException: foo
+ * at Test.a(Test.java:16)
+ * at Test.main(Test.java:6)
+ * Caused by: org.apache.mina.common.support.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>
+ * @since 1.0
+ * @version $Id$
+ */
+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()).
+ *
+ * @return String message string of the throwable
+ */
+ 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);
+ }
+
+}
Propchange: directory/sandbox/trustin/mina-spi/core/src/main/java/org/apache/mina/common/support/lang/exception/NestableException.java
------------------------------------------------------------------------------
svn:keywords = HeadURL Id LastChangedBy LastChangedDate LastChangedRevision
Added: directory/sandbox/trustin/mina-spi/core/src/main/java/org/apache/mina/common/support/lang/exception/NestableRuntimeException.java
URL: http://svn.apache.org/viewcvs/directory/sandbox/trustin/mina-spi/core/src/main/java/org/apache/mina/common/support/lang/exception/NestableRuntimeException.java?rev=370807&view=auto
==============================================================================
--- directory/sandbox/trustin/mina-spi/core/src/main/java/org/apache/mina/common/support/lang/exception/NestableRuntimeException.java (added)
+++ directory/sandbox/trustin/mina-spi/core/src/main/java/org/apache/mina/common/support/lang/exception/NestableRuntimeException.java Fri Jan 20 05:47:50 2006
@@ -0,0 +1,159 @@
+/*
+ * Copyright 2002-2005 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.mina.common.support.lang.exception;
+
+import java.io.PrintStream;
+import java.io.PrintWriter;
+
+/**
+ * The base class of all runtime exceptions which can contain other
+ * exceptions.
+ *
+ * @see org.apache.mina.common.support.lang.exception.NestableException
+ * @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>
+ * @since 1.0
+ * @version $Id$
+ */
+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()).
+ *
+ * @return String message string of the throwable
+ */
+ 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);
+ }
+
+}
Propchange: directory/sandbox/trustin/mina-spi/core/src/main/java/org/apache/mina/common/support/lang/exception/NestableRuntimeException.java
------------------------------------------------------------------------------
svn:keywords = HeadURL Id LastChangedBy LastChangedDate LastChangedRevision
Added: directory/sandbox/trustin/mina-spi/core/src/main/java/org/apache/mina/common/support/lang/exception/package.html
URL: http://svn.apache.org/viewcvs/directory/sandbox/trustin/mina-spi/core/src/main/java/org/apache/mina/common/support/lang/exception/package.html?rev=370807&view=auto
==============================================================================
--- directory/sandbox/trustin/mina-spi/core/src/main/java/org/apache/mina/common/support/lang/exception/package.html (added)
+++ directory/sandbox/trustin/mina-spi/core/src/main/java/org/apache/mina/common/support/lang/exception/package.html Fri Jan 20 05:47:50 2006
@@ -0,0 +1,26 @@
+<!--
+Copyright 2002-2005 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.
+-->
+<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>
+<p>Lastly, {@link org.apache.commons.lang.exception.ExceptionUtils}
+also contains <code>Throwable</code> manipulation and examination routines.</p>
+@since 1.0
+</body>
+</html>
Propchange: directory/sandbox/trustin/mina-spi/core/src/main/java/org/apache/mina/common/support/lang/exception/package.html
------------------------------------------------------------------------------
svn:keywords = HeadURL Id LastChangedBy LastChangedDate LastChangedRevision
Added: directory/sandbox/trustin/mina-spi/core/src/main/java/org/apache/mina/common/support/lang/math/DoubleRange.java
URL: http://svn.apache.org/viewcvs/directory/sandbox/trustin/mina-spi/core/src/main/java/org/apache/mina/common/support/lang/math/DoubleRange.java?rev=370807&view=auto
==============================================================================
--- directory/sandbox/trustin/mina-spi/core/src/main/java/org/apache/mina/common/support/lang/math/DoubleRange.java (added)
+++ directory/sandbox/trustin/mina-spi/core/src/main/java/org/apache/mina/common/support/lang/math/DoubleRange.java Fri Jan 20 05:47:50 2006
@@ -0,0 +1,410 @@
+/*
+ * Copyright 2002-2005 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.mina.common.support.lang.math;
+
+import java.io.Serializable;
+
+/**
+ * <p><code>DoubleRange</code> represents an inclusive range of <code>double</code>s.</p>
+ *
+ * @author Stephen Colebourne
+ * @since 2.0
+ * @version $Id$
+ */
+public final class DoubleRange extends Range implements Serializable {
+
+ private static final long serialVersionUID = 71849363892740L;
+
+ /**
+ * The minimum number in this range (inclusive).
+ */
+ private final double min;
+ /**
+ * The maximum number in this range (inclusive).
+ */
+ private final double max;
+
+ /**
+ * Cached output minObject (class is immutable).
+ */
+ private transient Double minObject = null;
+ /**
+ * Cached output maxObject (class is immutable).
+ */
+ private transient Double maxObject = null;
+ /**
+ * Cached output hashCode (class is immutable).
+ */
+ private transient int hashCode = 0;
+ /**
+ * Cached output toString (class is immutable).
+ */
+ private transient String toString = null;
+
+ /**
+ * <p>Constructs a new <code>DoubleRange</code> using the specified
+ * number as both the minimum and maximum in this range.</p>
+ *
+ * @param number the number to use for this range
+ * @throws IllegalArgumentException if the number is <code>NaN</code>
+ */
+ public DoubleRange(double number) {
+ super();
+ if (Double.isNaN(number)) {
+ throw new IllegalArgumentException("The number must not be NaN");
+ }
+ this.min = number;
+ this.max = number;
+ }
+
+ /**
+ * <p>Constructs a new <code>DoubleRange</code> using the specified
+ * number as both the minimum and maximum in this range.</p>
+ *
+ * @param number the number to use for this range, must not
+ * be <code>null</code>
+ * @throws IllegalArgumentException if the number is <code>null</code>
+ * @throws IllegalArgumentException if the number is <code>NaN</code>
+ */
+ public DoubleRange(Number number) {
+ super();
+ if (number == null) {
+ throw new IllegalArgumentException("The number must not be null");
+ }
+ this.min = number.doubleValue();
+ this.max = number.doubleValue();
+ if (Double.isNaN(min) || Double.isNaN(max)) {
+ throw new IllegalArgumentException("The number must not be NaN");
+ }
+ if (number instanceof Double) {
+ this.minObject = (Double) number;
+ this.maxObject = (Double) number;
+ }
+ }
+
+ /**
+ * <p>Constructs a new <code>DoubleRange</code> with the specified
+ * minimum and maximum numbers (both inclusive).</p>
+ *
+ * <p>The arguments may be passed in the order (min,max) or (max,min). The
+ * getMinimum and getMaximum methods will return the correct values.</p>
+ *
+ * @param number1 first number that defines the edge of the range, inclusive
+ * @param number2 second number that defines the edge of the range, inclusive
+ * @throws IllegalArgumentException if either number is <code>NaN</code>
+ */
+ public DoubleRange(double number1, double number2) {
+ super();
+ if (Double.isNaN(number1) || Double.isNaN(number2)) {
+ throw new IllegalArgumentException("The numbers must not be NaN");
+ }
+ if (number2 < number1) {
+ this.min = number2;
+ this.max = number1;
+ } else {
+ this.min = number1;
+ this.max = number2;
+ }
+ }
+
+ /**
+ * <p>Constructs a new <code>DoubleRange</code> with the specified
+ * minimum and maximum numbers (both inclusive).</p>
+ *
+ * <p>The arguments may be passed in the order (min,max) or (max,min). The
+ * getMinimum and getMaximum methods will return the correct values.</p>
+ *
+ * @param number1 first number that defines the edge of the range, inclusive
+ * @param number2 second number that defines the edge of the range, inclusive
+ * @throws IllegalArgumentException if either number is <code>null</code>
+ * @throws IllegalArgumentException if either number is <code>NaN</code>
+ */
+ public DoubleRange(Number number1, Number number2) {
+ super();
+ if (number1 == null || number2 == null) {
+ throw new IllegalArgumentException("The numbers must not be null");
+ }
+ double number1val = number1.doubleValue();
+ double number2val = number2.doubleValue();
+ if (Double.isNaN(number1val) || Double.isNaN(number2val)) {
+ throw new IllegalArgumentException("The numbers must not be NaN");
+ }
+ if (number2val < number1val) {
+ this.min = number2val;
+ this.max = number1val;
+ if (number2 instanceof Double) {
+ this.minObject = (Double) number2;
+ }
+ if (number1 instanceof Double) {
+ this.maxObject = (Double) number1;
+ }
+ } else {
+ this.min = number1val;
+ this.max = number2val;
+ if (number1 instanceof Double) {
+ this.minObject = (Double) number1;
+ }
+ if (number2 instanceof Double) {
+ this.maxObject = (Double) number2;
+ }
+ }
+ }
+
+ // Accessors
+ //--------------------------------------------------------------------
+
+ /**
+ * <p>Returns the minimum number in this range.</p>
+ *
+ * @return the minimum number in this range
+ */
+ public Number getMinimumNumber() {
+ if (minObject == null) {
+ minObject = new Double(min);
+ }
+ return minObject;
+ }
+
+ /**
+ * <p>Gets the minimum number in this range as a <code>long</code>.</p>
+ *
+ * <p>This conversion can lose information for large values or decimals.</p>
+ *
+ * @return the minimum number in this range
+ */
+ public long getMinimumLong() {
+ return (long) min;
+ }
+
+ /**
+ * <p>Gets the minimum number in this range as a <code>int</code>.</p>
+ *
+ * <p>This conversion can lose information for large values or decimals.</p>
+ *
+ * @return the minimum number in this range
+ */
+ public int getMinimumInteger() {
+ return (int) min;
+ }
+
+ /**
+ * <p>Gets the minimum number in this range as a <code>double</code>.</p>
+ *
+ * @return the minimum number in this range
+ */
+ public double getMinimumDouble() {
+ return min;
+ }
+
+ /**
+ * <p>Gets the minimum number in this range as a <code>float</code>.</p>
+ *
+ * <p>This conversion can lose information for large values.</p>
+ *
+ * @return the minimum number in this range
+ */
+ public float getMinimumFloat() {
+ return (float) min;
+ }
+
+ /**
+ * <p>Returns the maximum number in this range.</p>
+ *
+ * @return the maximum number in this range
+ */
+ public Number getMaximumNumber() {
+ if (maxObject == null) {
+ maxObject = new Double(max);
+ }
+ return maxObject;
+ }
+
+ /**
+ * <p>Gets the maximum number in this range as a <code>long</code>.</p>
+ *
+ * <p>This conversion can lose information for large values or decimals.</p>
+ *
+ * @return the maximum number in this range
+ */
+ public long getMaximumLong() {
+ return (long) max;
+ }
+
+ /**
+ * <p>Gets the maximum number in this range as a <code>int</code>.</p>
+ *
+ * <p>This conversion can lose information for large values or decimals.</p>
+ *
+ * @return the maximum number in this range
+ */
+ public int getMaximumInteger() {
+ return (int) max;
+ }
+
+ /**
+ * <p>Gets the maximum number in this range as a <code>double</code>.</p>
+ *
+ * @return the maximum number in this range
+ */
+ public double getMaximumDouble() {
+ return max;
+ }
+
+ /**
+ * <p>Gets the maximum number in this range as a <code>float</code>.</p>
+ *
+ * <p>This conversion can lose information for large values.</p>
+ *
+ * @return the maximum number in this range
+ */
+ public float getMaximumFloat() {
+ return (float) max;
+ }
+
+ // Tests
+ //--------------------------------------------------------------------
+
+ /**
+ * <p>Tests whether the specified <code>number</code> occurs within
+ * this range using <code>double</code> comparison.</p>
+ *
+ * <p><code>null</code> is handled and returns <code>false</code>.</p>
+ *
+ * @param number the number to test, may be <code>null</code>
+ * @return <code>true</code> if the specified number occurs within this range
+ */
+ public boolean containsNumber(Number number) {
+ if (number == null) {
+ return false;
+ }
+ return containsDouble(number.doubleValue());
+ }
+
+ /**
+ * <p>Tests whether the specified <code>double</code> occurs within
+ * this range using <code>double</code> comparison.</p>
+ *
+ * <p>This implementation overrides the superclass for performance as it is
+ * the most common case.</p>
+ *
+ * @param value the double to test
+ * @return <code>true</code> if the specified number occurs within this
+ * range by <code>double</code> comparison
+ */
+ public boolean containsDouble(double value) {
+ return value >= min && value <= max;
+ }
+
+ // Range tests
+ //--------------------------------------------------------------------
+
+ /**
+ * <p>Tests whether the specified range occurs entirely within this range
+ * using <code>double</code> comparison.</p>
+ *
+ * <p><code>null</code> is handled and returns <code>false</code>.</p>
+ *
+ * @param range the range to test, may be <code>null</code>
+ * @return <code>true</code> if the specified range occurs entirely within this range
+ * @throws IllegalArgumentException if the range is not of this type
+ */
+ public boolean containsRange(Range range) {
+ if (range == null) {
+ return false;
+ }
+ return containsDouble(range.getMinimumDouble())
+ && containsDouble(range.getMaximumDouble());
+ }
+
+ /**
+ * <p>Tests whether the specified range overlaps with this range
+ * using <code>double</code> comparison.</p>
+ *
+ * <p><code>null</code> is handled and returns <code>false</code>.</p>
+ *
+ * @param range the range to test, may be <code>null</code>
+ * @return <code>true</code> if the specified range overlaps with this range
+ */
+ public boolean overlapsRange(Range range) {
+ if (range == null) {
+ return false;
+ }
+ return range.containsDouble(min)
+ || range.containsDouble(max)
+ || containsDouble(range.getMinimumDouble());
+ }
+
+ // Basics
+ //--------------------------------------------------------------------
+
+ /**
+ * <p>Compares this range to another object to test if they are equal.</p>.
+ *
+ * <p>To be equal, the class, minimum and maximum must be equal.</p>
+ *
+ * @param obj the reference object with which to compare
+ * @return <code>true</code> if this object is equal
+ */
+ public boolean equals(Object obj) {
+ if (obj == this) {
+ return true;
+ }
+ if (obj instanceof DoubleRange == false) {
+ return false;
+ }
+ DoubleRange range = (DoubleRange) obj;
+ return (Double.doubleToLongBits(min) == Double.doubleToLongBits(range.min) &&
+ Double.doubleToLongBits(max) == Double.doubleToLongBits(range.max));
+ }
+
+ /**
+ * <p>Gets a hashCode for the range.</p>
+ *
+ * @return a hash code value for this object
+ */
+ public int hashCode() {
+ if (hashCode == 0) {
+ hashCode = 17;
+ hashCode = 37 * hashCode + getClass().hashCode();
+ long lng = Double.doubleToLongBits(min);
+ hashCode = 37 * hashCode + ((int) (lng ^ (lng >> 32)));
+ lng = Double.doubleToLongBits(max);
+ hashCode = 37 * hashCode + ((int) (lng ^ (lng >> 32)));
+ }
+ return hashCode;
+ }
+
+ /**
+ * <p>Gets the range as a <code>String</code>.</p>
+ *
+ * <p>The format of the String is 'Range[<i>min</i>,<i>max</i>]'.</p>
+ *
+ * @return the <code>String</code> representation of this range
+ */
+ public String toString() {
+ if (toString == null) {
+ StringBuffer buf = new StringBuffer(32);
+ buf.append("Range[");
+ buf.append(min);
+ buf.append(',');
+ buf.append(max);
+ buf.append(']');
+ toString = buf.toString();
+ }
+ return toString;
+ }
+
+}
Propchange: directory/sandbox/trustin/mina-spi/core/src/main/java/org/apache/mina/common/support/lang/math/DoubleRange.java
------------------------------------------------------------------------------
svn:keywords = HeadURL Id LastChangedBy LastChangedDate LastChangedRevision
Added: directory/sandbox/trustin/mina-spi/core/src/main/java/org/apache/mina/common/support/lang/math/FloatRange.java
URL: http://svn.apache.org/viewcvs/directory/sandbox/trustin/mina-spi/core/src/main/java/org/apache/mina/common/support/lang/math/FloatRange.java?rev=370807&view=auto
==============================================================================
--- directory/sandbox/trustin/mina-spi/core/src/main/java/org/apache/mina/common/support/lang/math/FloatRange.java (added)
+++ directory/sandbox/trustin/mina-spi/core/src/main/java/org/apache/mina/common/support/lang/math/FloatRange.java Fri Jan 20 05:47:50 2006
@@ -0,0 +1,404 @@
+/*
+ * Copyright 2002-2005 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.mina.common.support.lang.math;
+
+import java.io.Serializable;
+
+/**
+ * <p><code>FloatRange</code> represents an inclusive range of <code>float</code>s.</p>
+ *
+ * @author Stephen Colebourne
+ * @since 2.0
+ * @version $Id$
+ */
+public final class FloatRange extends Range implements Serializable {
+
+ private static final long serialVersionUID = 71849363892750L;
+
+ /**
+ * The minimum number in this range (inclusive).
+ */
+ private final float min;
+ /**
+ * The maximum number in this range (inclusive).
+ */
+ private final float max;
+
+ /**
+ * Cached output minObject (class is immutable).
+ */
+ private transient Float minObject = null;
+ /**
+ * Cached output maxObject (class is immutable).
+ */
+ private transient Float maxObject = null;
+ /**
+ * Cached output hashCode (class is immutable).
+ */
+ private transient int hashCode = 0;
+ /**
+ * Cached output toString (class is immutable).
+ */
+ private transient String toString = null;
+
+ /**
+ * <p>Constructs a new <code>FloatRange</code> using the specified
+ * number as both the minimum and maximum in this range.</p>
+ *
+ * @param number the number to use for this range
+ * @throws IllegalArgumentException if the number is <code>NaN</code>
+ */
+ public FloatRange(float number) {
+ super();
+ if (Float.isNaN(number)) {
+ throw new IllegalArgumentException("The number must not be NaN");
+ }
+ this.min = number;
+ this.max = number;
+ }
+
+ /**
+ * <p>Constructs a new <code>FloatRange</code> using the specified
+ * number as both the minimum and maximum in this range.</p>
+ *
+ * @param number the number to use for this range, must not
+ * be <code>null</code>
+ * @throws IllegalArgumentException if the number is <code>null</code>
+ * @throws IllegalArgumentException if the number is <code>NaN</code>
+ */
+ public FloatRange(Number number) {
+ super();
+ if (number == null) {
+ throw new IllegalArgumentException("The number must not be null");
+ }
+ this.min = number.floatValue();
+ this.max = number.floatValue();
+ if (Float.isNaN(min) || Float.isNaN(max)) {
+ throw new IllegalArgumentException("The number must not be NaN");
+ }
+ if (number instanceof Float) {
+ this.minObject = (Float) number;
+ this.maxObject = (Float) number;
+ }
+ }
+
+ /**
+ * <p>Constructs a new <code>FloatRange</code> with the specified
+ * minimum and maximum numbers (both inclusive).</p>
+ *
+ * <p>The arguments may be passed in the order (min,max) or (max,min). The
+ * getMinimum and getMaximum methods will return the correct values.</p>
+ *
+ * @param number1 first number that defines the edge of the range, inclusive
+ * @param number2 second number that defines the edge of the range, inclusive
+ * @throws IllegalArgumentException if either number is <code>NaN</code>
+ */
+ public FloatRange(float number1, float number2) {
+ super();
+ if (Float.isNaN(number1) || Float.isNaN(number2)) {
+ throw new IllegalArgumentException("The numbers must not be NaN");
+ }
+ if (number2 < number1) {
+ this.min = number2;
+ this.max = number1;
+ } else {
+ this.min = number1;
+ this.max = number2;
+ }
+ }
+
+ /**
+ * <p>Constructs a new <code>FloatRange</code> with the specified
+ * minimum and maximum numbers (both inclusive).</p>
+ *
+ * <p>The arguments may be passed in the order (min,max) or (max,min). The
+ * getMinimum and getMaximum methods will return the correct values.</p>
+ *
+ * @param number1 first number that defines the edge of the range, inclusive
+ * @param number2 second number that defines the edge of the range, inclusive
+ * @throws IllegalArgumentException if either number is <code>null</code>
+ * @throws IllegalArgumentException if either number is <code>NaN</code>
+ */
+ public FloatRange(Number number1, Number number2) {
+ super();
+ if (number1 == null || number2 == null) {
+ throw new IllegalArgumentException("The numbers must not be null");
+ }
+ float number1val = number1.floatValue();
+ float number2val = number2.floatValue();
+ if (Float.isNaN(number1val) || Float.isNaN(number2val)) {
+ throw new IllegalArgumentException("The numbers must not be NaN");
+ }
+ if (number2val < number1val) {
+ this.min = number2val;
+ this.max = number1val;
+ if (number2 instanceof Float) {
+ this.minObject = (Float) number2;
+ }
+ if (number1 instanceof Float) {
+ this.maxObject = (Float) number1;
+ }
+ } else {
+ this.min = number1val;
+ this.max = number2val;
+ if (number1 instanceof Float) {
+ this.minObject = (Float) number1;
+ }
+ if (number2 instanceof Float) {
+ this.maxObject = (Float) number2;
+ }
+ }
+ }
+
+ // Accessors
+ //--------------------------------------------------------------------
+
+ /**
+ * <p>Returns the minimum number in this range.</p>
+ *
+ * @return the minimum number in this range
+ */
+ public Number getMinimumNumber() {
+ if (minObject == null) {
+ minObject = new Float(min);
+ }
+ return minObject;
+ }
+
+ /**
+ * <p>Gets the minimum number in this range as a <code>long</code>.</p>
+ *
+ * <p>This conversion can lose information for large values or decimals.</p>
+ *
+ * @return the minimum number in this range
+ */
+ public long getMinimumLong() {
+ return (long) min;
+ }
+
+ /**
+ * <p>Gets the minimum number in this range as a <code>int</code>.</p>
+ *
+ * <p>This conversion can lose information for large values or decimals.</p>
+ *
+ * @return the minimum number in this range
+ */
+ public int getMinimumInteger() {
+ return (int) min;
+ }
+
+ /**
+ * <p>Gets the minimum number in this range as a <code>double</code>.</p>
+ *
+ * @return the minimum number in this range
+ */
+ public double getMinimumDouble() {
+ return min;
+ }
+
+ /**
+ * <p>Gets the minimum number in this range as a <code>float</code>.</p>
+ *
+ * @return the minimum number in this range
+ */
+ public float getMinimumFloat() {
+ return min;
+ }
+
+ /**
+ * <p>Returns the maximum number in this range.</p>
+ *
+ * @return the maximum number in this range
+ */
+ public Number getMaximumNumber() {
+ if (maxObject == null) {
+ maxObject = new Float(max);
+ }
+ return maxObject;
+ }
+
+ /**
+ * <p>Gets the maximum number in this range as a <code>long</code>.</p>
+ *
+ * <p>This conversion can lose information for large values or decimals.</p>
+ *
+ * @return the maximum number in this range
+ */
+ public long getMaximumLong() {
+ return (long) max;
+ }
+
+ /**
+ * <p>Gets the maximum number in this range as a <code>int</code>.</p>
+ *
+ * <p>This conversion can lose information for large values or decimals.</p>
+ *
+ * @return the maximum number in this range
+ */
+ public int getMaximumInteger() {
+ return (int) max;
+ }
+
+ /**
+ * <p>Gets the maximum number in this range as a <code>double</code>.</p>
+ *
+ * @return the maximum number in this range
+ */
+ public double getMaximumDouble() {
+ return max;
+ }
+
+ /**
+ * <p>Gets the maximum number in this range as a <code>float</code>.</p>
+ *
+ * @return the maximum number in this range
+ */
+ public float getMaximumFloat() {
+ return max;
+ }
+
+ // Tests
+ //--------------------------------------------------------------------
+
+ /**
+ * <p>Tests whether the specified <code>number</code> occurs within
+ * this range using <code>float</code> comparison.</p>
+ *
+ * <p><code>null</code> is handled and returns <code>false</code>.</p>
+ *
+ * @param number the number to test, may be <code>null</code>
+ * @return <code>true</code> if the specified number occurs within this range
+ */
+ public boolean containsNumber(Number number) {
+ if (number == null) {
+ return false;
+ }
+ return containsFloat(number.floatValue());
+ }
+
+ /**
+ * <p>Tests whether the specified <code>float</code> occurs within
+ * this range using <code>float</code> comparison.</p>
+ *
+ * <p>This implementation overrides the superclass for performance as it is
+ * the most common case.</p>
+ *
+ * @param value the float to test
+ * @return <code>true</code> if the specified number occurs within this
+ * range by <code>float</code> comparison
+ */
+ public boolean containsFloat(float value) {
+ return value >= min && value <= max;
+ }
+
+ // Range tests
+ //--------------------------------------------------------------------
+
+ /**
+ * <p>Tests whether the specified range occurs entirely within this range
+ * using <code>float</code> comparison.</p>
+ *
+ * <p><code>null</code> is handled and returns <code>false</code>.</p>
+ *
+ * @param range the range to test, may be <code>null</code>
+ * @return <code>true</code> if the specified range occurs entirely within this range
+ * @throws IllegalArgumentException if the range is not of this type
+ */
+ public boolean containsRange(Range range) {
+ if (range == null) {
+ return false;
+ }
+ return containsFloat(range.getMinimumFloat()) &&
+ containsFloat(range.getMaximumFloat());
+ }
+
+ /**
+ * <p>Tests whether the specified range overlaps with this range
+ * using <code>float</code> comparison.</p>
+ *
+ * <p><code>null</code> is handled and returns <code>false</code>.</p>
+ *
+ * @param range the range to test, may be <code>null</code>
+ * @return <code>true</code> if the specified range overlaps with this range
+ */
+ public boolean overlapsRange(Range range) {
+ if (range == null) {
+ return false;
+ }
+ return range.containsFloat(min) ||
+ range.containsFloat(max) ||
+ containsFloat(range.getMinimumFloat());
+ }
+
+ // Basics
+ //--------------------------------------------------------------------
+
+ /**
+ * <p>Compares this range to another object to test if they are equal.</p>.
+ *
+ * <p>To be equal, the class, minimum and maximum must be equal.</p>
+ *
+ * @param obj the reference object with which to compare
+ * @return <code>true</code> if this object is equal
+ */
+ public boolean equals(Object obj) {
+ if (obj == this) {
+ return true;
+ }
+ if (obj instanceof FloatRange == false) {
+ return false;
+ }
+ FloatRange range = (FloatRange) obj;
+ return (Float.floatToIntBits(min) == Float.floatToIntBits(range.min) &&
+ Float.floatToIntBits(max) == Float.floatToIntBits(range.max));
+ }
+
+ /**
+ * <p>Gets a hashCode for the range.</p>
+ *
+ * @return a hash code value for this object
+ */
+ public int hashCode() {
+ if (hashCode == 0) {
+ hashCode = 17;
+ hashCode = 37 * hashCode + getClass().hashCode();
+ hashCode = 37 * hashCode + Float.floatToIntBits(min);
+ hashCode = 37 * hashCode + Float.floatToIntBits(max);
+ }
+ return hashCode;
+ }
+
+ /**
+ * <p>Gets the range as a <code>String</code>.</p>
+ *
+ * <p>The format of the String is 'Range[<i>min</i>,<i>max</i>]'.</p>
+ *
+ * @return the <code>String</code> representation of this range
+ */
+ public String toString() {
+ if (toString == null) {
+ StringBuffer buf = new StringBuffer(32);
+ buf.append("Range[");
+ buf.append(min);
+ buf.append(',');
+ buf.append(max);
+ buf.append(']');
+ toString = buf.toString();
+ }
+ return toString;
+ }
+
+}
Propchange: directory/sandbox/trustin/mina-spi/core/src/main/java/org/apache/mina/common/support/lang/math/FloatRange.java
------------------------------------------------------------------------------
svn:keywords = HeadURL Id LastChangedBy LastChangedDate LastChangedRevision