001/**
002 * Copyright 2005-2017 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.rice.kew.notes.web;
017
018import org.apache.commons.lang.StringUtils;
019import org.apache.struts.action.ActionForm;
020import org.apache.struts.action.ActionForward;
021import org.apache.struts.action.ActionMapping;
022import org.apache.struts.action.ActionMessages;
023import org.apache.struts.upload.FormFile;
024import org.kuali.rice.core.api.resourceloader.GlobalResourceLoader;
025import org.kuali.rice.core.api.util.RiceConstants;
026import org.kuali.rice.coreservice.framework.CoreFrameworkServiceLocator;
027import org.kuali.rice.kew.notes.Attachment;
028import org.kuali.rice.kew.notes.CustomNoteAttribute;
029import org.kuali.rice.kew.notes.Note;
030import org.kuali.rice.kew.notes.service.NoteService;
031import org.kuali.rice.kew.routeheader.DocumentRouteHeaderValue;
032import org.kuali.rice.kew.routeheader.service.RouteHeaderService;
033import org.kuali.rice.kew.service.KEWServiceLocator;
034import org.kuali.rice.kew.api.KewApiConstants;
035import org.kuali.rice.kew.web.KewKualiAction;
036import org.kuali.rice.kim.api.identity.Person;
037import org.kuali.rice.kim.api.services.KimApiServiceLocator;
038import org.kuali.rice.krad.UserSession;
039import org.kuali.rice.krad.data.DataObjectService;
040import org.kuali.rice.krad.service.KRADServiceLocator;
041import org.kuali.rice.krad.util.GlobalVariables;
042import org.kuali.rice.krad.util.KRADConstants;
043
044import javax.persistence.EntityManager;
045import javax.servlet.http.HttpServletRequest;
046import javax.servlet.http.HttpServletResponse;
047import java.sql.Timestamp;
048import java.text.DateFormat;
049import java.util.Collections;
050import java.util.Comparator;
051import java.util.Date;
052import java.util.Iterator;
053import java.util.List;
054
055
056/**
057 * Struts action for interfacing with the Notes system.
058 *
059 * @see NoteService
060 *
061 * @author Kuali Rice Team (rice.collab@kuali.org)
062 */
063public class NoteAction extends KewKualiAction {
064
065    private static final org.apache.log4j.Logger LOG = org.apache.log4j.Logger.getLogger(NoteAction.class);
066    private DataObjectService dataObjectService;
067
068    @Override
069    public ActionForward execute(ActionMapping mapping, ActionForm form,
070            HttpServletRequest request, HttpServletResponse response)
071            throws Exception {
072        initForm(request, form);
073        return super.execute(mapping, form, request, response);
074    }
075    
076    //public ActionForward start(ActionMapping mapping, ActionForm form, HttpServletRequest request, HttpServletResponse response) throws Exception {
077    //    return mapping.findForward("allNotesReport");
078    //}
079    
080   
081    @Override
082    public ActionForward start(ActionMapping mapping, ActionForm form, HttpServletRequest request, HttpServletResponse response) throws Exception {
083        NoteForm noteForm = (NoteForm) form;
084        if(StringUtils.isBlank(noteForm.getShowEdit())) {
085                noteForm.setShowEdit("no");
086        }
087        return super.start(mapping, noteForm, request, response);
088    }
089
090    
091    public ActionForward add(ActionMapping mapping, ActionForm form, HttpServletRequest request, HttpServletResponse response) throws Exception {
092        NoteForm noteForm = (NoteForm) form;
093        noteForm.setShowEdit("no");
094        noteForm.setNoteIdNumber(null);
095        retrieveNoteList(request, noteForm);
096        noteForm.setShowAdd(Boolean.TRUE);
097        return start(mapping, form, request, response);
098    }
099
100    public ActionForward deleteAttachment(ActionMapping mapping, ActionForm form, HttpServletRequest request, HttpServletResponse response) throws Exception {
101        NoteForm noteForm = (NoteForm) form;
102        NoteService noteService = KEWServiceLocator.getNoteService();
103        Note note = noteService.getNoteByNoteId(noteForm.getNote().getNoteId());
104        noteService.deleteAttachment(note.getAttachments().remove(0));
105        noteForm.setDocId(note.getDocumentId());
106        noteForm.setNoteIdNumber(note.getNoteId());
107        edit(mapping, form, request, response);
108        return start(mapping, form, request, response);
109        //return mapping.findForward("allNotesReport");
110    }
111
112    public ActionForward edit(ActionMapping mapping, ActionForm form, HttpServletRequest request, HttpServletResponse response) throws Exception {
113        NoteForm noteForm = (NoteForm) form;
114        if ("yes".equalsIgnoreCase(noteForm.getShowEdit())) {
115            noteForm.setNoteIdNumber(noteForm.getNote().getNoteId());
116        } else {
117            noteForm.setShowEdit("yes");
118            Note noteToEdit = getNoteService().getNoteByNoteId(noteForm.getNoteIdNumber());
119            noteForm.setNote(noteToEdit);
120            noteForm.getNote().setNoteCreateLongDate(new Long(noteForm.getNote().getNoteCreateDate().getTime()));
121        }
122        retrieveNoteList(request, noteForm);
123        return start(mapping, form, request, response);
124    }
125
126//    public ActionForward attachFile(ActionMapping mapping, ActionForm form, HttpServletRequest request, HttpServletResponse response) throws Exception {
127//
128//
129//      return start(mapping, form, request, response);
130//    }
131
132    public ActionForward save(ActionMapping mapping, ActionForm form, HttpServletRequest request, HttpServletResponse response) throws Exception {
133        NoteForm noteForm = (NoteForm) form;
134        Note noteToSave = null;
135        if (noteForm.getShowEdit().equals("yes")) {
136            noteToSave = noteForm.getNote();
137            noteToSave.setNoteCreateDate(new Timestamp(noteToSave.getNoteCreateLongDate().longValue()));
138        } else {
139            noteToSave = new Note();
140            noteToSave.setNoteId(null);
141            noteToSave.setDocumentId(noteForm.getDocId());
142            noteToSave.setNoteCreateDate(new Timestamp((new Date()).getTime()));
143            noteToSave.setNoteAuthorWorkflowId(getUserSession().getPrincipalId());
144            noteToSave.setNoteText(noteForm.getAddText());
145        }
146        CustomNoteAttribute customNoteAttribute = null;
147        DocumentRouteHeaderValue routeHeader = getRouteHeaderService().getRouteHeader(noteToSave.getDocumentId());
148        boolean canEditNote = false;
149        boolean canAddNotes = false;
150        if (routeHeader != null) {
151            customNoteAttribute = routeHeader.getCustomNoteAttribute();
152            if (customNoteAttribute != null) {
153                customNoteAttribute.setUserSession(GlobalVariables.getUserSession());
154                canAddNotes = customNoteAttribute.isAuthorizedToAddNotes();
155                canEditNote = customNoteAttribute.isAuthorizedToEditNote(noteToSave);
156            }
157        }
158
159        if ((noteForm.getShowEdit().equals("yes") && canEditNote) ||
160                (!noteForm.getShowEdit().equals("yes") && canAddNotes)) {
161                FormFile uploadedFile = (FormFile)noteForm.getFile();
162                if (uploadedFile != null && StringUtils.isNotBlank(uploadedFile.getFileName())) {
163                        Attachment attachment = new Attachment();
164                        attachment.setAttachedObject(uploadedFile.getInputStream());
165                        attachment.setFileName(uploadedFile.getFileName());
166                        attachment.setMimeType(uploadedFile.getContentType());
167                        attachment.setNote(noteToSave);
168                        noteToSave.getAttachments().add(attachment);
169            } else {
170                if(noteToSave.getNoteId() != null) { //note is not new and we need to ensure the attachments are preserved
171                    noteToSave.setAttachments(getNoteService().getNoteByNoteId(noteToSave.getNoteId()).getAttachments());
172                }
173            }
174            getNoteService().saveNote(noteToSave);
175        }
176        if (noteForm.getShowEdit().equals("yes")) {
177            noteForm.setNote(new Note());
178        } else {
179            noteForm.setAddText(null);
180        }
181        noteForm.setShowEdit("no");
182        noteForm.setNoteIdNumber(null);
183        retrieveNoteList(request, noteForm);
184        flushDocumentHeaderCache();
185
186        return start(mapping, form, request, response);
187    }
188
189    public ActionForward delete(ActionMapping mapping, ActionForm form, HttpServletRequest request, HttpServletResponse response) throws Exception {
190        NoteForm noteForm = (NoteForm) form;
191        Note existingNote = getNoteService().getNoteByNoteId(noteForm.getNoteIdNumber());
192        getNoteService().deleteNote(existingNote);
193        noteForm.setShowEdit("no");
194        noteForm.setNoteIdNumber(null);
195        retrieveNoteList(request, noteForm);
196        return start(mapping, form, request, response);
197    }
198
199    public ActionForward cancel(ActionMapping mapping, ActionForm form, HttpServletRequest request, HttpServletResponse response) throws Exception {
200        NoteForm noteForm = (NoteForm) form;
201        noteForm.setShowEdit("no");
202        noteForm.setNote(new Note());
203        noteForm.setNoteIdNumber(null);
204        retrieveNoteList(request, noteForm);
205        return start(mapping, form, request, response);
206    }
207
208    public ActionForward sort(ActionMapping mapping, ActionForm form, HttpServletRequest request, HttpServletResponse response) throws Exception {
209        return start(mapping, form, request, response);
210    }
211
212
213
214    public ActionMessages initForm(HttpServletRequest request, ActionForm form) throws Exception {
215        NoteForm noteForm = (NoteForm) form;
216        noteForm.setCurrentUserName(getUserSession().getPerson().getName());
217        noteForm.setCurrentDate(getCurrentDate());
218        if (! "workflowReport".equalsIgnoreCase(noteForm.getMethodToCall()) && ! "add".equalsIgnoreCase(noteForm.getMethodToCall()) && ! "cancel".equalsIgnoreCase(noteForm.getMethodToCall()) && ! "edit".equalsIgnoreCase(noteForm.getMethodToCall()) && ! "delete".equalsIgnoreCase(noteForm.getMethodToCall()) && ! "save".equalsIgnoreCase(noteForm.getMethodToCall())) {
219            retrieveNoteList(request, noteForm);
220        }
221        boolean showAttachments = CoreFrameworkServiceLocator.getParameterService().getParameterValueAsBoolean(KewApiConstants.KEW_NAMESPACE, KRADConstants.DetailTypes.ALL_DETAIL_TYPE, KewApiConstants.SHOW_ATTACHMENTS_IND);
222        noteForm.setShowAttachments(new Boolean(showAttachments));
223        return null;
224    }
225
226    private void retrieveNoteList(HttpServletRequest request, NoteForm noteForm) throws Exception {
227        if (noteForm.getDocId() != null) {
228//            List allNotes = getNoteService().getNotesByDocumentId(noteForm.getDocId());
229
230            CustomNoteAttribute customNoteAttribute = null;
231            flushDocumentHeaderCache();
232            DocumentRouteHeaderValue routeHeader = getRouteHeaderService().getRouteHeader(noteForm.getDocId());
233
234            List<Note> allNotes = routeHeader.getNotes();
235            boolean canAddNotes = false;
236            if (routeHeader != null) {
237                customNoteAttribute = routeHeader.getCustomNoteAttribute();
238                if (customNoteAttribute != null) {
239                    customNoteAttribute.setUserSession(GlobalVariables.getUserSession());
240                    canAddNotes = customNoteAttribute.isAuthorizedToAddNotes();
241                }
242            }
243            Iterator<Note> notesIter = allNotes.iterator();
244            while (notesIter.hasNext()) {
245                Note singleNote = notesIter.next();
246                singleNote.setNoteCreateLongDate(new Long(singleNote.getNoteCreateDate().getTime()));
247                getAuthorData(singleNote);
248                boolean canEditNote = false;
249                if (customNoteAttribute != null) {
250                        canEditNote = customNoteAttribute.isAuthorizedToEditNote(singleNote);
251                }
252                singleNote.setAuthorizedToEdit(new Boolean(canEditNote));
253                // KULRICE-5201 - added StringUtils.equals to check equally since this is no longer a numeric (int) comparison
254                if (StringUtils.equals(noteForm.getNoteIdNumber(), singleNote.getNoteId())) {
255                    singleNote.setEditingNote(Boolean.TRUE);
256                }
257            }
258            if (noteForm.getSortNotes() != null && noteForm.getSortNotes().booleanValue()) {
259                if (KewApiConstants.Sorting.SORT_SEQUENCE_DSC.equalsIgnoreCase(noteForm.getSortOrder())) {
260                    noteForm.setSortOrder(KewApiConstants.Sorting.SORT_SEQUENCE_ASC);
261                    noteForm.setSortNotes(Boolean.FALSE);
262                } else {
263                    noteForm.setSortOrder(KewApiConstants.Sorting.SORT_SEQUENCE_DSC);
264                    noteForm.setSortNotes(Boolean.FALSE);
265                }
266            } else {
267                noteForm.setSortOrder(noteForm.getSortOrder());
268            }
269            noteForm.setNoteList(sortNotes(allNotes, noteForm.getSortOrder()));
270            noteForm.setNumberOfNotes(new Integer(allNotes.size()));
271            noteForm.setAuthorizedToAdd(new Boolean(canAddNotes));
272            noteForm.setShowAdd(Boolean.TRUE);
273            if (! canAddNotes) {
274                noteForm.setShowAdd(Boolean.FALSE);
275            } else if (noteForm.getNoteList().size() == 0) {
276                noteForm.setShowAdd(Boolean.FALSE);
277            }
278
279            EntityManager entityManager = (EntityManager) GlobalResourceLoader.getService("rice.kew.entityManager");
280            entityManager.detach(routeHeader);
281        }
282    }
283
284    private void getAuthorData(Note note) throws Exception {
285        Person user = null;
286        String id = "";
287        if (note != null && note.getNoteAuthorWorkflowId() != null && ! "".equalsIgnoreCase(note.getNoteAuthorWorkflowId())) {
288                user = KimApiServiceLocator.getPersonService().getPerson(note.getNoteAuthorWorkflowId());
289            id = note.getNoteAuthorWorkflowId();
290        }
291        if (user != null) {
292            note.setNoteAuthorFullName(user.getName());
293            note.setNoteAuthorEmailAddress(user.getEmailAddressUnmasked());
294            note.setNoteAuthorNetworkId(user.getPrincipalId());
295        } else {
296            note.setNoteAuthorFullName(id + " (Name not Available)");
297            note.setNoteAuthorEmailAddress("Not Available");
298            note.setNoteAuthorNetworkId("Not Available");
299        }
300    }
301
302    public String getCurrentDate() {
303        Date currentDate = new Date();
304        DateFormat dateFormat = RiceConstants.getDefaultDateFormat();
305        return dateFormat.format(currentDate);
306    }
307
308    private List<Note> sortNotes(List<Note> allNotes, String sortOrder) {
309        final int returnCode = KewApiConstants.Sorting.SORT_SEQUENCE_DSC.equalsIgnoreCase(sortOrder) ? -1 : 1;
310
311        try {
312          Collections.sort(allNotes,
313          new Comparator<Note>() {
314            @Override
315                        public int compare(Note o1, Note o2) {
316                        Timestamp date1 = o1.getNoteCreateDate();
317                        Timestamp date2 = o2.getNoteCreateDate();
318
319                if (date1.before(date2)) {
320                  return returnCode * -1;
321                } else if (date1.after(date2)) {
322                  return returnCode;
323                } else {
324                  return 0;
325                }
326            }
327          });
328      } catch (Throwable e) {
329        LOG.error(e.getMessage(), e);
330      }
331      return allNotes;
332    }
333
334    private NoteService getNoteService() {
335        return (NoteService) KEWServiceLocator.getService(KEWServiceLocator.NOTE_SERVICE);
336    }
337
338    private RouteHeaderService getRouteHeaderService() {
339        return (RouteHeaderService) KEWServiceLocator.getService(KEWServiceLocator.DOC_ROUTE_HEADER_SRV);
340    }
341
342    private static UserSession getUserSession() {
343        return GlobalVariables.getUserSession();
344    }
345
346    public DataObjectService getDataObjectService() {
347        if(dataObjectService == null) {
348            dataObjectService = KRADServiceLocator.getDataObjectService();
349        }
350
351        return dataObjectService;
352    }
353
354    private void flushDocumentHeaderCache() {
355        getDataObjectService().flush(DocumentRouteHeaderValue.class);
356    }
357
358}