View Javadoc
1   /**
2    * Copyright 2005-2016 The Kuali Foundation
3    *
4    * Licensed under the Educational Community License, Version 2.0 (the "License");
5    * you may not use this file except in compliance with the License.
6    * You may obtain a copy of the License at
7    *
8    * http://www.opensource.org/licenses/ecl2.php
9    *
10   * Unless required by applicable law or agreed to in writing, software
11   * distributed under the License is distributed on an "AS IS" BASIS,
12   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13   * See the License for the specific language governing permissions and
14   * limitations under the License.
15   */
16  package org.kuali.rice.krad.web.service.impl;
17  
18  import org.apache.commons.lang.StringUtils;
19  import org.kuali.rice.krad.file.FileMeta;
20  import org.kuali.rice.krad.uif.UifConstants;
21  import org.kuali.rice.krad.uif.UifParameters;
22  import org.kuali.rice.krad.uif.lifecycle.ViewLifecycle;
23  import org.kuali.rice.krad.uif.util.ObjectPropertyUtils;
24  import org.kuali.rice.krad.util.KRADUtils;
25  import org.kuali.rice.krad.web.form.DialogResponse;
26  import org.kuali.rice.krad.web.form.UifFormBase;
27  import org.kuali.rice.krad.web.service.CollectionControllerService;
28  import org.kuali.rice.krad.web.service.FileControllerService;
29  import org.kuali.rice.krad.web.service.ModelAndViewService;
30  import org.springframework.web.multipart.MultipartFile;
31  import org.springframework.web.multipart.MultipartHttpServletRequest;
32  import org.springframework.web.servlet.ModelAndView;
33  
34  import javax.servlet.http.HttpServletRequest;
35  import javax.servlet.http.HttpServletResponse;
36  import java.util.Collection;
37  import java.util.Date;
38  import java.util.Iterator;
39  import java.util.List;
40  import java.util.UUID;
41  
42  /**
43   * Default implementation of the file controller service.
44   *
45   * @author Kuali Rice Team (rice.collab@kuali.org)
46   */
47  public class FileControllerServiceImpl implements FileControllerService {
48  
49      protected static final String DELETE_FILE_UPLOAD_LINE_DIALOG = "DialogGroup-DeleteFileUploadLine";
50  
51      private CollectionControllerService collectionControllerService;
52      private ModelAndViewService modelAndViewService;
53  
54      /**
55       * {@inheritDoc}
56       */
57      @Override
58      public ModelAndView addFileUploadLine(final UifFormBase form) {
59          form.setAjaxReturnType(UifConstants.AjaxReturnTypes.UPDATECOMPONENT.getKey());
60          form.setAjaxRequest(true);
61  
62          MultipartHttpServletRequest request = (MultipartHttpServletRequest) form.getRequest();
63  
64          final String collectionId = request.getParameter(UifParameters.UPDATE_COMPONENT_ID);
65          final String bindingPath = request.getParameter(UifConstants.PostMetadata.BINDING_PATH);
66  
67          Class<?> collectionObjectClass = (Class<?>) form.getViewPostMetadata().getComponentPostData(collectionId,
68                  UifConstants.PostMetadata.COLL_OBJECT_CLASS);
69  
70          Iterator<String> fileNamesItr = request.getFileNames();
71  
72          while (fileNamesItr.hasNext()) {
73              String propertyPath = fileNamesItr.next();
74  
75              MultipartFile uploadedFile = request.getFile(propertyPath);
76  
77              final FileMeta fileObject = (FileMeta) KRADUtils.createNewObjectFromClass(collectionObjectClass);
78              try {
79                  fileObject.init(uploadedFile);
80              } catch (Exception e) {
81                  throw new RuntimeException("Unable to initialize new file object", e);
82              }
83  
84              String id = UUID.randomUUID().toString() + "_" + uploadedFile.getName();
85              fileObject.setId(id);
86  
87              fileObject.setDateUploaded(new Date());
88  
89              fileObject.setUrl("?methodToCall=getFileFromLine&formKey="
90                      + form.getFormKey()
91                      + "&fileName="
92                      + fileObject.getName()
93                      + "&propertyPath="
94                      + propertyPath);
95  
96              ViewLifecycle.encapsulateLifecycle(form.getView(), form, form.getViewPostMetadata(), null, request,
97                      new Runnable() {
98                          @Override
99                          public void run() {
100                             ViewLifecycle.getHelper().processAndAddLineObject(form, fileObject, collectionId,
101                                     bindingPath);
102                         }
103                     });
104         }
105 
106         return getModelAndViewService().getModelAndView(form);
107     }
108 
109     /**
110      * {@inheritDoc}
111      */
112     @Override
113     public ModelAndView deleteFileUploadLine(UifFormBase form) {
114         DialogResponse deleteFileUploadLineDialogResponse = form.getDialogResponse(DELETE_FILE_UPLOAD_LINE_DIALOG);
115 
116         if (deleteFileUploadLineDialogResponse == null) {
117             // no confirmation dialog found, so create one on the form and return it
118             return getModelAndViewService().showDialog(DELETE_FILE_UPLOAD_LINE_DIALOG, true, form);
119         }
120 
121         return getCollectionControllerService().deleteLine(form);
122     }
123 
124     /**
125      * {@inheritDoc}
126      */
127     @Override
128     public void getFileFromLine(UifFormBase form, HttpServletResponse response) {
129         HttpServletRequest request = form.getRequest();
130 
131         String selectedCollectionPath = request.getParameter("propertyPath");
132 
133         if (StringUtils.isBlank(selectedCollectionPath)) {
134             throw new RuntimeException("Selected collection was not set for delete line action, cannot delete line");
135         }
136 
137         String selectedLine = request.getParameter(UifParameters.SELECTED_LINE_INDEX);
138         int selectedLineIndex;
139         if (StringUtils.isNotBlank(selectedLine)) {
140             selectedLineIndex = Integer.parseInt(selectedLine);
141         } else {
142             selectedLineIndex = -1;
143         }
144 
145         if (selectedLineIndex == -1) {
146             throw new RuntimeException("Selected line index was not set for delete line action, cannot delete line");
147         }
148 
149         Collection<FileMeta> collection = ObjectPropertyUtils.getPropertyValue(form, selectedCollectionPath);
150 
151         if (collection instanceof List) {
152             FileMeta fileLine = ((List<FileMeta>) collection).get(selectedLineIndex);
153             sendFileFromLineResponse(form, response, (List<FileMeta>) collection, fileLine);
154         }
155     }
156 
157     /**
158      * Hook controller method to send a response back by using response.flushBuffer() using request/collection/fileLine
159      * information provided.
160      *
161      * <p>A sample implementation may look like:
162      * <code> <pre>
163      * if (fileLine instanceof FileMetaBlob) {
164      * InputStream is = ((FileMetaBlob) fileLine).getBlob().getBinaryStream();
165      * response.setContentType("application/force-download");
166      * response.setHeader("Content-Disposition", "attachment; filename=" + fileLine.getName());
167      *
168      * // copy it to response's OutputStream
169      * FileCopyUtils.copy(is, response.getOutputStream());
170      *
171      * response.flushBuffer();
172      * }
173      * </pre></code></p>
174      *
175      * @param form form instance containing the file request data
176      * @param response Http response object for streaming back the file contents
177      * @param collection collection the file object belongs to
178      * @param fileLine the particular file line instance the contents should be sent back for
179      */
180     protected void sendFileFromLineResponse(UifFormBase form, HttpServletResponse response, List<FileMeta> collection,
181             FileMeta fileLine) {
182         // empty method for overrides
183     }
184 
185     protected CollectionControllerService getCollectionControllerService() {
186         return collectionControllerService;
187     }
188 
189     public void setCollectionControllerService(CollectionControllerService collectionControllerService) {
190         this.collectionControllerService = collectionControllerService;
191     }
192 
193     protected ModelAndViewService getModelAndViewService() {
194         return modelAndViewService;
195     }
196 
197     public void setModelAndViewService(ModelAndViewService modelAndViewService) {
198         this.modelAndViewService = modelAndViewService;
199     }
200 }