001: package net.sf.crispy;
002:
003: import java.io.ByteArrayOutputStream;
004: import java.io.IOException;
005: import java.io.OutputStream;
006: import java.io.PrintStream;
007: import java.io.Serializable;
008: import java.lang.reflect.Constructor;
009: import java.util.ArrayList;
010: import java.util.List;
011: import java.util.Map;
012:
013: import net.sf.crispy.impl.ServiceManager;
014: import net.sf.crispy.util.Converter;
015: import net.sf.crispy.util.Util;
016:
017: /**
018: * Wraped the server side thrown exception. Transport to the client.
019: * Unwraped the exception and thrown the exception on the client side.
020: *
021: * @author Linke
022: * @since 1.1.0
023: *
024: */
025: public final class ExceptionWrapper implements Serializable {
026:
027: private static final long serialVersionUID = -2137246018098063392L;
028:
029: private byte stackTraceByteArray[] = null;
030: private String message = "no message available";
031: private String exceptionClassName = "no exception class name";
032: private List stackTraceElementWrapperList = new ArrayList(0);
033:
034: private Object exceptionPlaceHolder = null;
035: private boolean withExceptionSerializer = false;
036:
037: public ExceptionWrapper() {
038: }
039:
040: public ExceptionWrapper(Throwable pvThrowable) {
041: this (pvThrowable, false);
042: }
043:
044: public ExceptionWrapper(Throwable pvThrowable,
045: boolean pvWithExceptionSerializer) {
046: setMessage(pvThrowable.getMessage());
047: setExceptionClassName(pvThrowable.getClass().getName());
048: stackTrace2ByteArray(pvThrowable);
049: copyStackTraceElement(pvThrowable.getStackTrace());
050: withExceptionSerializer = pvWithExceptionSerializer;
051:
052: if (getWithExceptionSerializer() == true) {
053: createPlaceHolder(pvThrowable);
054: }
055: }
056:
057: private void createPlaceHolder(Throwable pvThrowable) {
058: try {
059: Converter lvConverter = new Converter();
060: lvConverter.setWithSimpleKeyMapper(true);
061: exceptionPlaceHolder = lvConverter.makeSimple(pvThrowable);
062: // StackTrace can't unmarshall
063: ((Map) exceptionPlaceHolder).remove("stackTrace");
064: } catch (Exception e) {
065: if (ServiceManager.DEBUG_MODE_ON) {
066: e.printStackTrace();
067: }
068: }
069: }
070:
071: public boolean getWithExceptionSerializer() {
072: return withExceptionSerializer;
073: }
074:
075: public void setExceptionPlaceHolder(Object pvPlaceHolder) {
076: exceptionPlaceHolder = pvPlaceHolder;
077: }
078:
079: public Object getExceptionPlaceHolder() {
080: return exceptionPlaceHolder;
081: }
082:
083: public void setMessage(String pvMessage) {
084: message = pvMessage;
085: }
086:
087: public String getMessage() {
088: return message;
089: }
090:
091: public void setExceptionClassName(String pvExceptionClassName) {
092: exceptionClassName = pvExceptionClassName;
093: }
094:
095: public String getExceptionClassName() {
096: return exceptionClassName;
097: }
098:
099: public void setStackTraceByteArray(byte b[]) {
100: stackTraceByteArray = b;
101: }
102:
103: public byte[] getStackTraceByteArray() {
104: return stackTraceByteArray;
105: }
106:
107: public List getStackTraceElementWrapperList() {
108: return stackTraceElementWrapperList;
109: }
110:
111: public void setStackTraceElementWrapperList(
112: List pvStackTraceElementWrapperList) {
113: stackTraceElementWrapperList = pvStackTraceElementWrapperList;
114: }
115:
116: public void copyStackTraceElement(
117: StackTraceElement[] pvStackTraceElements) {
118: int lvArraySize = pvStackTraceElements.length;
119: stackTraceElementWrapperList = new ArrayList(lvArraySize);
120: for (int i = 0; i < lvArraySize; i++) {
121: stackTraceElementWrapperList
122: .add(new StackTraceElementWrapper(
123: pvStackTraceElements[i]));
124: }
125: }
126:
127: public void stackTrace2ByteArray(Throwable pvThrowable) {
128: ByteArrayOutputStream out = new ByteArrayOutputStream();
129: PrintStream lvPrintStream = new PrintStream(out);
130: pvThrowable.printStackTrace(lvPrintStream);
131:
132: setStackTraceByteArray(out.toByteArray());
133: }
134:
135: public void printStackTrace2() {
136: int lvSize = stackTraceElementWrapperList.size();
137: System.out.println(getExceptionClassName() + ": "
138: + getMessage());
139: for (int i = 0; i < lvSize; i++) {
140: System.out.println(" at "
141: + stackTraceElementWrapperList.get(i));
142: }
143: }
144:
145: public void printStackTrace() {
146: printStackTrace(System.out);
147: }
148:
149: public void printStackTrace(OutputStream pvOutputStream) {
150: ByteArrayOutputStream out = new ByteArrayOutputStream();
151: try {
152: out.write(getStackTraceByteArray());
153: out.writeTo(pvOutputStream);
154: out.flush();
155: out.close();
156: } catch (IOException e) {
157: if (ServiceManager.DEBUG_MODE_ON) {
158: e.printStackTrace();
159: }
160: }
161:
162: }
163:
164: public Exception newExceptionInstance() {
165:
166: Exception lvResult = null;
167: try {
168: Converter lvConverter = new Converter();
169: lvConverter.setWithSimpleKeyMapper(true);
170: lvResult = (Exception) lvConverter
171: .makeComplex(getExceptionPlaceHolder());
172: } catch (Exception e) {
173: if (ServiceManager.DEBUG_MODE_ON) {
174: e.printStackTrace();
175: }
176: }
177: if (lvResult != null) {
178: lvResult.initCause(new InvocationException(getMessage()));
179: return lvResult;
180: } else {
181: return newExceptionInstanceIntern();
182: }
183: }
184:
185: private Exception newExceptionInstanceIntern() {
186: Exception lvException = new InvocationException(this );
187: try {
188: Class c = Class.forName(this .getExceptionClassName());
189: Constructor con[] = c.getConstructors();
190: for (int i = 0; i < con.length; i++) {
191: int lvParamSize = con[i].getParameterTypes().length;
192: if ((lvParamSize == 1)
193: && (con[i].getParameterTypes()[0]
194: .equals(String.class))) {
195: lvException = (Exception) con[i]
196: .newInstance(new Object[] { this
197: .getMessage() });
198: break;
199: } else if (lvParamSize == 0) {
200: lvException = (Exception) con[i].newInstance(null);
201: break;
202: }
203: }
204: } catch (Exception e) {
205: if (ServiceManager.DEBUG_MODE_ON) {
206: e.printStackTrace();
207: }
208: }
209: return lvException;
210: }
211:
212: /**
213: * This method is used on the server side (from the invocation handler) to convert the
214: * <code>Exception</code> to the <code>ExceptionWrapper</code>.
215: *
216: * @param pvResult Result of execution remote call (on the server side).
217: * @return The unchanged result object or if the result object is a Throwable,
218: * than is the return value a ExceptionWrapper from the Throwable.
219: */
220: public static Object isThrowableThanHandleThrowable(
221: final Object pvResult) {
222: if (pvResult instanceof Throwable) {
223: Throwable lvThrowable = (Throwable) pvResult;
224:
225: if (ServiceManager.DEBUG_MODE_ON == true) {
226: lvThrowable.printStackTrace();
227: }
228:
229: Throwable t = Util.findDeepestThrowable(lvThrowable);
230: return new ExceptionWrapper(t, true);
231: } else {
232: return pvResult;
233: }
234: }
235:
236: /**
237: * This method is calling from the client side procy (Executor or Static-Proxy).
238: * It is converting from the <code>ExceptionWrapper</code> to the <code>Exception</code>.
239: *
240: * @param pvResult Result of execution remote call (on the server side).
241: * @return The same result object (unchanged)
242: * @throws Exception If the result is a map and in the map is a key: class and value
243: * is equals ExceptionWrapper, than throw the server side created Exception.
244: */
245: public static Object isResultExceptionThanThrowIt(
246: final Object pvResult) throws Exception {
247: if (pvResult instanceof Map) {
248: Map lvMap = (Map) pvResult;
249: Object lvClassObj = lvMap.get("class");
250: if ((lvClassObj != null)
251: && lvClassObj.equals(ExceptionWrapper.class
252: .getName())) {
253:
254: // Map lvMapSimpleException = (Map) lvMap.get("simpleException");
255: // if (lvMapSimpleException != null) {
256: // lvMapSimpleException.remove("stackTrace");
257: // }
258:
259: Converter lvConverter = new Converter();
260: lvConverter.setWithSimpleKeyMapper(true);
261: Object o = lvConverter.makeComplex(lvMap);
262: ExceptionWrapper lvExceptionWrapper = (ExceptionWrapper) o;
263: throw lvExceptionWrapper.newExceptionInstance();
264: }
265: } else if (pvResult instanceof ExceptionWrapper) {
266: ExceptionWrapper lvExceptionWrapper = (ExceptionWrapper) pvResult;
267: throw lvExceptionWrapper.newExceptionInstance();
268: }
269: return pvResult;
270: }
271:
272: }
|