001/** 002 * Copyright 2005-2016 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 */ 016package org.kuali.rice.kns.web.struts.action; 017 018import org.apache.log4j.Logger; 019import org.apache.struts.Globals; 020import org.apache.struts.action.Action; 021import org.apache.struts.action.ActionForm; 022import org.apache.struts.action.ActionForward; 023import org.apache.struts.action.ActionMapping; 024import org.kuali.rice.core.api.config.property.ConfigContext; 025import org.kuali.rice.core.api.util.RiceConstants; 026import org.kuali.rice.kns.util.IncidentReportUtils; 027import org.kuali.rice.kns.web.struts.form.KualiExceptionIncidentForm; 028import org.kuali.rice.krad.exception.ExceptionIncident; 029import org.kuali.rice.krad.exception.KualiExceptionIncident; 030import org.kuali.rice.krad.service.KRADServiceLocatorWeb; 031import org.kuali.rice.krad.service.KualiExceptionIncidentService; 032import org.kuali.rice.krad.util.GlobalVariables; 033import org.kuali.rice.krad.util.KRADConstants; 034 035import javax.servlet.http.HttpServletRequest; 036import javax.servlet.http.HttpServletResponse; 037import java.util.Enumeration; 038import java.util.HashMap; 039import java.util.Map; 040 041/** 042 * This is the struts action class for handling the exception for Kuali 043 * applications. 044 * 045 * @deprecated KNS Struts deprecated, use KRAD and the Spring MVC framework. 046 */ 047@Deprecated 048public class KualiExceptionHandlerAction extends Action { 049 private static final Logger LOG = Logger 050 .getLogger(KualiExceptionHandlerAction.class); 051 052 private static final String EXCEPTION_TIME_STAMP = "exception-timeStamp"; 053 private static final String EXCEPTION_DOCUMENT_ID = "exception-" + ExceptionIncident.DOCUMENT_ID; 054 private static final String EXCEPTION_USER_EMAIL = "exception-" + ExceptionIncident.USER_EMAIL; 055 private static final String EXCEPTION_USER_NAME = "exception-" + ExceptionIncident.USER_NAME; 056 private static final String EXCEPTION_UUID = "exception-" + ExceptionIncident.UUID; 057 private static final String EXCEPTION_COMPONENT_NAME = "exception-" + ExceptionIncident.COMPONENT_NAME; 058 private static final String EXCEPTION_EXCEPTION_REPORT_SUBJECT = "exception-" + ExceptionIncident.EXCEPTION_REPORT_SUBJECT; 059 private static final String EXCEPTION_EXCEPTION_MESSAGE = "exception-" + ExceptionIncident.EXCEPTION_MESSAGE; 060 private static final String EXCEPTION_STACK_TRACE = "exception-" + ExceptionIncident.STACK_TRACE; 061 062 /** 063 * This overridden method dispatches action to be taken based on 064 * "methodToCall" parameter. The exception is processed when there is no 065 * "methodToCall" specified. 066 * 067 * @see org.apache.struts.action.Action#execute(org.apache.struts.action.ActionMapping, 068 * org.apache.struts.action.ActionForm, 069 * javax.servlet.http.HttpServletRequest, 070 * javax.servlet.http.HttpServletResponse) 071 */ 072 public ActionForward execute(ActionMapping mapping, ActionForm form, 073 HttpServletRequest request, HttpServletResponse response) 074 throws Exception { 075 return executeException(mapping, form, request, response); 076 } 077 078 /** 079 * This overridden method processes the exception and post exception (when 080 * user either submit/cancel the exception JSP page). 081 * <ul> 082 * <li>ProcessDefinition application Exception - Exception is stored in Http Request</li> 083 * <li>ProcessDefinition exception incident reporting - No exception, only form data</li> 084 * </ul> 085 * 086 * @see org.apache.struts.action.Action#execute(org.apache.struts.action.ActionMapping, 087 * org.apache.struts.action.ActionForm, 088 * javax.servlet.http.HttpServletRequest, 089 * javax.servlet.http.HttpServletResponse) 090 */ 091 public ActionForward executeException(ActionMapping mapping, 092 ActionForm form, HttpServletRequest request, 093 HttpServletResponse response) throws Exception { 094 095 if (LOG.isDebugEnabled()) { 096 String lm = String.format("ENTRY %s%n%s", form.getClass() 097 .getSimpleName(), request.getRequestURI()); 098 LOG.debug(lm); 099 } 100 101 // Get exception thrown 102 Exception e = (Exception) request.getAttribute(Globals.EXCEPTION_KEY); 103 104 // Initialize defined action mapping from struts-config 105 ActionForward returnForward = null; 106 107 // In case there is no exception, either a post back after page was 108 // filled in 109 // or just an error from directly accessing this struts action 110 if (e == null) { 111 if (form instanceof KualiExceptionIncidentForm) { 112 KualiExceptionIncidentForm formObject = (KualiExceptionIncidentForm) form; 113 // Manage conditions: submit or cancel 114 if (!formObject.isCancel()) { 115 // Locate the post exception handler service. The service id 116 // is 117 // defined in the application properties 118 // Only process the post exception handling when the 119 // service 120 // is specified 121 KualiExceptionIncidentService reporterService = KRADServiceLocatorWeb 122 .getKualiExceptionIncidentService(); 123 // An instance of the ExceptionIncident is created by 124 // the 125 // ExceptionIncidentService 126 Map reducedMap = new HashMap(); 127 Enumeration<String> names = request.getParameterNames(); 128 while (names.hasMoreElements()) { 129 String name = names.nextElement(); 130 reducedMap.put(name, request.getParameter(name)); 131 } 132 133 // Sensitive data stored in user session 134 Map<String, Object> userSessionMap = GlobalVariables.getUserSession().getObjectMap(); 135 136 // Only display if this is the right exception 137 if(userSessionMap.get("EXCEPTION_TIME_STAMP").toString().equals(reducedMap.get(ExceptionIncident.STACK_TRACE))) { 138 reducedMap.put(ExceptionIncident.DOCUMENT_ID, userSessionMap.get("EXCEPTION_DOCUMENT_ID").toString()); 139 reducedMap.put(ExceptionIncident.USER_EMAIL, userSessionMap.get("EXCEPTION_USER_EMAIL").toString()); 140 reducedMap.put(ExceptionIncident.USER_NAME, userSessionMap.get("EXCEPTION_USER_NAME").toString()); 141 reducedMap.put(ExceptionIncident.UUID, userSessionMap.get("EXCEPTION_UUID").toString()); 142 reducedMap.put(ExceptionIncident.COMPONENT_NAME, userSessionMap.get("EXCEPTION_COMPONENT_NAME").toString()); 143 reducedMap.put(ExceptionIncident.EXCEPTION_REPORT_SUBJECT, userSessionMap.get("EXCEPTION_EXCEPTION_REPORT_SUBJECT").toString()); 144 reducedMap.put(ExceptionIncident.EXCEPTION_MESSAGE, userSessionMap.get("EXCEPTION_EXCEPTION_MESSAGE").toString()); 145 reducedMap.put(ExceptionIncident.STACK_TRACE, userSessionMap.get("EXCEPTION_STACK_TRACE").toString()); 146 147 } else { 148 reducedMap.put(ExceptionIncident.STACK_TRACE,"Not available."); 149 } 150 151 KualiExceptionIncident exceptionIncident = reporterService 152 .getExceptionIncident(reducedMap); 153 154 // Report the incident 155 reporterService.report(exceptionIncident); 156 } else { 157 // Set return after canceling 158 ActionForward cancelForward = mapping 159 .findForward(KRADConstants.MAPPING_CANCEL); 160 if (cancelForward == null) { 161 cancelForward = returnForward; 162 } else { 163 returnForward = cancelForward; 164 } 165 } 166 } 167 } else { 168 // ProcessDefinition the received exception from HTTP request 169 returnForward = processException(mapping, form, request, e); 170 } 171 172 // Not specified, return 173 if (returnForward == null) { 174 returnForward = mapping.findForward(KRADConstants.MAPPING_CLOSE); 175 } 176 177 if (LOG.isDebugEnabled()) { 178 String lm = String.format("EXIT %s", 179 (returnForward == null) ? "null" : returnForward.getPath()); 180 LOG.debug(lm); 181 } 182 183 return returnForward; 184 } 185 186 /** 187 * This method process the caught exception by creating an exception 188 * information properties list and forward these properties to the exception 189 * incident handler JSP. 190 * 191 * @param exception 192 * @param mapping 193 * @param request 194 * @param documentId 195 * Id of the document that Struts threw exception during its 196 * processing. null if not the document processing that caused 197 * the exception 198 * @return 199 * @throws Exception 200 */ 201 @SuppressWarnings("unchecked") 202 protected ActionForward processException(ActionMapping mapping, 203 ActionForm form, HttpServletRequest request, Exception exception) 204 throws Exception { 205 // Only process the exception handling when the service 206 // is specified 207 KualiExceptionIncidentService reporterService = KRADServiceLocatorWeb 208 .getKualiExceptionIncidentService(); 209 // Get exception properties from the Http Request 210 Map<String, String> properties = (Map<String, String>) request 211 .getAttribute(IncidentReportUtils.EXCEPTION_PROPERTIES); 212 // Construct the exception incident object 213 KualiExceptionIncident ei = reporterService.getExceptionIncident( 214 exception, properties); 215 216 // Add sensitive data to user session 217 String exceptionTimeStamp = String.valueOf(System.currentTimeMillis()); 218 GlobalVariables.getUserSession().addObject("EXCEPTION_TIME_STAMP", exceptionTimeStamp); 219 GlobalVariables.getUserSession().addObject("EXCEPTION_DOCUMENT_ID", ei.getProperty(ExceptionIncident.DOCUMENT_ID)); 220 GlobalVariables.getUserSession().addObject("EXCEPTION_USER_EMAIL", ei.getProperty(ExceptionIncident.USER_EMAIL)); 221 GlobalVariables.getUserSession().addObject("EXCEPTION_USER_NAME", ei.getProperty(ExceptionIncident.USER_NAME)); 222 GlobalVariables.getUserSession().addObject("EXCEPTION_UUID", ei.getProperty(ExceptionIncident.UUID)); 223 GlobalVariables.getUserSession().addObject("EXCEPTION_COMPONENT_NAME", ei.getProperty(ExceptionIncident.COMPONENT_NAME)); 224 GlobalVariables.getUserSession().addObject("EXCEPTION_EXCEPTION_REPORT_SUBJECT", ei.getProperty(ExceptionIncident.EXCEPTION_REPORT_SUBJECT)); 225 GlobalVariables.getUserSession().addObject("EXCEPTION_EXCEPTION_MESSAGE", ei.getProperty(ExceptionIncident.EXCEPTION_MESSAGE)); 226 GlobalVariables.getUserSession().addObject("EXCEPTION_STACK_TRACE", ei.getProperty(ExceptionIncident.STACK_TRACE)); 227 228 // Hide sensitive data from form in production only 229 if(ConfigContext.getCurrentContextConfig().isProductionEnvironment()) { 230 Map<String, String> prodProperties = ei.toProperties(); 231 prodProperties.put(ExceptionIncident.DOCUMENT_ID, ""); 232 prodProperties.put(ExceptionIncident.USER_EMAIL, ""); 233 prodProperties.put(ExceptionIncident.USER_NAME, ""); 234 prodProperties.put(ExceptionIncident.UUID, ""); 235 prodProperties.put(ExceptionIncident.COMPONENT_NAME, ""); 236 prodProperties.put(ExceptionIncident.EXCEPTION_REPORT_SUBJECT, ""); 237 prodProperties.put(ExceptionIncident.EXCEPTION_MESSAGE, ""); 238 prodProperties.put(ExceptionIncident.STACK_TRACE, exceptionTimeStamp); 239 ei = reporterService.getExceptionIncident( 240 null, prodProperties); 241 } 242 243 // Set full exception properties in Http Request and forward to JSP 244 request.setAttribute(KualiExceptionHandlerAction.class 245 .getSimpleName(), ei.toProperties()); 246 return mapping.findForward(RiceConstants.MAPPING_BASIC); 247 } 248}