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 }