package org.jboss.resteasy.core;

import java.io.PrintWriter;
import java.io.StringWriter;

/**
 * A ExceptionAdapter.
 *
 * @author <a href="ryan@damnhandy.com">Ryan J. McDonough</a>
 * @version $Revision: $
 */
public class ExceptionAdapter extends RuntimeException
{

   /**
    * The serialVersionUID
    */
   private static final long serialVersionUID = 6628087350457915908L;

   private final String stackTrace;

   /**
    *
    */
   private Exception originalException;

   /**
    * Create a new ExceptionAdapter.
    *
    * @param e exception
    */
   public ExceptionAdapter(final Exception e)
   {
      this(e.getMessage(), e);
   }

   public ExceptionAdapter(final String message, final Exception e)
   {
      super(new StringBuilder(message == null ? "" : message).append(" : ").append(e.getMessage()).toString());
      originalException = e;
      StringWriter sw = new StringWriter();
      e.printStackTrace(new PrintWriter(sw));
      stackTrace = sw.toString();
   }

   /**
    * Prints stack trace.
    *
    * @see java.lang.Throwable#printStackTrace()
    */
   //CHECKSTYLE.OFF: RegexpSinglelineJava
   public void printStackTrace()
   {
      printStackTrace(System.err);
   }
   //CHECKSTYLE.ON: RegexpSinglelineJava

   /**
    * Prints stack trace.
    *
    * @param s print stream
    * @see java.lang.Throwable#printStackTrace(java.io.PrintStream)
    */
   public void printStackTrace(java.io.PrintStream s)
   {
      synchronized (s)
      {
         s.printf("%s: ", getClass().getName());
         s.print(stackTrace);
      }
   }

   /**
    * Prints stack trace.
    *
    * @param s print writer
    * @see java.lang.Throwable#printStackTrace(java.io.PrintWriter)
    */
   public void printStackTrace(java.io.PrintWriter s)
   {
      synchronized (s)
      {
         s.print(getClass().getName() + ": ");
         s.print(stackTrace);
      }
   }


   /**
    * Rethrows the original exception class.
    *
    * @throws Exception exception
    */
   public void rethrow() throws Exception
   {
      throw this.originalException;
   }
}
