001: /*
002: * This file or a portion of this file is licensed under the terms of
003: * the Globus Toolkit Public License, found in file GTPL, or at
004: * http://www.globus.org/toolkit/download/license.html. This notice must
005: * appear in redistributions of this file, with or without modification.
006: *
007: * Redistributions of this Software, with or without modification, must
008: * reproduce the GTPL in: (1) the Software, or (2) the Documentation or
009: * some other similar material which is provided with the Software (if
010: * any).
011: *
012: * Copyright 1999-2004 University of Chicago and The University of
013: * Southern California. All rights reserved.
014: */
015:
016: package org.griphyn.common.util;
017:
018: import org.griphyn.common.util.DynamicLoader;
019:
020: /**
021: * The base exception class to notify of errors, while instantiating classes
022: * via any of the factories. Each factory, should throw an exception that is
023: * a subclass of this class.
024: *
025: * @author Karan Vahi
026: * @author Jens-S. Vöckler
027: * @author Gaurang Mehta
028: */
029: public class FactoryException
030: // method A: no need to change interface, obsfuscated use, though
031: extends java.lang.RuntimeException
032: //method B: needs API small change, but makes things clear.
033: //extends java.lang.Exception
034: {
035:
036: /**
037: * The default classname that is associated with the exception.
038: */
039: public static final String DEFAULT_NAME = "Object";
040:
041: /**
042: * The name of the class that was trying to be instantiated when this
043: * error occured, or some other signifier like module name.
044: */
045: protected String mClassname;
046:
047: /**
048: * Converts most of the common instantiation exceptions from the class
049: * loader into an error message. Use for getting sensible error messages,
050: * of the causes that are associated with a FactoryException. The index
051: * in the messages starts from 0.
052: *
053: * @return the error message
054: */
055: public String convertException() {
056: return convertException(mClassname, this , 0);
057: }
058:
059: /**
060: * Converts most of the common instantiation exceptions from the class
061: * loader into an error message. Use for getting sensible error messages,
062: * of the causes that are associated with a FactoryException. The index
063: * in the messages starts from 0.
064: *
065: * @param index the index to start from.
066: *
067: * @return the error message.
068: */
069: public String convertException(int index) {
070: return convertException(mClassname, this , index);
071: }
072:
073: /**
074: * Converts most of the common instantiation exceptions from the class
075: * loader into an error message. Use for getting sensible error messages,
076: * of the causes that are associated with a FactoryException.
077: *
078: * @param classname the class that was trying to be loaded or some other
079: * signifier.
080: * @param e the FactoryException that is thrown.
081: * @param index the index to start from.
082: *
083: * @return the error message.
084: */
085: public static String convertException(String classname,
086: Throwable e, int index) {
087: Throwable prev = null;
088: StringBuffer message = new StringBuffer();
089:
090: int i = index;
091: //append all the causes
092: for (Throwable cause = e; cause != null; cause = cause
093: .getCause()) {
094: message.append("\n [").append(Integer.toString(++i))
095: .append("]: ");
096: if (cause instanceof FactoryException) {
097: message.append(cause.getMessage());
098: classname = ((FactoryException) cause).getClassname();
099: } else if (prev != null && prev instanceof FactoryException) {
100: //we can use the convert method
101: message.append(DynamicLoader.convertExceptionToString(
102: classname, cause));
103: } else {
104: //for all other exceptions just chain the message
105: message.append(cause.getMessage());
106: }
107:
108: //append just one elment of stack trace for each exception
109: message.append(" at ").append(cause.getStackTrace()[0]);
110:
111: prev = cause;
112: }
113: return message.toString();
114: }
115:
116: /**
117: * Constructs a <code>FactoryException</code> with no detail
118: * message. The associated classname is set to value specified by
119: * <code>DEFAULT_NAME</code>.
120: *
121: * @param msg the detailed message.
122: *
123: * @see #DEFAULT_NAME
124: */
125: public FactoryException(String msg) {
126: super (msg);
127: mClassname = this .DEFAULT_NAME;
128: }
129:
130: /**
131: * Constructs a <code>FactoryException</code> with the specified detailed
132: * message.
133: *
134: * @param msg is the detailed message.
135: * @param classname the name of class that was trying to be instantiated or
136: * some other signifier like module name.
137: */
138: public FactoryException(String msg, String classname) {
139: super (msg);
140: mClassname = classname;
141: }
142:
143: /**
144: * Constructs a <code>FactoryException</code> with the
145: * specified detailed message and a cause. The associated classname is set
146: * to value specified by <code>DEFAULT_NAME</code>.
147: *
148: * @param msg is the detailed message that is to be logged.
149: * @param cause is the cause (which is saved for later retrieval by the
150: * {@link java.lang.Throwable#getCause()} method). A <code>null</code>
151: * value is permitted, and indicates that the cause is nonexistent or
152: * unknown.
153: *
154: * @see #DEFAULT_NAME
155: */
156: public FactoryException(String msg, Throwable cause) {
157: super (msg, cause);
158: mClassname = this .DEFAULT_NAME;
159: }
160:
161: /**
162: * Constructs a <code>FactoryException</code> with the
163: * specified detailed message and a cause.
164: *
165: * @param msg is the detailed message that is to be logged.
166: * @param classname the name of class that was trying to be instantiated.
167: * @param cause is the cause (which is saved for later retrieval by the
168: * {@link java.lang.Throwable#getCause()} method). A <code>null</code>
169: * value is permitted, and indicates that the cause is nonexistent or
170: * unknown.
171: */
172: public FactoryException(String msg, String classname,
173: Throwable cause) {
174: super (msg, cause);
175: mClassname = classname;
176: }
177:
178: /**
179: * Returns the name of the class that was trying to be loaded when this
180: * error occured, or some other signifier like a module name.
181: *
182: * @return the name of the class.
183: */
184: public String getClassname() {
185: return this.mClassname;
186: }
187:
188: }
|