001: /*
002: * BEGIN_HEADER - DO NOT EDIT
003: *
004: * The contents of this file are subject to the terms
005: * of the Common Development and Distribution License
006: * (the "License"). You may not use this file except
007: * in compliance with the License.
008: *
009: * You can obtain a copy of the license at
010: * https://open-esb.dev.java.net/public/CDDLv1.0.html.
011: * See the License for the specific language governing
012: * permissions and limitations under the License.
013: *
014: * When distributing Covered Code, include this CDDL
015: * HEADER in each file and include the License file at
016: * https://open-esb.dev.java.net/public/CDDLv1.0.html.
017: * If applicable add the following below this CDDL HEADER,
018: * with the fields enclosed by brackets "[]" replaced with
019: * your own identifying information: Portions Copyright
020: * [year] [name of copyright owner]
021: */
022:
023: /*
024: * @(#)JBIRemoteException.java
025: * Copyright 2004-2007 Sun Microsystems, Inc. All Rights Reserved.
026: *
027: * END_HEADER - DO NOT EDIT
028: */
029: package com.sun.jbi.ui.common;
030:
031: import java.io.PrintStream;
032: import java.io.PrintWriter;
033: import java.io.Serializable;
034: import java.io.StringWriter;
035: import java.util.ArrayList;
036: import javax.management.MBeanException;
037: import javax.management.RuntimeMBeanException;
038: import javax.management.RuntimeOperationsException;
039:
040: /**
041: * A Remote Exception class that saves the cause exception stack trace in a
042: * buffer for serialization. By throwing this exception on jmx server side on
043: * mbean operations and attributes, we don't have to include the cause exception
044: * classes on the client side. This class also allows the server side code to
045: * add error code, so that the remote client can get the error code and display
046: * the message from its local bundle.
047: *
048: * @author graj
049: */
050:
051: public class JBIRemoteException extends Exception implements
052: Serializable {
053: /** aCuase StackTrace */
054: protected StringBuffer mCauseStackTrace;
055:
056: /** aCuase Message trace */
057: protected String[] mCauseMessageTrace;
058:
059: /**
060: * Determines if a de-serialized file is compatible with this class.
061: *
062: * 1. Run serialver -show from the command line
063: * 2. Point the tool to the class file including the package,
064: * for example:
065: * com.sun.jbi.ui.common.JBIRemoteException - without the .class The
066: * serialver docs for Windows OS is at:
067: * http://java.sun.com/j2se/1.5.0/docs/tooldocs/windows/serialver.html and
068: * Unix OS is at:
069: * http://java.sun.com/j2se/1.5.0/docs/tooldocs/solaris/serialver.html
070: *
071: * Maintainers must change this value if and only if the new version of this
072: * class is not compatible with old versions. See Sun docs for <a
073: * href=http://java.sun.com/products/jdk/1.1/docs/guide
074: * /serialization/spec/version.doc.html> details. </a>
075: */
076: static final long serialVersionUID = 4431187824092164710L;
077:
078: /**
079: * Creates a new instance of JBIException with an exception message.
080: *
081: * @param aMessage
082: * String describing this exception.
083: */
084: public JBIRemoteException(String aMessage) {
085: this (aMessage, (Throwable) null);
086: }
087:
088: /**
089: * Creates a new instance of JBIException with the specified cause.
090: *
091: * @param aCause
092: * Throwable which represents an underlying problem (or null).
093: */
094: public JBIRemoteException(Throwable aCause) {
095: this ((String) null, aCause);
096: }
097:
098: /**
099: * Creates a new instance of JBIException with the specified message and
100: * cause.
101: *
102: * @param aMessage
103: * String describing this exception.
104: * @param aCause
105: * Throwable which represents an underlying problem (or null).
106: */
107: public JBIRemoteException(String aMessage, Throwable aCause) {
108: super (aMessage);
109: initCauseTrace(aCause);
110: // if ( aCause != null )
111: // {
112: // aCause.printStackTrace();
113: // }
114: }
115:
116: /**
117: * Creates a new instance of JBIException.
118: *
119: * @param exception
120: */
121: public JBIRemoteException(JBIRemoteException exception) {
122: this .mCauseMessageTrace = exception.getCauseMessageTrace();
123: this .mCauseStackTrace = exception.getCauseStackTrace();
124: }
125:
126: /**
127: * initializes the stacktrace and messages from cause
128: *
129: * @param aCause
130: * a cause
131: */
132: public void initCauseTrace(Throwable aCause) {
133: this .mCauseStackTrace = null;
134: this .mCauseMessageTrace = null;
135: if (aCause == null) {
136: return;
137: }
138:
139: // save the stack trace
140: StringWriter traceWriter = new StringWriter();
141: PrintWriter printWriter = new PrintWriter(traceWriter);
142: aCause.printStackTrace(printWriter);
143: printWriter.close();
144: this .mCauseStackTrace = traceWriter.getBuffer();
145:
146: ArrayList list = new ArrayList();
147:
148: for (Throwable nextCause = aCause; nextCause != null; nextCause = nextCause
149: .getCause()) {
150: list.add(nextCause.getMessage());
151: }
152: this .mCauseMessageTrace = (String[]) list
153: .toArray(new String[0]);
154: }
155:
156: /**
157: * Returns the detail message string of this throwable.
158: *
159: * @return the detail message string of this <tt>Throwable</tt> instance
160: * (which may be <tt>null</tt>). + the cause messages
161: */
162: public String getMessage() {
163: String mainMsg = super .getMessage();
164:
165: if (this .mCauseMessageTrace == null
166: || this .mCauseMessageTrace.length <= 0) {
167: return mainMsg;
168: }
169:
170: boolean hasMainMsg = (mainMsg != null);
171:
172: StringWriter stringWriter = new StringWriter();
173: PrintWriter msgWriter = new PrintWriter(stringWriter);
174: if (hasMainMsg) {
175: msgWriter.println(mainMsg);
176: msgWriter.print(Util.getCommonI18NBundle().getMessage(
177: "jbi.remote.exception.msg.root.cause.msg",
178: this .mCauseMessageTrace[0]));
179: } else {
180: msgWriter.print(this .mCauseMessageTrace[0]);
181: }
182:
183: for (int i = 1; i < this .mCauseMessageTrace.length; ++i) {
184: msgWriter.println();
185: msgWriter.print(Util.getCommonI18NBundle().getMessage(
186: "jbi.remote.exception.msg.root.cause.msg",
187: this .mCauseMessageTrace[i]));
188: }
189: msgWriter.close();
190: return stringWriter.toString();
191: }
192:
193: /**
194: * gets the cuase trace in a string buffer
195: *
196: * @return trace in a string buffer
197: */
198: public String[] getCauseMessageTrace() {
199: return this .mCauseMessageTrace;
200: }
201:
202: /**
203: * gets the cuase trace in a string buffer
204: *
205: * @return trace in a string buffer
206: */
207: public StringBuffer getCauseStackTrace() {
208: return this .mCauseStackTrace;
209: }
210:
211: /**
212: * override method
213: *
214: * @param s
215: * writer
216: */
217: public void printStackTrace(PrintWriter s) {
218: super .printStackTrace(s);
219: // s.println("Error Code : " + this.mErrorCode);
220: synchronized (s) {
221: if (this .mCauseStackTrace != null) {
222: s.println(this .mCauseStackTrace.toString());
223: }
224: }
225: }
226:
227: /**
228: * override method
229: *
230: * @param s
231: * stream
232: */
233: public void printStackTrace(PrintStream s) {
234: super .printStackTrace(s);
235: // s.println("Error Code : " + this.mErrorCode);
236: synchronized (s) {
237: if (this .mCauseStackTrace != null) {
238: s.println(this .mCauseStackTrace.toString());
239: }
240: }
241: }
242:
243: /**
244: * retrieves the exception message and try to construct the jbi mgmt message
245: *
246: * @return JBIManagementMessage object
247: */
248: public JBIManagementMessage extractJBIManagementMessage() {
249: String exMessage = null;
250: String[] msgs = getCauseMessageTrace();
251: if (msgs != null && msgs.length > 0) {
252: exMessage = msgs[0];
253: }
254:
255: if (exMessage == null) {
256: return null;
257: }
258:
259: JBIManagementMessage mgmtMsg = JBIManagementMessage
260: .createJBIManagementMessage(exMessage);
261:
262: return mgmtMsg;
263: }
264:
265: /**
266: * filters the jmx exception and wraps the root cause user exception int the
267: * JBIRemoteException
268: *
269: * @param jmxEx
270: * exception
271: * @return remote exception
272: */
273: public static JBIRemoteException filterJmxExceptions(Exception jmxEx) {
274: Throwable rootCause = jmxEx;
275: Throwable cause = rootCause;
276: for (;;) {
277: if (cause == null
278: || !(cause instanceof MBeanException
279: || cause instanceof RuntimeMBeanException || cause instanceof RuntimeOperationsException)) {
280: break;
281: }
282: rootCause = cause.getCause();
283: cause = rootCause;
284: }
285: if (rootCause instanceof JBIRemoteException) {
286: return (JBIRemoteException) rootCause;
287: } else {
288: return new JBIRemoteException(rootCause);
289: }
290: }
291:
292: }
|