001 /* 002 * Copyright 2011 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.kfs.sys.web.struts; 017 018 import java.io.File; 019 import java.io.FileInputStream; 020 import java.io.FileNotFoundException; 021 import java.io.InputStream; 022 import java.util.ArrayList; 023 import java.util.HashMap; 024 import java.util.List; 025 import java.util.Map; 026 import java.util.Set; 027 028 import javax.servlet.http.HttpServletRequest; 029 import javax.servlet.http.HttpServletResponse; 030 031 import org.apache.commons.lang.StringUtils; 032 import org.apache.struts.action.ActionForm; 033 import org.apache.struts.action.ActionForward; 034 import org.apache.struts.action.ActionMapping; 035 import org.apache.struts.upload.FormFile; 036 import org.kuali.kfs.sys.KFSConstants; 037 import org.kuali.kfs.sys.KFSKeyConstants; 038 import org.kuali.kfs.sys.batch.BatchInputFileSetType; 039 import org.kuali.kfs.sys.batch.BatchSpringContext; 040 import org.kuali.kfs.sys.batch.service.BatchInputFileSetService; 041 import org.kuali.kfs.sys.businessobject.BatchUpload; 042 import org.kuali.kfs.sys.context.SpringContext; 043 import org.kuali.kfs.sys.exception.FileStorageException; 044 import org.kuali.rice.kim.bo.Person; 045 import org.kuali.rice.kim.bo.impl.KimAttributes; 046 import org.kuali.rice.kim.bo.types.dto.AttributeSet; 047 import org.kuali.rice.kim.service.IdentityManagementService; 048 import org.kuali.rice.kim.util.KimCommonUtils; 049 import org.kuali.rice.kim.util.KimConstants; 050 import org.kuali.rice.kns.exception.AuthorizationException; 051 import org.kuali.rice.kns.exception.ValidationException; 052 import org.kuali.rice.kns.util.GlobalVariables; 053 import org.kuali.rice.kns.util.KNSConstants; 054 import org.kuali.rice.kns.util.WebUtils; 055 import org.kuali.rice.kns.web.struts.action.KualiAction; 056 import org.kuali.rice.core.util.KeyLabelPair; 057 058 /** 059 * This class is the struts action for the batch upload screen that supports file sets 060 */ 061 public class KualiBatchInputFileSetAction extends KualiAction { 062 private static org.apache.log4j.Logger LOG = org.apache.log4j.Logger.getLogger(KualiBatchInputFileSetAction.class); 063 private static IdentityManagementService identityManagementService; 064 private IdentityManagementService getIdentityManagementService() { 065 if (identityManagementService == null) { 066 identityManagementService = SpringContext.getBean(IdentityManagementService.class); 067 } 068 return identityManagementService; 069 } 070 071 /** 072 * @see org.kuali.rice.kns.web.struts.action.KualiAction#execute(org.apache.struts.action.ActionMapping, 073 * org.apache.struts.action.ActionForm, javax.servlet.http.HttpServletRequest, javax.servlet.http.HttpServletResponse) 074 */ 075 @Override 076 public ActionForward execute(ActionMapping mapping, ActionForm form, HttpServletRequest request, HttpServletResponse response) throws Exception { 077 ActionForward forward = super.execute(mapping, form, request, response); 078 setupForm((KualiBatchInputFileSetForm) form); 079 return forward; 080 } 081 082 /** 083 * @see org.kuali.rice.kns.web.struts.action.KualiAction#checkAuthorization(org.apache.struts.action.ActionForm, java.lang.String) 084 */ 085 @Override 086 protected void checkAuthorization(ActionForm form, String methodToCall) throws AuthorizationException { 087 BatchUpload batchUpload = ((KualiBatchInputFileSetForm) form).getBatchUpload(); 088 BatchInputFileSetType batchInputFileType = retrieveBatchInputFileSetTypeImpl(batchUpload.getBatchInputTypeName()); 089 AttributeSet permissionDetails = new AttributeSet(); 090 permissionDetails.put(KimAttributes.NAMESPACE_CODE, KimCommonUtils.getNamespaceCode(batchInputFileType.getClass())); 091 permissionDetails.put(KimAttributes.BEAN_NAME, batchUpload.getBatchInputTypeName()); 092 if (!getIdentityManagementService().isAuthorizedByTemplateName(GlobalVariables.getUserSession().getPrincipalId(), KNSConstants.KNS_NAMESPACE, KFSConstants.PermissionTemplate.UPLOAD_BATCH_INPUT_FILES.name, permissionDetails, null)) { 093 throw new AuthorizationException(GlobalVariables.getUserSession().getPrincipalName(), methodToCall, batchUpload.getBatchInputTypeName()); 094 } 095 } 096 097 /** 098 * Forwards to the batch upload JSP. Initial request. 099 */ 100 public ActionForward start(ActionMapping mapping, ActionForm form, HttpServletRequest request, HttpServletResponse response) throws Exception { 101 BatchUpload batchUpload = ((KualiBatchInputFileSetForm) form).getBatchUpload(); 102 BatchInputFileSetType batchType = retrieveBatchInputFileSetTypeImpl(batchUpload.getBatchInputTypeName()); 103 return mapping.findForward(KFSConstants.MAPPING_BASIC); 104 } 105 106 /** 107 * Sends the uploaded file contents, requested file name, and batch type to the BatchInputTypeService for storage. If errors 108 * were encountered, messages will be in GlobalVariables.errorMap, which is checked and set for display by the request 109 * processor. 110 */ 111 public ActionForward save(ActionMapping mapping, ActionForm form, HttpServletRequest request, HttpServletResponse response) throws Exception { 112 BatchUpload batchUpload = ((KualiBatchInputFileSetForm) form).getBatchUpload(); 113 BatchInputFileSetType batchType = retrieveBatchInputFileSetTypeImpl(batchUpload.getBatchInputTypeName()); 114 115 boolean requiredValuesForFilesMissing = false; 116 if (StringUtils.isBlank(batchUpload.getFileUserIdentifer())) { 117 GlobalVariables.getMessageMap().putError(KFSConstants.GLOBAL_ERRORS, KFSKeyConstants.ERROR_BATCH_UPLOAD_NO_FILE_SET_IDENTIFIER_SELECTED, new String[] {}); 118 requiredValuesForFilesMissing = true; 119 } 120 121 BatchInputFileSetService batchInputFileSetService = SpringContext.getBean(BatchInputFileSetService.class); 122 if (!batchInputFileSetService.isFileUserIdentifierProperlyFormatted(batchUpload.getFileUserIdentifer())) { 123 GlobalVariables.getMessageMap().putError(KFSConstants.GLOBAL_ERRORS, KFSKeyConstants.ERROR_BATCH_UPLOAD_FILE_SET_IDENTIFIER_BAD_FORMAT); 124 requiredValuesForFilesMissing = true; 125 } 126 127 Map<String, FormFile> uploadedFiles = ((KualiBatchInputFileSetForm) form).getUploadedFiles(); 128 Map<String, InputStream> typeToStreamMap = new HashMap<String, InputStream>(); 129 130 for (String fileType : uploadedFiles.keySet()) { 131 FormFile uploadedFile = uploadedFiles.get(fileType); 132 if (uploadedFile == null || uploadedFile.getInputStream() == null || uploadedFile.getInputStream().available() == 0) { 133 GlobalVariables.getMessageMap().putError(KFSConstants.GLOBAL_ERRORS, KFSKeyConstants.ERROR_BATCH_UPLOAD_NO_FILE_SELECTED_SAVE_FOR_FILE_TYPE, new String[] { batchType.getFileTypeDescription().get(fileType) }); 134 requiredValuesForFilesMissing = true; 135 } 136 else { 137 typeToStreamMap.put(fileType, uploadedFile.getInputStream()); 138 } 139 } 140 141 if (requiredValuesForFilesMissing) { 142 return mapping.findForward(KFSConstants.MAPPING_BASIC); 143 } 144 145 try { 146 Map<String, String> typeToSavedFileNames = batchInputFileSetService.save(GlobalVariables.getUserSession().getPerson(), batchType, batchUpload.getFileUserIdentifer(), typeToStreamMap); 147 } 148 catch (FileStorageException e) { 149 LOG.error("Error occured while trying to save file set (probably tried to save a file that already exists).", e); 150 GlobalVariables.getMessageMap().putError(KFSConstants.GLOBAL_ERRORS, KFSKeyConstants.ERROR_BATCH_UPLOAD_FILE_SAVE_ERROR, new String[] { e.getMessage() }); 151 return mapping.findForward(KFSConstants.MAPPING_BASIC); 152 } 153 catch (ValidationException e) { 154 LOG.error("Error occured while trying to validate file set.", e); 155 GlobalVariables.getMessageMap().putError(KFSConstants.GLOBAL_ERRORS, KFSKeyConstants.ERROR_BATCH_UPLOAD_FILE_VALIDATION_ERROR); 156 return mapping.findForward(KFSConstants.MAPPING_BASIC); 157 } 158 GlobalVariables.getMessageList().add(KFSKeyConstants.MESSAGE_BATCH_UPLOAD_SAVE_SUCCESSFUL); 159 160 return mapping.findForward(KFSConstants.MAPPING_BASIC); 161 } 162 163 /** 164 * Retrieves a BatchInputFileType implementation from Spring based on the given name. 165 */ 166 public BatchInputFileSetType retrieveBatchInputFileSetTypeImpl(String batchInputTypeName) { 167 BatchInputFileSetType batchInputType = BatchSpringContext.getBatchInputFileSetType(batchInputTypeName); 168 if (batchInputType == null) { 169 LOG.error("Batch input type implementation not found for id " + batchInputTypeName); 170 throw new RuntimeException(("Batch input type implementation not found for id " + batchInputTypeName)); 171 } 172 173 return batchInputType; 174 } 175 176 /** 177 * Builds list of filenames that the user has permission to manage, and populates the form member. Throws an exception if the 178 * batch file set type is not active. Sets the title key from the batch input type. This method must be called before the action 179 * handler to ensure proper authorization. 180 */ 181 public void setupForm(KualiBatchInputFileSetForm form) { 182 BatchInputFileSetType batchInputFileSetType = retrieveBatchInputFileSetTypeImpl(form.getBatchUpload().getBatchInputTypeName()); 183 184 if (batchInputFileSetType == null) { 185 LOG.error("Batch input type implementation not found for id " + form.getBatchUpload().getBatchInputTypeName()); 186 throw new RuntimeException("Batch input type implementation not found for id " + form.getBatchUpload().getBatchInputTypeName()); 187 } 188 189 if (!SpringContext.getBean(BatchInputFileSetService.class).isBatchInputTypeActive(batchInputFileSetType)) { 190 throw new RuntimeException("Batch input file set type is not active."); 191 } 192 form.setBatchInputFileSetType(batchInputFileSetType); 193 194 // set title key 195 form.setTitleKey(batchInputFileSetType.getTitleKey()); 196 } 197 198 } 199