View Javadoc
1   /**
2    * Copyright 2005-2014 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.controller;
17  
18  import javax.servlet.http.HttpServletRequest;
19  import javax.servlet.http.HttpServletResponse;
20  
21  import org.apache.commons.lang.ArrayUtils;
22  import org.apache.log4j.Logger;
23  import org.kuali.rice.core.api.CoreApiServiceLocator;
24  import org.kuali.rice.core.api.config.property.ConfigurationService;
25  import org.kuali.rice.core.api.util.RiceKeyConstants;
26  import org.kuali.rice.kew.api.KewApiConstants;
27  import org.kuali.rice.krad.bo.Attachment;
28  import org.kuali.rice.krad.bo.Note;
29  import org.kuali.rice.krad.bo.PersistableAttachment;
30  import org.kuali.rice.krad.bo.PersistableAttachmentList;
31  import org.kuali.rice.krad.bo.PersistableBusinessObject;
32  import org.kuali.rice.krad.datadictionary.DocumentEntry;
33  import org.kuali.rice.krad.exception.UnknownDocumentIdException;
34  import org.kuali.rice.krad.maintenance.MaintenanceDocument;
35  import org.kuali.rice.krad.maintenance.Maintainable;
36  import org.kuali.rice.krad.maintenance.MaintenanceUtils;
37  import org.kuali.rice.krad.service.KRADServiceLocatorWeb;
38  import org.kuali.rice.krad.service.MaintenanceDocumentService;
39  import org.kuali.rice.krad.uif.UifConstants;
40  import org.kuali.rice.krad.uif.UifParameters;
41  import org.kuali.rice.krad.util.GlobalVariables;
42  import org.kuali.rice.krad.util.KRADConstants;
43  import org.kuali.rice.krad.util.KRADUtils;
44  import org.kuali.rice.krad.web.form.DocumentFormBase;
45  import org.kuali.rice.krad.web.form.InitiatedDocumentInfoForm;
46  import org.kuali.rice.krad.web.form.MaintenanceDocumentForm;
47  import org.kuali.rice.krad.web.form.UifFormBase;
48  import org.springframework.stereotype.Controller;
49  import org.springframework.validation.BindingResult;
50  import org.springframework.web.bind.ServletRequestBindingException;
51  import org.springframework.web.bind.annotation.ModelAttribute;
52  import org.springframework.web.bind.annotation.RequestMapping;
53  import org.springframework.web.bind.annotation.RequestMethod;
54  import org.springframework.web.servlet.ModelAndView;
55  
56  import java.io.ByteArrayInputStream;
57  import java.io.FileNotFoundException;
58  import java.io.IOException;
59  import java.util.Properties;
60  
61  /**
62   * Controller for <code>MaintenanceDocumentView</code> screens which operate on
63   * <code>MaintenanceDocument</code> instances
64   *
65   * @author Kuali Rice Team (rice.collab@kuali.org)
66   */
67  @Controller
68  @RequestMapping(value = "/maintenance")
69  public class MaintenanceDocumentController extends DocumentControllerBase {
70      protected static final Logger LOG = Logger.getLogger(MaintenanceDocumentController.class);
71  
72      /**
73       * @see org.kuali.rice.krad.web.controller.UifControllerBase#createInitialForm(javax.servlet.http.HttpServletRequest)
74       */
75      @Override
76      protected MaintenanceDocumentForm createInitialForm(HttpServletRequest request) {
77          return new MaintenanceDocumentForm();
78      }
79  
80      /**
81       * After the document is loaded calls method to setup the maintenance object
82       */
83      @Override
84      @MethodAccessible
85      @RequestMapping(params = "methodToCall=docHandler")
86      public ModelAndView docHandler(@ModelAttribute("KualiForm") DocumentFormBase formBase, BindingResult result,
87              HttpServletRequest request, HttpServletResponse response) throws Exception {
88  
89          // TODO getting double view if we call base, not sure how to handle
90          // so pasting in superclass code
91          // super.docHandler(formBase, request, response);
92          // * begin copy/paste from the base
93          MaintenanceDocumentForm form = (MaintenanceDocumentForm) formBase;
94  
95          // in all of the following cases we want to load the document
96          if (ArrayUtils.contains(DOCUMENT_LOAD_COMMANDS, form.getCommand()) && form.getDocId() != null) {
97              try {
98                  loadDocument(form);
99              } catch (UnknownDocumentIdException udie) {
100                 ConfigurationService kualiConfigurationService = CoreApiServiceLocator.getKualiConfigurationService();
101                 StringBuffer sb = new StringBuffer();
102                 sb.append(kualiConfigurationService.getPropertyValueAsString(KRADConstants.KRAD_URL_KEY));
103                 sb.append(kualiConfigurationService.getPropertyValueAsString(KRADConstants.KRAD_INITIATED_DOCUMENT_URL_KEY));
104                 Properties props = new Properties();
105                 props.put(UifParameters.METHOD_TO_CALL, UifConstants.MethodToCallNames.START);
106                 GlobalVariables.getUifFormManager().removeSessionForm(form); // removeForm(form);
107                 return performRedirect(new InitiatedDocumentInfoForm(), sb.toString(), props);
108             }
109         } else if (KewApiConstants.INITIATE_COMMAND.equals(form.getCommand())) {
110             createDocument(form);
111         } else {
112             LOG.error("docHandler called with invalid parameters");
113             throw new IllegalArgumentException("docHandler called with invalid parameters");
114         }
115         // * end copy/paste from the base
116 
117         if (KewApiConstants.ACTIONLIST_COMMAND.equals(form.getCommand()) ||
118                 KewApiConstants.DOCSEARCH_COMMAND.equals(form.getCommand()) ||
119                 KewApiConstants.SUPERUSER_COMMAND.equals(form.getCommand()) ||
120                 KewApiConstants.HELPDESK_ACTIONLIST_COMMAND.equals(form.getCommand()) && form.getDocId() != null) {
121             // TODO: set state in view
122             // form.setReadOnly(true);
123             form.setMaintenanceAction((form.getDocument()).getNewMaintainableObject().getMaintenanceAction());
124 
125             // Retrieving the FileName from BO table
126             Maintainable tmpMaintainable = form.getDocument().getNewMaintainableObject();
127             if (tmpMaintainable.getDataObject() instanceof PersistableAttachment) {
128                 PersistableAttachment bo = (PersistableAttachment) getLegacyDataAdapter()
129                         .retrieve((PersistableBusinessObject) tmpMaintainable.getDataObject());
130                 if (bo != null) {
131                     request.setAttribute("fileName", bo.getFileName());
132                 }
133             }
134         } else if (KewApiConstants.INITIATE_COMMAND.equals(form.getCommand())) {
135             // form.setReadOnly(false);
136             setupMaintenance(form, request, KRADConstants.MAINTENANCE_NEW_ACTION);
137         } else {
138             LOG.error("We should never have gotten to here");
139             throw new IllegalArgumentException("docHandler called with invalid parameters");
140         }
141 
142         return getUIFModelAndView(form);
143     }
144 
145     /**
146      * Default method for controller that setups a new
147      * <code>MaintenanceDocumentView</code> with the default new action
148      */
149     @Override
150     @MethodAccessible
151     @RequestMapping(params = "methodToCall=" + KRADConstants.Maintenance.METHOD_TO_CALL_NEW)
152     public ModelAndView start(@ModelAttribute("KualiForm") UifFormBase form, HttpServletRequest request,
153             HttpServletResponse response) {
154         MaintenanceDocumentForm maintenanceForm = (MaintenanceDocumentForm) form;
155 
156         // indicate that default values should be applied to this view
157         maintenanceForm.addViewThatNeedsDefaultValuesApplied(form.getViewId());
158 
159         setupMaintenance(maintenanceForm, request, KRADConstants.MAINTENANCE_NEW_ACTION);
160 
161         return getUIFModelAndView(maintenanceForm);
162     }
163 
164     /**
165      * Setups a new <code>MaintenanceDocumentView</code> with the edit maintenance
166      * action
167      */
168     @MethodAccessible
169     @RequestMapping(params = "methodToCall=" + KRADConstants.Maintenance.METHOD_TO_CALL_EDIT)
170     public ModelAndView maintenanceEdit(@ModelAttribute("KualiForm") MaintenanceDocumentForm form, BindingResult result,
171             HttpServletRequest request, HttpServletResponse response) throws Exception {
172 
173         setupMaintenance(form, request, KRADConstants.MAINTENANCE_EDIT_ACTION);
174 
175         return getUIFModelAndView(form);
176     }
177 
178     /**
179      * Setups a new <code>MaintenanceDocumentView</code> with the copy maintenance
180      * action
181      */
182     @MethodAccessible
183     @RequestMapping(params = "methodToCall=" + KRADConstants.Maintenance.METHOD_TO_CALL_COPY)
184     public ModelAndView maintenanceCopy(@ModelAttribute("KualiForm") MaintenanceDocumentForm form, BindingResult result,
185             HttpServletRequest request, HttpServletResponse response) throws Exception {
186 
187         setupMaintenance(form, request, KRADConstants.MAINTENANCE_COPY_ACTION);
188 
189         return getUIFModelAndView(form);
190     }
191 
192     /**
193      * Setups a new <code>MaintenanceDocumentView</code> with the new with existing
194      * maintenance action
195      */
196     @MethodAccessible
197     @RequestMapping(params = "methodToCall=" + KRADConstants.Maintenance.METHOD_TO_CALL_NEW_WITH_EXISTING)
198     public ModelAndView maintenanceNewWithExisting(@ModelAttribute("KualiForm") MaintenanceDocumentForm form,
199             BindingResult result, HttpServletRequest request, HttpServletResponse response) throws Exception {
200 
201         setupMaintenance(form, request, KRADConstants.MAINTENANCE_NEWWITHEXISTING_ACTION);
202 
203         return getUIFModelAndView(form);
204     }
205 
206     /**
207      * Setups a new <code>MaintenanceDocumentView</code> with the delete maintenance
208      * action
209      */
210     @MethodAccessible
211     @RequestMapping(params = "methodToCall=" + KRADConstants.Maintenance.METHOD_TO_CALL_DELETE)
212     public ModelAndView maintenanceDelete(@ModelAttribute("KualiForm") MaintenanceDocumentForm form,
213             BindingResult result, HttpServletRequest request, HttpServletResponse response) throws Exception {
214 
215         GlobalVariables.getMessageMap().putWarning(KRADConstants.GLOBAL_MESSAGES, RiceKeyConstants.MESSAGE_DELETE);
216 
217         setupMaintenance(form, request, KRADConstants.MAINTENANCE_DELETE_ACTION);
218 
219         return getUIFModelAndView(form);
220     }
221 
222     /**
223      * Sets up the <code>MaintenanceDocument</code> on initial get request
224      *
225      * <p>
226      * First step is to create a new document instance based on the query
227      * parameters (document type name or object class name). Then call the
228      * <code>Maintainable</code> to do setup on the object being maintained.
229      * </p>
230      *
231      * @param form - <code>MaintenanceDocumentForm</code> instance
232      * @param request - HTTP request object
233      * @param maintenanceAction - the maintenance action (new, new from existing, edit, copy)
234      * being request
235      * @throws Exception
236      */
237     protected void setupMaintenance(MaintenanceDocumentForm form, HttpServletRequest request, String maintenanceAction) {
238         MaintenanceDocument document = form.getDocument();
239 
240         // create a new document object, if required
241         if (document == null) {
242             document = getMaintenanceDocumentService()
243                     .setupNewMaintenanceDocument(form.getDataObjectClassName(), form.getDocTypeName(),
244                             maintenanceAction);
245 
246             form.setDocument(document);
247             form.setDocTypeName(document.getDocumentHeader().getWorkflowDocument().getDocumentTypeName());
248         }
249 
250         // set action on form
251         form.setMaintenanceAction(maintenanceAction);
252 
253         // invoke maintenance document service to setup the object for maintenance
254         getMaintenanceDocumentService().setupMaintenanceObject(document, maintenanceAction, request.getParameterMap());
255 
256         // for new maintainable check if a maintenance lock exists and if so
257         // warn the user
258         if (KRADConstants.MAINTENANCE_NEW_ACTION.equals(maintenanceAction)) {
259             MaintenanceUtils.checkForLockingDocument(document, false);
260         }
261 
262         // Retrieve notes topic display flag from data dictionary and add to
263         // document
264         // TODO: should be in the view as permission
265         DocumentEntry entry = KRADServiceLocatorWeb.getDocumentDictionaryService()
266                 .getMaintenanceDocumentEntry(document.getDocumentHeader().getWorkflowDocument().getDocumentTypeName());
267         document.setDisplayTopicFieldInNotes(entry.getDisplayTopicFieldInNotes());
268     }
269 
270     /**
271      * Override route to retrieve the maintenance object if it is an attachment
272      *
273      * {@inheritDoc}
274      */
275     @Override
276     @RequestMapping(params = "methodToCall=route")
277     public ModelAndView route(@ModelAttribute("KualiForm") DocumentFormBase form, BindingResult result,
278             HttpServletRequest request, HttpServletResponse response) {
279 
280         ModelAndView modelAndView;
281 
282         modelAndView = super.route(form, result, request, response);
283 
284         MaintenanceDocument document = (MaintenanceDocument) form.getDocument();
285         if (document.getNewMaintainableObject().getDataObject() instanceof PersistableAttachment) {
286             PersistableAttachment bo = (PersistableAttachment) getLegacyDataAdapter()
287                     .retrieve((PersistableBusinessObject) document.getNewMaintainableObject().getDataObject());
288             request.setAttribute("fileName", bo.getFileName());
289         }
290 
291         modelAndView = getUIFModelAndView(form);
292 
293         return modelAndView;
294     }
295 
296     /**
297      * Downloads the attachment to the user's browser
298      *
299      * @param uifForm
300      * @param result
301      * @param request
302      * @param response
303      * @return ModelView
304      * @throws Exception
305      */
306     @Override
307     @RequestMapping(method = RequestMethod.POST, params = "methodToCall=downloadBOAttachment")
308     public ModelAndView downloadBOAttachment(@ModelAttribute("KualiForm") UifFormBase uifForm, BindingResult result,
309             HttpServletRequest request,
310             HttpServletResponse response) throws ServletRequestBindingException, FileNotFoundException, IOException {
311 
312         //first check if attachment connected to note
313         String noteIdentifierParameter = request.getParameter(KRADConstants.NOTE_IDENTIFIER);
314         if (noteIdentifierParameter != null) {
315             Long noteIdentifier = Long.valueOf(noteIdentifierParameter);
316             Note note = this.getNoteService().getNoteByNoteId(noteIdentifier);
317             if (note != null) {
318                 Attachment attachment = note.getAttachment();
319                 if (attachment != null) {
320 
321                     //make sure attachment is setup with backwards reference to note (rather then doing this we could also just call the attachment service (with a new method that took in the note)
322                     attachment.setNote(note);
323 
324                     // Add attachment to response
325                     KRADUtils.addAttachmentToResponse(response, getAttachmentService().retrieveAttachmentContents(
326                             attachment), attachment.getAttachmentMimeTypeCode(), attachment.getAttachmentFileName(),
327                             attachment.getAttachmentFileSize());
328 
329                     return null;
330                 }
331             }
332         }
333 
334         MaintenanceDocumentForm form = (MaintenanceDocumentForm) uifForm;
335         MaintenanceDocument document = (MaintenanceDocument) form.getDocument();
336         Object dataObject = document.getDocumentDataObject();
337 
338         if (dataObject instanceof PersistableAttachment) {
339             PersistableAttachment attachment = (PersistableAttachment) dataObject;
340             byte[] attachmentContent = attachment.getAttachmentContent();
341             if (attachmentContent != null) {
342 
343                 ByteArrayInputStream inputStream = new ByteArrayInputStream(attachmentContent);
344                 KRADUtils.addAttachmentToResponse(response, inputStream, attachment.getContentType(),
345                         attachment.getFileName(), attachmentContent.length);
346                 return null;
347             }
348         } else if (dataObject instanceof PersistableAttachmentList) {
349             PersistableAttachmentList<PersistableAttachment> attachmentList =
350                     (PersistableAttachmentList<PersistableAttachment>) dataObject;
351             PersistableAttachmentList<PersistableAttachment> attachmentListBo =
352                     (PersistableAttachmentList<PersistableAttachment>) document.getNewMaintainableObject()
353                             .getDataObject();
354             PersistableAttachment attachment = (PersistableAttachment) attachmentListBo.getAttachments().get(
355                     Integer.parseInt(form.getActionParamaterValue("selectedLineIndex")));
356             byte[] attachmentContent = attachment.getAttachmentContent();
357             if (attachmentContent != null) {
358 
359                 ByteArrayInputStream inputStream = new ByteArrayInputStream(attachmentContent);
360                 KRADUtils.addAttachmentToResponse(response, inputStream, attachment.getContentType(),
361                         attachment.getFileName(), attachmentContent.length);
362                 return null;
363             }
364         }
365 
366         return null;
367     }
368 
369     protected MaintenanceDocumentService getMaintenanceDocumentService() {
370         return KRADServiceLocatorWeb.getMaintenanceDocumentService();
371     }
372 
373 }