001 /** 002 * Copyright 2005-2012 The Kuali Foundation 003 * 004 * Licensed under the Educational Community License, Version 2.0 (the "License"); 005 * you may not use this file except in compliance with the License. 006 * You may obtain a copy of the License at 007 * 008 * http://www.opensource.org/licenses/ecl2.php 009 * 010 * Unless required by applicable law or agreed to in writing, software 011 * distributed under the License is distributed on an "AS IS" BASIS, 012 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 013 * See the License for the specific language governing permissions and 014 * limitations under the License. 015 */ 016 package org.kuali.rice.kns.web.struts.action; 017 018 import org.apache.log4j.Logger; 019 import org.apache.struts.Globals; 020 import org.apache.struts.action.Action; 021 import org.apache.struts.action.ActionForm; 022 import org.apache.struts.action.ActionForward; 023 import org.apache.struts.action.ActionMapping; 024 import org.kuali.rice.core.api.util.RiceConstants; 025 import org.kuali.rice.kns.util.IncidentReportUtils; 026 import org.kuali.rice.kns.web.struts.form.KualiExceptionIncidentForm; 027 import org.kuali.rice.krad.exception.KualiExceptionIncident; 028 import org.kuali.rice.krad.service.KRADServiceLocatorWeb; 029 import org.kuali.rice.krad.service.KualiExceptionIncidentService; 030 import org.kuali.rice.krad.util.KRADConstants; 031 032 import javax.servlet.http.HttpServletRequest; 033 import javax.servlet.http.HttpServletResponse; 034 import java.util.Enumeration; 035 import java.util.HashMap; 036 import java.util.Map; 037 038 /** 039 * This is the struts action class for handling the exception for Kuali 040 * applications. 041 * 042 */ 043 public class KualiExceptionHandlerAction extends Action { 044 private static final Logger LOG = Logger 045 .getLogger(KualiExceptionHandlerAction.class); 046 047 /** 048 * This overridden method dispatches action to be taken based on 049 * "methodToCall" parameter. The exception is processed when there is no 050 * "methodToCall" specified. 051 * 052 * @see org.apache.struts.action.Action#execute(org.apache.struts.action.ActionMapping, 053 * org.apache.struts.action.ActionForm, 054 * javax.servlet.http.HttpServletRequest, 055 * javax.servlet.http.HttpServletResponse) 056 */ 057 public ActionForward execute(ActionMapping mapping, ActionForm form, 058 HttpServletRequest request, HttpServletResponse response) 059 throws Exception { 060 return executeException(mapping, form, request, response); 061 } 062 063 /** 064 * This overridden method processes the exception and post exception (when 065 * user either submit/cancel the exception JSP page). 066 * <ul> 067 * <li>ProcessDefinition application Exception - Exception is stored in Http Request</li> 068 * <li>ProcessDefinition exception incident reporting - No exception, only form data</li> 069 * </ul> 070 * 071 * @see org.apache.struts.action.Action#execute(org.apache.struts.action.ActionMapping, 072 * org.apache.struts.action.ActionForm, 073 * javax.servlet.http.HttpServletRequest, 074 * javax.servlet.http.HttpServletResponse) 075 */ 076 public ActionForward executeException(ActionMapping mapping, 077 ActionForm form, HttpServletRequest request, 078 HttpServletResponse response) throws Exception { 079 080 if (LOG.isDebugEnabled()) { 081 String lm = String.format("ENTRY %s%n%s", form.getClass() 082 .getSimpleName(), request.getRequestURI()); 083 LOG.debug(lm); 084 } 085 086 // Get exception thrown 087 Exception e = (Exception) request.getAttribute(Globals.EXCEPTION_KEY); 088 089 // Initialize defined action mapping from struts-config 090 ActionForward returnForward = null; 091 092 // In case there is no exception, either a post back after page was 093 // filled in 094 // or just an error from directly accessing this struts action 095 if (e == null) { 096 if (form instanceof KualiExceptionIncidentForm) { 097 KualiExceptionIncidentForm formObject = (KualiExceptionIncidentForm) form; 098 // Manage conditions: submit or cancel 099 if (!formObject.isCancel()) { 100 // Locate the post exception handler service. The service id 101 // is 102 // defined in the application properties 103 // Only process the post exception handling when the 104 // service 105 // is specified 106 KualiExceptionIncidentService reporterService = KRADServiceLocatorWeb 107 .getKualiExceptionIncidentService(); 108 // An instance of the ExceptionIncident is created by 109 // the 110 // ExceptionIncidentService 111 Map reducedMap = new HashMap(); 112 Enumeration<String> names = request.getParameterNames(); 113 while (names.hasMoreElements()) { 114 String name = names.nextElement(); 115 reducedMap.put(name, request.getParameter(name)); 116 } 117 KualiExceptionIncident exceptionIncident = reporterService 118 .getExceptionIncident(reducedMap); 119 // Report the incident 120 reporterService.report(exceptionIncident); 121 } else { 122 // Set return after canceling 123 ActionForward cancelForward = mapping 124 .findForward(KRADConstants.MAPPING_CANCEL); 125 if (cancelForward == null) { 126 cancelForward = returnForward; 127 } else { 128 returnForward = cancelForward; 129 } 130 } 131 } 132 } else { 133 // ProcessDefinition the received exception from HTTP request 134 returnForward = processException(mapping, form, request, e); 135 } 136 137 // Not specified, return 138 if (returnForward == null) { 139 returnForward = mapping.findForward(KRADConstants.MAPPING_CLOSE); 140 } 141 142 if (LOG.isDebugEnabled()) { 143 String lm = String.format("EXIT %s", 144 (returnForward == null) ? "null" : returnForward.getPath()); 145 LOG.debug(lm); 146 } 147 148 return returnForward; 149 } 150 151 /** 152 * This method process the caught exception by creating an exception 153 * information properties list and forward these properties to the exception 154 * incident handler JSP. 155 * 156 * @param exception 157 * @param mapping 158 * @param request 159 * @param documentId 160 * Id of the document that Struts threw exception during its 161 * processing. null if not the document processing that caused 162 * the exception 163 * @return 164 * @throws Exception 165 */ 166 @SuppressWarnings("unchecked") 167 protected ActionForward processException(ActionMapping mapping, 168 ActionForm form, HttpServletRequest request, Exception exception) 169 throws Exception { 170 // Only process the exception handling when the service 171 // is specified 172 KualiExceptionIncidentService reporterService = KRADServiceLocatorWeb 173 .getKualiExceptionIncidentService(); 174 // Get exception properties from the Http Request 175 Map<String, String> properties = (Map<String, String>) request 176 .getAttribute(IncidentReportUtils.EXCEPTION_PROPERTIES); 177 // Construct the exception incident object 178 KualiExceptionIncident ei = reporterService.getExceptionIncident( 179 exception, properties); 180 // Set full exception properties in Http Request and forward to JSP 181 request.setAttribute(KualiExceptionHandlerAction.class 182 .getSimpleName(), ei.toProperties()); 183 return mapping.findForward(RiceConstants.MAPPING_BASIC); 184 } 185 }