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.module.cam.document.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.module.cam.CamsKeyConstants;
037    import org.kuali.kfs.module.cam.batch.AssetBarcodeInventoryInputFileType;
038    import org.kuali.kfs.module.cam.batch.service.AssetBarcodeInventoryInputFileService;
039    import org.kuali.kfs.sys.KFSConstants;
040    import org.kuali.kfs.sys.KFSKeyConstants;
041    import org.kuali.kfs.sys.batch.BatchInputFileSetType;
042    import org.kuali.kfs.sys.batch.service.BatchInputFileSetService;
043    import org.kuali.kfs.sys.businessobject.BatchUpload;
044    import org.kuali.kfs.sys.context.SpringContext;
045    import org.kuali.kfs.sys.exception.FileStorageException;
046    import org.kuali.kfs.sys.web.struts.KualiBatchInputFileSetAction;
047    import org.kuali.kfs.sys.web.struts.KualiBatchInputFileSetForm;
048    import org.kuali.rice.kim.bo.Person;
049    import org.kuali.rice.kns.exception.ValidationException;
050    import org.kuali.rice.kns.util.GlobalVariables;
051    import org.kuali.rice.kns.util.WebUtils;
052    import org.kuali.rice.core.util.KeyLabelPair;
053    
054    
055    /**
056     * 
057     * Action class for the CAMS Barcode Inventory upload. 
058     */
059    public class AssetBarCodeInventoryInputFileAction extends KualiBatchInputFileSetAction {
060        private static org.apache.log4j.Logger LOG = org.apache.log4j.Logger.getLogger(AssetBarCodeInventoryInputFileAction.class);
061    
062        /**
063         * 
064         * @see org.kuali.kfs.sys.web.struts.KualiBatchInputFileSetAction#save(org.apache.struts.action.ActionMapping, org.apache.struts.action.ActionForm, javax.servlet.http.HttpServletRequest, javax.servlet.http.HttpServletResponse)
065         * 
066         * Overridden because I needed to validate the file type is correct.
067         */
068        @Override
069        public ActionForward save(ActionMapping mapping, ActionForm form, HttpServletRequest request, HttpServletResponse response) throws Exception {
070            BatchUpload batchUpload = ((AssetBarCodeInventoryInputFileForm) form).getBatchUpload();
071            AssetBarcodeInventoryInputFileType batchType = (AssetBarcodeInventoryInputFileType)retrieveBatchInputFileSetTypeImpl(batchUpload.getBatchInputTypeName());
072            
073            Map<String, FormFile> uploadedFiles = ((KualiBatchInputFileSetForm) form).getUploadedFiles();
074            
075            String fileTypeExtension = ((AssetBarcodeInventoryInputFileType)batchType).getFileExtension();
076            String fileName = uploadedFiles.get(fileTypeExtension.substring(1)).getFileName();
077                
078            //Validating the file type is the correct one before saving.
079            if (!StringUtils.isBlank(fileName) && !fileName.endsWith(fileTypeExtension)) {
080                GlobalVariables.getMessageMap().putError(KFSConstants.GLOBAL_ERRORS, CamsKeyConstants.BarcodeInventory.ERROR_INVALID_FILE_TYPE);
081                return mapping.findForward(KFSConstants.MAPPING_BASIC);
082            }            
083            
084            //return super.save(mapping, form, request, response);
085            
086            String uploadDescription = ((AssetBarCodeInventoryInputFileForm) form).getUploadDescription();
087    
088            boolean requiredValuesForFilesMissing = false;
089            if (StringUtils.isBlank(batchUpload.getFileUserIdentifer())) {
090                GlobalVariables.getMessageMap().putError(KFSConstants.GLOBAL_ERRORS, KFSKeyConstants.ERROR_BATCH_UPLOAD_NO_FILE_SET_IDENTIFIER_SELECTED, new String[] {});
091                requiredValuesForFilesMissing = true;
092            }
093    
094            if (StringUtils.isBlank(uploadDescription)) {
095                GlobalVariables.getMessageMap().putError(KFSConstants.GLOBAL_ERRORS, KFSKeyConstants.ERROR_DOCUMENT_NO_DESCRIPTION);
096                requiredValuesForFilesMissing = true;
097            }
098            
099            
100            
101            AssetBarcodeInventoryInputFileService batchInputFileSetService = SpringContext.getBean(AssetBarcodeInventoryInputFileService.class);
102            
103            if (!batchInputFileSetService.isFileUserIdentifierProperlyFormatted(batchUpload.getFileUserIdentifer())) {
104                GlobalVariables.getMessageMap().putError(KFSConstants.GLOBAL_ERRORS, KFSKeyConstants.ERROR_BATCH_UPLOAD_FILE_SET_IDENTIFIER_BAD_FORMAT);
105                requiredValuesForFilesMissing = true;
106            }
107    
108            Map<String, InputStream> typeToStreamMap = new HashMap<String, InputStream>();
109    
110            for (String fileType : uploadedFiles.keySet()) {
111                FormFile uploadedFile = uploadedFiles.get(fileType);
112                if (uploadedFile == null || uploadedFile.getInputStream() == null || uploadedFile.getInputStream().available() == 0) {
113                    GlobalVariables.getMessageMap().putError(KFSConstants.GLOBAL_ERRORS, KFSKeyConstants.ERROR_BATCH_UPLOAD_NO_FILE_SELECTED_SAVE_FOR_FILE_TYPE, new String[] { batchType.getFileTypeDescription().get(fileType) });
114                    requiredValuesForFilesMissing = true;
115                }
116                else {
117                    typeToStreamMap.put(fileType, uploadedFile.getInputStream());
118                }
119            }
120    
121            if (requiredValuesForFilesMissing) {
122                return mapping.findForward(KFSConstants.MAPPING_BASIC);
123            }
124    
125            try {
126                //Map<String, String> typeToSavedFileNames =  batchInputFileSetService.save(GlobalVariables.getUserSession().getPerson(), batchType, batchUpload.getFileUserIdentifer(), typeToStreamMap, ((AssetBarCodeInventoryInputFileForm) form).isSupressDoneFileCreation(),uploadDescription);
127                Map<String, String> typeToSavedFileNames =  batchInputFileSetService.save(GlobalVariables.getUserSession().getPerson(), batchType, batchUpload.getFileUserIdentifer(), typeToStreamMap, ((AssetBarCodeInventoryInputFileForm) form));            
128            }
129            catch (FileStorageException e) {
130                LOG.error("Error occured while trying to save file set (probably tried to save a file that already exists).", e);
131                GlobalVariables.getMessageMap().putError(KFSConstants.GLOBAL_ERRORS, KFSKeyConstants.ERROR_BATCH_UPLOAD_FILE_SAVE_ERROR, new String[] { e.getMessage() });
132                return mapping.findForward(KFSConstants.MAPPING_BASIC);
133            }
134            catch (ValidationException e) {
135                LOG.error("Error occured while trying to validate file set.", e);
136                GlobalVariables.getMessageMap().putError(KFSConstants.GLOBAL_ERRORS, KFSKeyConstants.ERROR_BATCH_UPLOAD_FILE_VALIDATION_ERROR);
137                return mapping.findForward(KFSConstants.MAPPING_BASIC);
138            }
139            GlobalVariables.getMessageList().add(KFSKeyConstants.MESSAGE_BATCH_UPLOAD_SAVE_SUCCESSFUL);
140    
141            return mapping.findForward(KFSConstants.MAPPING_BASIC);
142            
143        }
144        
145        /**
146         * 
147         * Builds list of filenames that the user has permission to manage, and populates the form member. Throws an exception if the
148         * batch file set type is not active. Sets the title key from the batch input type. This method must be called before the action
149         * handler to ensure proper authorization.
150         * 
151         */
152        @Override    
153        public void setupForm(KualiBatchInputFileSetForm form) {
154            BatchInputFileSetType batchInputFileSetType = retrieveBatchInputFileSetTypeImpl(form.getBatchUpload().getBatchInputTypeName());
155    
156            if (batchInputFileSetType == null) {
157                LOG.error("Batch input type implementation not found for id " + form.getBatchUpload().getBatchInputTypeName());
158                throw new RuntimeException("Batch input type implementation not found for id " + form.getBatchUpload().getBatchInputTypeName());
159            }
160    
161            if (!SpringContext.getBean(BatchInputFileSetService.class).isBatchInputTypeActive(batchInputFileSetType)) {
162                throw new RuntimeException("Batch input file set type is not active.");
163            }
164            form.setBatchInputFileSetType(batchInputFileSetType);
165    
166            BatchInputFileSetService batchInputFileSetService = SpringContext.getBean(BatchInputFileSetService.class);
167    
168            List<KeyLabelPair> fileTypes = new ArrayList<KeyLabelPair>();
169            fileTypes.add(new KeyLabelPair("", "Select a file type to download"));
170            
171            for (String fileAlias : batchInputFileSetType.getFileTypes()) {
172                fileTypes.add(new KeyLabelPair(fileAlias, batchInputFileSetType.getFileTypeDescription().get(fileAlias)));
173            }
174            form.setFileTypes(fileTypes);
175            
176            // set title key
177            form.setTitleKey(batchInputFileSetType.getTitleKey());
178        }
179    }