001/*
002 * Copyright 2007 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.ole.sys.web.struts;
017
018import java.io.ByteArrayInputStream;
019import java.io.InputStream;
020import java.util.HashMap;
021import java.util.Map;
022
023import javax.servlet.http.HttpServletRequest;
024import javax.servlet.http.HttpServletResponse;
025
026import org.apache.commons.io.IOUtils;
027import org.apache.struts.action.ActionForm;
028import org.apache.struts.action.ActionForward;
029import org.apache.struts.action.ActionMapping;
030import org.apache.struts.upload.FormFile;
031import org.kuali.ole.sys.OLEConstants;
032import org.kuali.ole.sys.OLEKeyConstants;
033import org.kuali.ole.sys.batch.BatchInputFileType;
034import org.kuali.ole.sys.batch.BatchSpringContext;
035import org.kuali.ole.sys.batch.service.BatchInputFileService;
036import org.kuali.ole.sys.businessobject.BatchUpload;
037import org.kuali.ole.sys.context.SpringContext;
038import org.kuali.ole.sys.exception.FileStorageException;
039import org.kuali.ole.sys.exception.ParseException;
040import org.kuali.rice.coreservice.framework.parameter.ParameterService;
041import org.kuali.rice.kim.api.KimConstants;
042import org.kuali.rice.kim.api.services.IdentityManagementService;
043import org.kuali.rice.kns.util.KNSGlobalVariables;
044import org.kuali.rice.kns.web.struts.action.KualiAction;
045import org.kuali.rice.krad.exception.AuthorizationException;
046import org.kuali.rice.krad.service.ModuleService;
047import org.kuali.rice.krad.util.GlobalVariables;
048import org.kuali.rice.krad.util.KRADConstants;
049
050/**
051 * Handles actions from the batch upload screen.
052 */
053public class KualiBatchInputFileAction extends KualiAction {
054    private static org.apache.log4j.Logger LOG = org.apache.log4j.Logger.getLogger(KualiBatchInputFileAction.class);
055    private static IdentityManagementService identityManagementService;
056    private IdentityManagementService getIdentityManagementService() {
057        if (identityManagementService == null) {
058            identityManagementService = SpringContext.getBean(IdentityManagementService.class);
059        }
060        return identityManagementService;
061    }
062
063    /**
064     * @see org.kuali.rice.kns.web.struts.action.KualiAction#execute(org.apache.struts.action.ActionMapping,
065     *      org.apache.struts.action.ActionForm, javax.servlet.http.HttpServletRequest, javax.servlet.http.HttpServletResponse)
066     */
067    @Override
068    public ActionForward execute(ActionMapping mapping, ActionForm form, HttpServletRequest request, HttpServletResponse response) throws Exception {
069        ActionForward forward = super.execute(mapping, form, request, response);
070        setupForm((KualiBatchInputFileForm) form);
071        return forward;
072    }
073
074    @Override
075    protected void checkAuthorization(ActionForm form, String methodToCall) throws AuthorizationException {
076        BatchUpload batchUpload = ((KualiBatchInputFileForm) form).getBatchUpload();
077        BatchInputFileType batchInputFileType = retrieveBatchInputFileTypeImpl(batchUpload.getBatchInputTypeName());
078        Map<String,String> permissionDetails = new HashMap<String,String>();
079        permissionDetails.put(KimConstants.AttributeConstants.NAMESPACE_CODE, getNamespaceCode(batchInputFileType.getClass()));
080        permissionDetails.put(KimConstants.AttributeConstants.BEAN_NAME, batchUpload.getBatchInputTypeName());
081        if (!getIdentityManagementService().isAuthorizedByTemplateName(GlobalVariables.getUserSession().getPrincipalId(), KRADConstants.KNS_NAMESPACE, OLEConstants.PermissionTemplate.UPLOAD_BATCH_INPUT_FILES.name, permissionDetails, null)) {
082            throw new AuthorizationException(GlobalVariables.getUserSession().getPrincipalName(), methodToCall, batchUpload.getBatchInputTypeName());
083        }
084    }
085
086    protected static String getNamespaceCode(Class<? extends Object> clazz) {
087        ModuleService moduleService = getKualiModuleService().getResponsibleModuleService(clazz);
088        if (moduleService == null) {
089            return KimConstants.KIM_TYPE_DEFAULT_NAMESPACE;
090        }
091        return moduleService.getModuleConfiguration().getNamespaceCode();
092    }
093
094    /**
095     * Forwards to the batch upload JSP. Initial request.
096     */
097    public ActionForward start(ActionMapping mapping, ActionForm form, HttpServletRequest request, HttpServletResponse response) throws Exception {
098        return mapping.findForward(OLEConstants.MAPPING_BASIC);
099    }
100
101    /**
102     * Sends the uploaded file contents, requested file name, and batch type to the BatchInputTypeService for storage. If errors
103     * were encountered, messages will be in GlobalVariables.errorMap, which is checked and set for display by the request
104     * processor.
105     */
106    public ActionForward save(ActionMapping mapping, ActionForm form, HttpServletRequest request, HttpServletResponse response) throws Exception {
107        BatchUpload batchUpload = ((KualiBatchInputFileForm) form).getBatchUpload();
108        if (LOG.isDebugEnabled()) {
109            LOG.debug("------------BatchInputTypeName---------->"+batchUpload.getBatchInputTypeName());
110        }
111        BatchInputFileType batchType = retrieveBatchInputFileTypeImpl(batchUpload.getBatchInputTypeName());
112
113
114        BatchInputFileService batchInputFileService = SpringContext.getBean(BatchInputFileService.class);
115        FormFile uploadedFile = ((KualiBatchInputFileForm) form).getUploadFile();
116
117        StringBuffer fileName = new StringBuffer(uploadedFile.getFileName());
118
119        int fileExtensionCount = fileName.indexOf(".");
120        String extension = fileName.substring(fileExtensionCount+1);
121
122
123
124        if (uploadedFile == null || uploadedFile.getInputStream() == null || uploadedFile.getInputStream().available() == 0) {
125            GlobalVariables.getMessageMap().putError(OLEConstants.GLOBAL_ERRORS, OLEKeyConstants.ERROR_BATCH_UPLOAD_NO_FILE_SELECTED_SAVE, new String[] {});
126            return mapping.findForward(OLEConstants.MAPPING_BASIC);
127        }
128
129        if (!batchInputFileService.isFileUserIdentifierProperlyFormatted(batchUpload.getFileUserIdentifer())) {
130            GlobalVariables.getMessageMap().putError(OLEConstants.GLOBAL_ERRORS, OLEKeyConstants.ERROR_BATCH_UPLOAD_FILE_USER_IDENTIFIER_BAD_FORMAT, new String[] {});
131            return mapping.findForward(OLEConstants.MAPPING_BASIC);
132        }
133
134        InputStream fileContents = ((KualiBatchInputFileForm) form).getUploadFile().getInputStream();
135        byte[] fileByteContent = IOUtils.toByteArray(fileContents);
136
137        Object parsedObject = null;
138        try {
139            parsedObject = batchInputFileService.parse(batchType, fileByteContent);
140        }
141        catch (ParseException e) {
142            LOG.error("errors parsing xml " + e.getMessage(), e);
143            GlobalVariables.getMessageMap().putError(OLEConstants.GLOBAL_ERRORS, OLEKeyConstants.ERROR_BATCH_UPLOAD_PARSING_XML, new String[] { e.getMessage() });
144        }
145
146        if (parsedObject != null && GlobalVariables.getMessageMap().hasNoErrors()) {
147            boolean validateSuccessful = batchInputFileService.validate(batchType, parsedObject);
148
149            if (validateSuccessful && GlobalVariables.getMessageMap().hasNoErrors()) {
150                try {
151                    InputStream saveStream = new ByteArrayInputStream(fileByteContent);
152                    String savedFileName ="";
153                    if(batchUpload.getBatchInputTypeName().equalsIgnoreCase("marcInputFileType")){
154                        if(batchUpload  == null || batchUpload.getBatchDestinationFilePath() == null){
155                            GlobalVariables.getMessageMap().putError(OLEConstants.GLOBAL_ERRORS, OLEKeyConstants.ERROR_BATCH_UPLOAD_NO_FILE_PATH_SELECTED_SAVE, new String[] {});
156                            return mapping.findForward(OLEConstants.MAPPING_BASIC);
157                        }
158                        savedFileName = batchInputFileService.save(GlobalVariables.getUserSession().getPerson(), batchType, batchUpload.getFileUserIdentifer(), saveStream, parsedObject,batchUpload.getBatchDestinationFilePath(),extension);
159                    }else{
160                        savedFileName = batchInputFileService.save(GlobalVariables.getUserSession().getPerson(), batchType, batchUpload.getFileUserIdentifer(), saveStream, parsedObject);
161                    }
162                    KNSGlobalVariables.getMessageList().add(OLEKeyConstants.MESSAGE_BATCH_UPLOAD_SAVE_SUCCESSFUL);
163                }
164                catch (FileStorageException e1) {
165                    LOG.error("errors saving xml " + e1.getMessage(), e1);
166                    GlobalVariables.getMessageMap().putError(OLEConstants.GLOBAL_ERRORS, OLEKeyConstants.ERROR_BATCH_UPLOAD_SAVE, new String[] { e1.getMessage() });
167                }
168            }
169        }
170
171        return mapping.findForward(OLEConstants.MAPPING_BASIC);
172    }
173
174    /**
175     * Retrieves a BatchInputFileType implementation from Spring based on the given name.
176     */
177    private BatchInputFileType retrieveBatchInputFileTypeImpl(String batchInputTypeName) {
178        BatchInputFileType batchInputType = BatchSpringContext.getBatchInputFileType(batchInputTypeName);
179        if (batchInputType == null) {
180            LOG.error("Batch input type implementation not found for id " + batchInputTypeName);
181            throw new RuntimeException(("Batch input type implementation not found for id " + batchInputTypeName));
182        }
183
184        return batchInputType;
185    }
186
187    /**
188     * Builds list of filenames that the user has permission to manage, and populates the form member. Sets the title key from the
189     * batch input type.
190     */
191    private void setupForm(KualiBatchInputFileForm form) {
192        BatchInputFileType batchInputFileType = retrieveBatchInputFileTypeImpl(form.getBatchUpload().getBatchInputTypeName());
193
194        if (batchInputFileType == null) {
195            LOG.error("Batch input type implementation not found for id " + form.getBatchUpload().getBatchInputTypeName());
196            throw new RuntimeException(("Batch input type implementation not found for id " + form.getBatchUpload().getBatchInputTypeName()));
197        }
198        ParameterService parmeterService =  SpringContext.getBean(ParameterService.class);
199        String url = parmeterService.getSubParameterValueAsString(BatchUpload.class,OLEConstants.BATCH_UPLOAD_HELP_SYS_PARAM_NAME, batchInputFileType.getFileTypeIdentifer());
200        form.setUrl(url);
201          // set title key
202        form.setTitleKey(batchInputFileType.getTitleKey());
203    }
204
205}
206