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.ByteArrayInputStream; 019 import java.io.File; 020 import java.io.FileInputStream; 021 import java.io.FileNotFoundException; 022 import java.io.InputStream; 023 import java.util.ArrayList; 024 import java.util.List; 025 026 import javax.servlet.http.HttpServletRequest; 027 import javax.servlet.http.HttpServletResponse; 028 029 import org.apache.commons.io.IOUtils; 030 import org.apache.commons.lang.StringUtils; 031 import org.apache.struts.action.ActionForm; 032 import org.apache.struts.action.ActionForward; 033 import org.apache.struts.action.ActionMapping; 034 import org.apache.struts.upload.FormFile; 035 import org.kuali.kfs.coa.businessobject.Account; 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.BatchInputFileType; 040 import org.kuali.kfs.sys.batch.BatchSpringContext; 041 import org.kuali.kfs.sys.batch.service.BatchInputFileService; 042 import org.kuali.kfs.sys.businessobject.BatchUpload; 043 import org.kuali.kfs.sys.context.SpringContext; 044 import org.kuali.kfs.sys.exception.FileStorageException; 045 import org.kuali.kfs.sys.exception.ParseException; 046 import org.kuali.rice.kim.bo.Person; 047 import org.kuali.rice.kim.bo.impl.KimAttributes; 048 import org.kuali.rice.kim.bo.types.dto.AttributeSet; 049 import org.kuali.rice.kim.service.IdentityManagementService; 050 import org.kuali.rice.kim.util.KimCommonUtils; 051 import org.kuali.rice.kim.util.KimConstants; 052 import org.kuali.rice.kns.exception.AuthorizationException; 053 import org.kuali.rice.kns.service.ParameterEvaluator; 054 import org.kuali.rice.kns.service.ParameterService; 055 import org.kuali.rice.kns.util.GlobalVariables; 056 import org.kuali.rice.kns.util.KNSConstants; 057 import org.kuali.rice.kns.util.WebUtils; 058 import org.kuali.rice.kns.web.struts.action.KualiAction; 059 import org.kuali.rice.core.util.KeyLabelPair; 060 061 /** 062 * Handles actions from the batch upload screen. 063 */ 064 public class KualiBatchInputFileAction extends KualiAction { 065 private static org.apache.log4j.Logger LOG = org.apache.log4j.Logger.getLogger(KualiBatchInputFileAction.class); 066 private static IdentityManagementService identityManagementService; 067 private IdentityManagementService getIdentityManagementService() { 068 if (identityManagementService == null) { 069 identityManagementService = SpringContext.getBean(IdentityManagementService.class); 070 } 071 return identityManagementService; 072 } 073 074 /** 075 * @see org.kuali.rice.kns.web.struts.action.KualiAction#execute(org.apache.struts.action.ActionMapping, 076 * org.apache.struts.action.ActionForm, javax.servlet.http.HttpServletRequest, javax.servlet.http.HttpServletResponse) 077 */ 078 @Override 079 public ActionForward execute(ActionMapping mapping, ActionForm form, HttpServletRequest request, HttpServletResponse response) throws Exception { 080 ActionForward forward = super.execute(mapping, form, request, response); 081 setupForm((KualiBatchInputFileForm) form); 082 return forward; 083 } 084 085 @Override 086 protected void checkAuthorization(ActionForm form, String methodToCall) throws AuthorizationException { 087 BatchUpload batchUpload = ((KualiBatchInputFileForm) form).getBatchUpload(); 088 BatchInputFileType batchInputFileType = retrieveBatchInputFileTypeImpl(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 return mapping.findForward(KFSConstants.MAPPING_BASIC); 102 } 103 104 /** 105 * Sends the uploaded file contents, requested file name, and batch type to the BatchInputTypeService for storage. If errors 106 * were encountered, messages will be in GlobalVariables.errorMap, which is checked and set for display by the request 107 * processor. 108 */ 109 public ActionForward save(ActionMapping mapping, ActionForm form, HttpServletRequest request, HttpServletResponse response) throws Exception { 110 BatchUpload batchUpload = ((KualiBatchInputFileForm) form).getBatchUpload(); 111 BatchInputFileType batchType = retrieveBatchInputFileTypeImpl(batchUpload.getBatchInputTypeName()); 112 113 BatchInputFileService batchInputFileService = SpringContext.getBean(BatchInputFileService.class); 114 FormFile uploadedFile = ((KualiBatchInputFileForm) form).getUploadFile(); 115 116 if (uploadedFile == null || uploadedFile.getInputStream() == null || uploadedFile.getInputStream().available() == 0) { 117 GlobalVariables.getMessageMap().putError(KFSConstants.GLOBAL_ERRORS, KFSKeyConstants.ERROR_BATCH_UPLOAD_NO_FILE_SELECTED_SAVE, new String[] {}); 118 return mapping.findForward(KFSConstants.MAPPING_BASIC); 119 } 120 121 if (!batchInputFileService.isFileUserIdentifierProperlyFormatted(batchUpload.getFileUserIdentifer())) { 122 GlobalVariables.getMessageMap().putError(KFSConstants.GLOBAL_ERRORS, KFSKeyConstants.ERROR_BATCH_UPLOAD_FILE_USER_IDENTIFIER_BAD_FORMAT, new String[] {}); 123 return mapping.findForward(KFSConstants.MAPPING_BASIC); 124 } 125 126 InputStream fileContents = ((KualiBatchInputFileForm) form).getUploadFile().getInputStream(); 127 byte[] fileByteContent = IOUtils.toByteArray(fileContents); 128 129 Object parsedObject = null; 130 try { 131 parsedObject = batchInputFileService.parse(batchType, fileByteContent); 132 } 133 catch (ParseException e) { 134 LOG.error("errors parsing xml " + e.getMessage(), e); 135 GlobalVariables.getMessageMap().putError(KFSConstants.GLOBAL_ERRORS, KFSKeyConstants.ERROR_BATCH_UPLOAD_PARSING_XML, new String[] { e.getMessage() }); 136 } 137 138 if (parsedObject != null && GlobalVariables.getMessageMap().isEmpty()) { 139 boolean validateSuccessful = batchInputFileService.validate(batchType, parsedObject); 140 141 if (validateSuccessful && GlobalVariables.getMessageMap().isEmpty()) { 142 try { 143 InputStream saveStream = new ByteArrayInputStream(fileByteContent); 144 145 String savedFileName = batchInputFileService.save(GlobalVariables.getUserSession().getPerson(), batchType, batchUpload.getFileUserIdentifer(), saveStream, parsedObject); 146 GlobalVariables.getMessageList().add(KFSKeyConstants.MESSAGE_BATCH_UPLOAD_SAVE_SUCCESSFUL); 147 } 148 catch (FileStorageException e1) { 149 LOG.error("errors saving xml " + e1.getMessage(), e1); 150 GlobalVariables.getMessageMap().putError(KFSConstants.GLOBAL_ERRORS, KFSKeyConstants.ERROR_BATCH_UPLOAD_SAVE, new String[] { e1.getMessage() }); 151 } 152 } 153 } 154 155 return mapping.findForward(KFSConstants.MAPPING_BASIC); 156 } 157 158 /** 159 * Retrieves a BatchInputFileType implementation from Spring based on the given name. 160 */ 161 private BatchInputFileType retrieveBatchInputFileTypeImpl(String batchInputTypeName) { 162 BatchInputFileType batchInputType = BatchSpringContext.getBatchInputFileType(batchInputTypeName); 163 if (batchInputType == null) { 164 LOG.error("Batch input type implementation not found for id " + batchInputTypeName); 165 throw new RuntimeException(("Batch input type implementation not found for id " + batchInputTypeName)); 166 } 167 168 return batchInputType; 169 } 170 171 /** 172 * Builds list of filenames that the user has permission to manage, and populates the form member. Sets the title key from the 173 * batch input type. 174 */ 175 private void setupForm(KualiBatchInputFileForm form) { 176 BatchInputFileType batchInputFileType = retrieveBatchInputFileTypeImpl(form.getBatchUpload().getBatchInputTypeName()); 177 178 if (batchInputFileType == null) { 179 LOG.error("Batch input type implementation not found for id " + form.getBatchUpload().getBatchInputTypeName()); 180 throw new RuntimeException(("Batch input type implementation not found for id " + form.getBatchUpload().getBatchInputTypeName())); 181 } 182 ParameterService parmeterService = SpringContext.getBean(ParameterService.class); 183 String url = parmeterService.getParameterValue(BatchUpload.class,KFSConstants.BATCH_UPLOAD_HELP_SYS_PARAM_NAME, batchInputFileType.getFileTypeIdentifer()); 184 form.setUrl(url); 185 // set title key 186 form.setTitleKey(batchInputFileType.getTitleKey()); 187 } 188 189 } 190