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 }