ExceptionWrapper.java :  » Web-Services » crispy » net » sf » crispy » Java Open Source

Java Open Source » Web Services » crispy 
crispy » net » sf » crispy » ExceptionWrapper.java
package net.sf.crispy;

import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.OutputStream;
import java.io.PrintStream;
import java.io.Serializable;
import java.lang.reflect.Constructor;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;

import net.sf.crispy.impl.ServiceManager;
import net.sf.crispy.util.Converter;
import net.sf.crispy.util.Util;

/**
 * Wraped the server side thrown exception. Transport to the client.
 * Unwraped the exception and thrown the exception on the client side.
 * 
 * @author Linke
 * @since 1.1.0
 *
 */
public final class ExceptionWrapper implements Serializable {

  private static final long serialVersionUID = -2137246018098063392L;
  
  private byte stackTraceByteArray[] = null;
  private String message = "no message available";
  private String exceptionClassName = "no exception class name";
  private List stackTraceElementWrapperList = new ArrayList(0);
  
  private Object exceptionPlaceHolder = null;
  private boolean withExceptionSerializer = false;
  
  public ExceptionWrapper() {}
  
  public ExceptionWrapper(Throwable pvThrowable) {
    this(pvThrowable, false);
  }
  public ExceptionWrapper(Throwable pvThrowable, boolean pvWithExceptionSerializer) {
    setMessage(pvThrowable.getMessage());
    setExceptionClassName(pvThrowable.getClass().getName());
    stackTrace2ByteArray(pvThrowable);
    copyStackTraceElement(pvThrowable.getStackTrace());
    withExceptionSerializer = pvWithExceptionSerializer;
    
    if (getWithExceptionSerializer() == true) {
      createPlaceHolder(pvThrowable);
    }
  }
  
  private void createPlaceHolder(Throwable pvThrowable) {
    try {
      Converter lvConverter = new Converter();
      lvConverter.setWithSimpleKeyMapper(true);
      exceptionPlaceHolder = lvConverter.makeSimple(pvThrowable);
      // StackTrace can't unmarshall
      ((Map) exceptionPlaceHolder).remove("stackTrace");
    } catch (Exception e) {
      if (ServiceManager.DEBUG_MODE_ON) {
        e.printStackTrace();
      }
    }        
  }

  public boolean getWithExceptionSerializer() { return withExceptionSerializer; }

  public void setExceptionPlaceHolder(Object pvPlaceHolder) { exceptionPlaceHolder = pvPlaceHolder; }
  public Object getExceptionPlaceHolder() { return exceptionPlaceHolder; }
  
  public void setMessage(String pvMessage) { message = pvMessage; }
  public String getMessage() { return message; }
  
  public void setExceptionClassName(String pvExceptionClassName) { exceptionClassName = pvExceptionClassName; }
  public String getExceptionClassName() { return exceptionClassName; }
  
  public void setStackTraceByteArray(byte b[]) { stackTraceByteArray = b; }
  public byte[] getStackTraceByteArray() { return stackTraceByteArray; }
  
  public List getStackTraceElementWrapperList() { return stackTraceElementWrapperList; }
  public void setStackTraceElementWrapperList(List pvStackTraceElementWrapperList) {stackTraceElementWrapperList = pvStackTraceElementWrapperList;}
  
  public void copyStackTraceElement(StackTraceElement[] pvStackTraceElements) {
    int lvArraySize = pvStackTraceElements.length;
    stackTraceElementWrapperList = new ArrayList(lvArraySize);
    for (int i=0; i<lvArraySize; i++) {
      stackTraceElementWrapperList.add(new StackTraceElementWrapper(pvStackTraceElements[i]));
    }
  }
  
  public void stackTrace2ByteArray(Throwable pvThrowable) {
    ByteArrayOutputStream out = new ByteArrayOutputStream();
    PrintStream lvPrintStream = new PrintStream(out);
    pvThrowable.printStackTrace(lvPrintStream);
    
    setStackTraceByteArray(out.toByteArray());
  }
  
  public void printStackTrace2() {
    int lvSize = stackTraceElementWrapperList.size();
    System.out.println(getExceptionClassName() + ": " + getMessage());
    for (int i=0; i<lvSize; i++) {
      System.out.println("  at " + stackTraceElementWrapperList.get(i));
    }
  }
  
  public void printStackTrace() {
    printStackTrace(System.out);
  }
  
  public void printStackTrace(OutputStream pvOutputStream) {
    ByteArrayOutputStream out = new ByteArrayOutputStream();
    try {
      out.write(getStackTraceByteArray());
      out.writeTo(pvOutputStream);
      out.flush();
      out.close();
    } catch (IOException e) {
      if (ServiceManager.DEBUG_MODE_ON) {
        e.printStackTrace();
      }
    }
    
  }
  
  public Exception newExceptionInstance() {
    
    Exception lvResult = null;
    try {
      Converter lvConverter = new Converter();
      lvConverter.setWithSimpleKeyMapper(true);
      lvResult = (Exception) lvConverter.makeComplex(getExceptionPlaceHolder());
    } catch (Exception e) {
      if (ServiceManager.DEBUG_MODE_ON) {
        e.printStackTrace();
      }
    }
    if (lvResult != null) {
      lvResult.initCause(new InvocationException(getMessage()));
      return lvResult;
    } else {
      return newExceptionInstanceIntern();
    }
  }
  
  private Exception newExceptionInstanceIntern() {
    Exception lvException = new InvocationException(this);
    try {
      Class c = Class.forName(this.getExceptionClassName());
      Constructor con[] = c.getConstructors();
      for (int i = 0; i < con.length; i++) {
        int lvParamSize = con[i].getParameterTypes().length;
        if ((lvParamSize == 1) && (con[i].getParameterTypes()[0].equals(String.class))) {
          lvException = (Exception) con[i].newInstance(new Object [] { this.getMessage() });
          break;
        }
        else if (lvParamSize == 0) {
          lvException = (Exception) con[i].newInstance(null);
          break;
        } 
      }
    } catch (Exception e) {
      if (ServiceManager.DEBUG_MODE_ON) {
        e.printStackTrace();
      }
    }
    return lvException;
  }
  
  /**
   * This method is used on the server side (from the invocation handler) to convert the
   * <code>Exception</code> to the <code>ExceptionWrapper</code>.
   * 
   * @param pvResult Result of execution remote call (on the server side).
   * @return The unchanged result object or if the result object is a Throwable,
   * than is the return value a ExceptionWrapper from the Throwable.
   */
    public static Object isThrowableThanHandleThrowable(final Object pvResult) {
      if (pvResult instanceof Throwable) {
        Throwable lvThrowable = (Throwable) pvResult;

        if (ServiceManager.DEBUG_MODE_ON == true) {
          lvThrowable.printStackTrace();
        }
 
        Throwable t = Util.findDeepestThrowable(lvThrowable);
        return new ExceptionWrapper(t, true);
      } else {
        return pvResult;
      }
    }
    
    /**
     * This method is calling from the client side procy (Executor or Static-Proxy).
     * It is converting from the <code>ExceptionWrapper</code> to the <code>Exception</code>.
     * 
     * @param pvResult Result of execution remote call (on the server side).
     * @return The same result object (unchanged) 
     * @throws Exception If the result is a map and in the map is a key: class and value 
     * is equals ExceptionWrapper, than throw the server side created Exception.
     */
    public static Object isResultExceptionThanThrowIt (final Object pvResult) throws Exception {
      if (pvResult instanceof Map) {
        Map lvMap = (Map) pvResult;
        Object lvClassObj = lvMap.get("class");
        if ((lvClassObj != null) && lvClassObj.equals(ExceptionWrapper.class.getName())) {
          
//          Map lvMapSimpleException = (Map) lvMap.get("simpleException");
//          if (lvMapSimpleException != null) {
//            lvMapSimpleException.remove("stackTrace");
//          }
          
          Converter lvConverter = new Converter();
          lvConverter.setWithSimpleKeyMapper(true);
          Object o = lvConverter.makeComplex(lvMap);
           ExceptionWrapper lvExceptionWrapper = (ExceptionWrapper) o;
           throw lvExceptionWrapper.newExceptionInstance();
        }
        }
        else if (pvResult instanceof ExceptionWrapper) {
         ExceptionWrapper lvExceptionWrapper = (ExceptionWrapper) pvResult;
         throw lvExceptionWrapper.newExceptionInstance();          
        }
        return pvResult;
    }    

}
java2s.com  | Contact Us | Privacy Policy
Copyright 2009 - 12 Demo Source and Support. All rights reserved.
All other trademarks are property of their respective owners.