1 16 17 package org.springframework.web.portlet.handler; 18 19 import java.util.Enumeration ; 20 import java.util.Properties ; 21 import java.util.Set ; 22 23 import javax.portlet.RenderRequest; 24 import javax.portlet.RenderResponse; 25 import javax.portlet.WindowState; 26 27 import org.apache.commons.logging.Log; 28 import org.apache.commons.logging.LogFactory; 29 30 import org.springframework.core.Ordered; 31 import org.springframework.web.portlet.HandlerExceptionResolver; 32 import org.springframework.web.portlet.ModelAndView; 33 34 46 public class SimpleMappingExceptionResolver implements HandlerExceptionResolver, Ordered { 47 48 51 public static final String DEFAULT_EXCEPTION_ATTRIBUTE = "exception"; 52 53 54 55 protected final Log logger = LogFactory.getLog(getClass()); 56 57 private int order = Integer.MAX_VALUE; 59 private Set mappedHandlers; 60 61 private boolean renderWhenMinimized = false; 62 63 private Log warnLogger; 64 65 private Properties exceptionMappings; 66 67 private String defaultErrorView; 68 69 private String exceptionAttribute = DEFAULT_EXCEPTION_ATTRIBUTE; 70 71 72 public void setOrder(int order) { 73 this.order = order; 74 } 75 76 public int getOrder() { 77 return this.order; 78 } 79 80 89 public void setMappedHandlers(Set mappedHandlers) { 90 this.mappedHandlers = mappedHandlers; 91 } 92 93 99 public void setRenderWhenMinimized(boolean renderWhenMinimized) { 100 this.renderWhenMinimized = renderWhenMinimized; 101 } 102 103 114 public void setWarnLogCategory(String loggerName) { 115 this.warnLogger = LogFactory.getLog(loggerName); 116 } 117 118 136 public void setExceptionMappings(Properties mappings) { 137 this.exceptionMappings = mappings; 138 } 139 140 145 public void setDefaultErrorView(String defaultErrorView) { 146 this.defaultErrorView = defaultErrorView; 147 } 148 149 154 public void setExceptionAttribute(String exceptionAttribute) { 155 this.exceptionAttribute = exceptionAttribute; 156 } 157 158 159 public ModelAndView resolveException(RenderRequest request, RenderResponse response, Object handler, Exception ex) { 160 if (this.mappedHandlers != null && !this.mappedHandlers.contains(handler)) { 162 return null; 163 } 164 165 if (WindowState.MINIMIZED.equals(request.getWindowState()) && !this.renderWhenMinimized) { 167 return null; 168 } 169 170 if (logger.isDebugEnabled()) { 172 logger.debug("Resolving exception from handler [" + handler + "]: " + ex); 173 } 174 logException(ex, request); 175 176 String viewName = determineViewName(ex, request); 178 if (viewName != null) { 179 return getModelAndView(viewName, ex, request); 180 } 181 else { 182 return null; 183 } 184 } 185 186 187 198 protected void logException(Exception ex, RenderRequest request) { 199 if (this.warnLogger != null && this.warnLogger.isWarnEnabled()) { 200 this.warnLogger.warn(buildLogMessage(ex, request), ex); 201 } 202 } 203 204 211 protected String buildLogMessage(Exception ex, RenderRequest request) { 212 return "Handler execution resulted in exception"; 213 } 214 215 216 224 protected String determineViewName(Exception ex, RenderRequest request) { 225 String viewName = null; 226 if (this.exceptionMappings != null) { 228 viewName = findMatchingViewName(this.exceptionMappings, ex); 229 } 230 if (viewName == null && this.defaultErrorView != null) { 232 if (logger.isDebugEnabled()) { 233 logger.debug("Resolving to default view '" + this.defaultErrorView + 234 "' for exception of type [" + ex.getClass().getName() + "]"); 235 } 236 viewName = this.defaultErrorView; 237 } 238 return viewName; 239 } 240 241 248 protected String findMatchingViewName(Properties exceptionMappings, Exception ex) { 249 String viewName = null; 250 String dominantMapping = null; 251 int deepest = Integer.MAX_VALUE; 252 for (Enumeration names = exceptionMappings.propertyNames(); names.hasMoreElements();) { 253 String exceptionMapping = (String ) names.nextElement(); 254 int depth = getDepth(exceptionMapping, ex); 255 if (depth >= 0 && depth < deepest) { 256 deepest = depth; 257 dominantMapping = exceptionMapping; 258 viewName = exceptionMappings.getProperty(exceptionMapping); 259 } 260 } 261 if (viewName != null && logger.isDebugEnabled()) { 262 logger.debug("Resolving to view '" + viewName + "' for exception of type [" + ex.getClass().getName() + 263 "], based on exception mapping [" + dominantMapping + "]"); 264 } 265 return viewName; 266 } 267 268 275 protected int getDepth(String exceptionMapping, Exception ex) { 276 return getDepth(exceptionMapping, ex.getClass(), 0); 277 } 278 279 private int getDepth(String exceptionMapping, Class exceptionClass, int depth) { 280 if (exceptionClass.getName().indexOf(exceptionMapping) != -1) { 281 return depth; 283 } 284 if (exceptionClass.equals(Throwable .class)) { 286 return -1; 287 } 288 return getDepth(exceptionMapping, exceptionClass.getSuperclass(), depth + 1); 289 } 290 291 292 301 protected ModelAndView getModelAndView(String viewName, Exception ex, RenderRequest request) { 302 return getModelAndView(viewName, ex); 303 } 304 305 314 protected ModelAndView getModelAndView(String viewName, Exception ex) { 315 ModelAndView mv = new ModelAndView(viewName); 316 if (this.exceptionAttribute != null) { 317 if (logger.isDebugEnabled()) { 318 logger.debug("Exposing Exception as model attribute '" + this.exceptionAttribute + "'"); 319 } 320 mv.addObject(this.exceptionAttribute, ex); 321 } 322 return mv; 323 } 324 325 } 326 | Popular Tags |