001/** 002 * Copyright 2005-2018 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.krad.inquiry; 017 018import org.apache.commons.lang.StringUtils; 019import org.kuali.rice.core.api.exception.RiceRuntimeException; 020import org.kuali.rice.krad.bo.PersistableAttachment; 021import org.kuali.rice.krad.bo.PersistableAttachmentList; 022import org.kuali.rice.krad.service.KRADServiceLocatorWeb; 023import org.kuali.rice.krad.service.ModuleService; 024import org.kuali.rice.krad.uif.UifParameters; 025import org.kuali.rice.krad.util.GlobalVariables; 026import org.kuali.rice.krad.util.KRADConstants; 027import org.kuali.rice.krad.util.KRADUtils; 028import org.kuali.rice.krad.web.form.InquiryForm; 029import org.kuali.rice.krad.web.form.UifFormBase; 030import org.kuali.rice.krad.web.service.impl.ControllerServiceImpl; 031import org.springframework.web.servlet.ModelAndView; 032 033import javax.servlet.http.HttpServletRequest; 034import javax.servlet.http.HttpServletResponse; 035import java.io.ByteArrayInputStream; 036import java.io.IOException; 037import java.lang.reflect.Method; 038import java.util.Properties; 039 040/** 041 * Override of navigation controller service to check if the initial inquiry needs redirected and also to 042 * retrieve the inquiry data object on the initial call. 043 * 044 * @author Kuali Rice Team (rice.collab@kuali.org) 045 */ 046public class InquiryControllerServiceImpl extends ControllerServiceImpl implements InquiryControllerService { 047 048 /** 049 * Determines if the inquiry request needs to be redirected based on the module service, if not retrieves 050 * the inquiry data object and sets the instance onto the form for display. 051 * 052 * <p>Note the inquiry data object is retrieved based on the key values passed by the request.</p> 053 * 054 * {@inheritDoc} 055 */ 056 @Override 057 public ModelAndView start(UifFormBase form) { 058 InquiryForm inquiryForm = (InquiryForm) form; 059 HttpServletRequest request = form.getRequest(); 060 061 Boolean hasRedirectedInquiryParameter = (request.getParameter(UifParameters.REDIRECTED_INQUIRY) != null 062 && request.getParameter(UifParameters.REDIRECTED_INQUIRY).contains("true")); 063 064 if (!inquiryForm.isRedirectedInquiry() && !hasRedirectedInquiryParameter) { 065 ModelAndView redirectModelAndView = checkForModuleInquiryRedirect(inquiryForm, request); 066 if (redirectModelAndView != null) { 067 return redirectModelAndView; 068 } 069 } 070 071 // invoke inquirable to retrieve inquiry data object 072 Object dataObject = inquiryForm.getInquirable().retrieveDataObject(KRADUtils.translateRequestParameterMap( 073 request.getParameterMap())); 074 075 inquiryForm.setDataObject(dataObject); 076 077 return super.start(inquiryForm); 078 } 079 080 /** 081 * Checks for a module service that claims the inquiry class as an EBO, and if found redirects to the URL 082 * given by the module service. 083 * 084 * @param inquiryForm form instance containing the inquiry data 085 * @param request http request being handled 086 * @return ModelAndView instance for redirecting to the inquiry, or null if a redirect is not needed 087 */ 088 protected ModelAndView checkForModuleInquiryRedirect(InquiryForm inquiryForm, HttpServletRequest request) { 089 Class<?> inquiryObjectClass; 090 try { 091 inquiryObjectClass = Class.forName(inquiryForm.getDataObjectClassName()); 092 } catch (ClassNotFoundException e) { 093 throw new RiceRuntimeException("Unable to get class for name: " + inquiryForm.getDataObjectClassName(), e); 094 } 095 096 ModuleService responsibleModuleService = 097 KRADServiceLocatorWeb.getKualiModuleService().getResponsibleModuleService(inquiryObjectClass); 098 if (responsibleModuleService != null && responsibleModuleService.isExternalizable(inquiryObjectClass)) { 099 String inquiryUrl = responsibleModuleService.getExternalizableDataObjectInquiryUrl(inquiryObjectClass, 100 KRADUtils.convertRequestMapToProperties(request.getParameterMap())); 101 102 Properties redirectUrlProps = new Properties(); 103 redirectUrlProps.put(UifParameters.REDIRECTED_INQUIRY, "true"); 104 105 GlobalVariables.getUifFormManager().removeSessionForm(inquiryForm); 106 107 return getModelAndViewService().performRedirect(inquiryForm, inquiryUrl, redirectUrlProps); 108 } 109 110 return null; 111 } 112 113 /** 114 * {@inheritDoc} 115 */ 116 @Override 117 public void downloadDataObjectAttachment(InquiryForm form, HttpServletResponse response) { 118 Object dataObject = form.getDataObject(); 119 120 if (dataObject instanceof PersistableAttachment) { 121 PersistableAttachment attachment = (PersistableAttachment) dataObject; 122 byte[] attachmentContent = attachment.getAttachmentContent(); 123 124 addAttachmentToResponse(response, attachmentContent, attachment.getContentType(), attachment.getFileName()); 125 } else if (dataObject instanceof PersistableAttachmentList) { 126 PersistableAttachmentList<PersistableAttachment> attachmentListBo = 127 (PersistableAttachmentList<PersistableAttachment>) dataObject; 128 PersistableAttachment attachment = attachmentListBo.getAttachments().get(Integer.parseInt( 129 form.getActionParamaterValue(UifParameters.SELECTED_LINE_INDEX))); 130 byte[] attachmentContent = attachment.getAttachmentContent(); 131 132 addAttachmentToResponse(response, attachmentContent, attachment.getContentType(), attachment.getFileName()); 133 } 134 } 135 136 /** 137 * {@inheritDoc} 138 */ 139 @Override 140 public void downloadCustomDataObjectAttachment(InquiryForm form, HttpServletRequest request, 141 HttpServletResponse response) throws Exception { 142 String fileName = request.getParameter(KRADConstants.DATA_OBJECT_ATTACHMENT_FILE_NAME); 143 String contentType = request.getParameter(KRADConstants.DATA_OBJECT_ATTACHMENT_FILE_CONTENT_TYPE); 144 String fileContentDataObjField = request.getParameter(KRADConstants.DATA_OBJECT_ATTACHMENT_FILE_CONTENT_FIELD); 145 146 if (fileName == null) { 147 throw new RuntimeException("Request Parameter " 148 + KRADConstants.DATA_OBJECT_ATTACHMENT_FILE_NAME + " must be provided"); 149 } 150 151 if (contentType == null) { 152 throw new RuntimeException("Request Parameter " 153 + KRADConstants.DATA_OBJECT_ATTACHMENT_FILE_CONTENT_TYPE + " must be provided"); 154 } 155 156 if (fileContentDataObjField == null) { 157 throw new RuntimeException("Request Parameter " 158 + KRADConstants.DATA_OBJECT_ATTACHMENT_FILE_CONTENT_FIELD + " must be provided"); 159 } 160 161 checkViewAuthorization(form); 162 163 Object dataObject = form.getDataObject(); 164 165 if (dataObject == null && GlobalVariables.getMessageMap().hasNoMessages()) { 166 throw new UnsupportedOperationException("The record you have inquired on does not exist."); 167 } 168 169 Method method = dataObject.getClass().getMethod("get" + StringUtils.capitalize(fileContentDataObjField)); 170 byte[] attachmentContent = (byte[]) method.invoke(dataObject); 171 172 addAttachmentToResponse(response, attachmentContent, contentType, fileName); 173 } 174 175 /** 176 * Adds the header and content of an attachment to the response. 177 * 178 * @param response HttpServletResponse instance 179 * @param attachmentContent the attachment contents 180 * @param contentType the content type of the attachment 181 * @param fileName the file name of the attachment 182 * @throws RuntimeException if unable to retrieve the attachment contents. 183 */ 184 private void addAttachmentToResponse(HttpServletResponse response, byte[] attachmentContent, 185 String contentType, String fileName) { 186 ByteArrayInputStream inputStream = null; 187 int attachmentContentLength; 188 189 if (attachmentContent != null) { 190 inputStream = new ByteArrayInputStream(attachmentContent); 191 attachmentContentLength = attachmentContent.length; 192 } else { 193 attachmentContentLength = 0; 194 } 195 196 try { 197 KRADUtils.addAttachmentToResponse(response, inputStream, contentType, fileName, attachmentContentLength); 198 } catch (IOException e) { 199 throw new RuntimeException("Unable to retrieve attachment contents", e); 200 } 201 } 202}