001 package com.mockrunner.struts;
002
003 import javax.servlet.ServletException;
004 import javax.servlet.http.HttpServletRequest;
005 import javax.servlet.http.HttpServletResponse;
006
007 import org.apache.struts.action.ActionForm;
008 import org.apache.struts.action.ActionMapping;
009 import org.apache.struts.action.ExceptionHandler;
010 import org.apache.struts.config.ExceptionConfig;
011
012 import com.mockrunner.base.NestedApplicationException;
013
014 /**
015 * The default implementation of {@link ExceptionHandlerConfig}. It uses the Struts
016 * exception handling mechanism. Use the various constructors to provide your subclass
017 * of <code>ExceptionHandler</code> or to configure exception handling using an
018 * instance of <code>ExceptionConfig</code>. The <code>ExceptionConfig</code> class
019 * allows you to set the handler class an exception type.
020 * Use {@link ActionTestModule#addExceptionHandler} to register an exception handler.
021 */
022 public class DefaultExceptionHandlerConfig implements ExceptionHandlerConfig
023 {
024 private ExceptionConfig exceptionConfig;
025 private ExceptionHandler exceptionHandler;
026 private Class exceptionClass;
027
028 public DefaultExceptionHandlerConfig(ExceptionConfig exceptionConfig)
029 {
030 this.exceptionConfig = exceptionConfig;
031 try
032 {
033 Class handlerClass = exceptionConfig.getClass().getClassLoader().loadClass(exceptionConfig.getHandler());
034 exceptionHandler = (ExceptionHandler)handlerClass.newInstance();
035 exceptionClass = exceptionConfig.getClass().getClassLoader().loadClass(exceptionConfig.getType());
036 }
037 catch(Exception exc)
038 {
039 throw new NestedApplicationException(exc);
040 }
041 }
042
043 public DefaultExceptionHandlerConfig(ExceptionHandler exceptionHandler, ExceptionConfig exceptionConfig)
044 {
045 this.exceptionHandler = exceptionHandler;
046 this.exceptionConfig = exceptionConfig;
047 this.exceptionConfig.setHandler(exceptionHandler.getClass().getName());
048 try
049 {
050 exceptionClass = exceptionConfig.getClass().getClassLoader().loadClass(exceptionConfig.getType());
051 }
052 catch(Exception exc)
053 {
054 throw new NestedApplicationException(exc);
055 }
056 }
057
058 public DefaultExceptionHandlerConfig(ExceptionHandler exceptionHandler, Class exceptionClass)
059 {
060 this.exceptionHandler = exceptionHandler;
061 this.exceptionClass = exceptionClass;
062 this.exceptionConfig = new ExceptionConfig();
063 this.exceptionConfig.setHandler(exceptionHandler.getClass().getName());
064 this.exceptionConfig.setType(exceptionClass.getName());
065 }
066
067 public DefaultExceptionHandlerConfig(Class exceptionClass)
068 {
069 this.exceptionHandler = new ExceptionHandler();
070 this.exceptionClass = exceptionClass;
071 this.exceptionConfig = new ExceptionConfig();
072 this.exceptionConfig.setHandler(ExceptionHandler.class.getName());
073 this.exceptionConfig.setType(exceptionClass.getName());
074 }
075
076 public boolean canHandle(Exception exception)
077 {
078 return exceptionClass.isInstance(exception);
079 }
080
081 public Object handle(Exception exception, ActionMapping mapping, ActionForm form, HttpServletRequest request, HttpServletResponse response) throws ServletException
082 {
083 if(!canHandle(exception)) return null;
084 if(null == exceptionHandler) return null;
085 return exceptionHandler.execute((Exception)exception, exceptionConfig, mapping, form, request, response);
086 }
087
088 /**
089 * Get the underlying <code>ExceptionConfig</code>. If you did not provide
090 * an instance of <code>ExceptionConfig</code>, this class will create one
091 * internally.
092 * @return the <code>ExceptionConfig</code>
093 */
094 public ExceptionConfig getExceptionConfig()
095 {
096 return exceptionConfig;
097 }
098
099 /**
100 * Get the underlying <code>ExceptionHandler</code>.
101 * @return the <code>ExceptionHandler</code>
102 */
103 public ExceptionHandler getExceptionHandler()
104 {
105 return exceptionHandler;
106 }
107 }