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