001/**
002 * Copyright 2005-2016 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.edl.impl.components;
017
018import org.apache.commons.fileupload.FileItem;
019import org.apache.commons.lang.StringUtils;
020import org.apache.log4j.Logger;
021import org.kuali.rice.core.api.CoreApiServiceLocator;
022import org.kuali.rice.core.api.config.property.ConfigContext;
023import org.kuali.rice.core.api.mail.EmailBcList;
024import org.kuali.rice.core.api.mail.EmailBody;
025import org.kuali.rice.core.api.mail.EmailCcList;
026import org.kuali.rice.core.api.mail.EmailContent;
027import org.kuali.rice.core.api.mail.EmailFrom;
028import org.kuali.rice.core.api.mail.EmailSubject;
029import org.kuali.rice.core.api.mail.EmailToList;
030import org.kuali.rice.core.api.util.RiceConstants;
031import org.kuali.rice.core.api.util.xml.XmlHelper;
032import org.kuali.rice.core.api.util.xml.XmlJotter;
033import org.kuali.rice.coreservice.api.CoreServiceApiServiceLocator;
034import org.kuali.rice.coreservice.framework.CoreFrameworkServiceLocator;
035import org.kuali.rice.edl.impl.EDLContext;
036import org.kuali.rice.edl.impl.EDLModelComponent;
037import org.kuali.rice.edl.impl.EDLXmlUtils;
038import org.kuali.rice.edl.impl.RequestParser;
039import org.kuali.rice.edl.impl.service.EdlServiceLocator;
040import org.kuali.rice.kew.api.KewApiConstants;
041import org.kuali.rice.kew.api.WorkflowDocument;
042import org.kuali.rice.kew.api.WorkflowRuntimeException;
043import org.kuali.rice.kew.mail.EmailStyleHelper;
044import org.kuali.rice.kew.notes.Attachment;
045import org.kuali.rice.kew.notes.CustomNoteAttribute;
046import org.kuali.rice.kew.notes.Note;
047import org.kuali.rice.kew.notes.service.NoteService;
048import org.kuali.rice.kew.routeheader.DocumentRouteHeaderValue;
049import org.kuali.rice.kew.routeheader.service.RouteHeaderService;
050import org.kuali.rice.kew.service.KEWServiceLocator;
051import org.kuali.rice.kim.api.identity.Person;
052import org.kuali.rice.kim.api.services.KimApiServiceLocator;
053import org.w3c.dom.Document;
054import org.w3c.dom.Element;
055
056import javax.xml.bind.JAXBContext;
057import javax.xml.bind.Marshaller;
058import javax.xml.parsers.DocumentBuilder;
059import javax.xml.parsers.DocumentBuilderFactory;
060import javax.xml.transform.Templates;
061import javax.xml.transform.TransformerConfigurationException;
062import javax.xml.xpath.XPath;
063import javax.xml.xpath.XPathConstants;
064import javax.xml.xpath.XPathExpressionException;
065import javax.xml.xpath.XPathFactory;
066import java.sql.Timestamp;
067import java.text.DateFormat;
068import java.util.ArrayList;
069import java.util.Collections;
070import java.util.Comparator;
071import java.util.Date;
072import java.util.Iterator;
073import java.util.List;
074import java.util.StringTokenizer;
075import java.util.regex.Matcher;
076import java.util.regex.Pattern;
077
078/**
079 * Adds notes support to EDL
080 * 
081 * @author Kuali Rice Team (rice.collab@kuali.org)
082 * 
083 */
084public class NoteConfigComponent implements EDLModelComponent {
085
086    private static final Logger LOG = Logger.getLogger(NoteConfigComponent.class);
087
088    private EmailStyleHelper emailStyleHelper = new EmailStyleHelper();
089    private String styleName;
090    private String from;
091    private List<String> to;
092    private List<String> cc = new ArrayList<String>();
093    private List<String> bc = new ArrayList<String>();
094    private static final String DEFAULT_EMAIL_FROM_ADDRESS = CoreFrameworkServiceLocator.getParameterService()
095            .getParameterValueAsString(KewApiConstants.KEW_NAMESPACE, "Mailer", "FROM_ADDRESS");//"workflow@indiana.edu";
096
097    public void updateDOM(Document dom, Element configElement, EDLContext edlContext) {
098        NoteForm noteForm = new NoteForm(edlContext.getRequestParser());
099        WorkflowDocument document = (WorkflowDocument) edlContext.getRequestParser().getAttribute(
100                RequestParser.WORKFLOW_DOCUMENT_SESSION_KEY);
101        try {
102            //establish notes depends on a document id being set on noteform or nothing happens
103            if (document != null) {
104                noteForm.setDocId(document.getDocumentId());
105            }
106            establishNotes(noteForm, edlContext, dom);
107            addNotes(dom, noteForm);
108        } catch (Exception e) {
109            throw new WorkflowRuntimeException("Caught exception processing notes", e);
110        }
111
112    }
113
114    public void establishNotes(NoteForm form, EDLContext edlContext, Document dom) throws Exception {
115
116        form.setCurrentUserName(edlContext.getUserSession().getPerson().getName());
117        form.setCurrentDate(getCurrentDate());
118        String methodToCall = form.getMethodToCall();
119        if (!org.apache.commons.lang.StringUtils.isEmpty(methodToCall)) {
120            if ("save".equalsIgnoreCase(methodToCall)) {
121                this.saveNote(form, edlContext, dom);
122            } else if ("edit".equalsIgnoreCase(methodToCall)) {
123                this.editNote(form);
124            } else if ("add".equalsIgnoreCase(methodToCall)) {
125                this.addNote(form);
126            } else if ("cancel".equalsIgnoreCase(methodToCall)) {
127                this.cancelEdit(form);
128            } else if ("delete".equalsIgnoreCase(methodToCall)) {
129                this.deleteNote(form);
130            } else if ("sort".equalsIgnoreCase(methodToCall)) {
131                this.sortNotes(form);
132            } else if ("deleteAttachment".equalsIgnoreCase(methodToCall)) {
133                this.deleteAttachment(form);
134            }
135        }
136        retrieveNoteList(form, edlContext);
137
138    }
139
140    /**
141     * Method added for notes editing function. Retrieve Note Listing from Route Header and put that
142     * in EdocLiteForm.
143     * @param request
144     * @param noteForm
145     * @throws Exception
146     */
147
148    private void retrieveNoteList(NoteForm form, EDLContext edlContext) throws Exception {
149        if (form.getDocId() != null) {
150            List allNotes = getNoteService().getNotesByDocumentId(form.getDocId());
151            CustomNoteAttribute customNoteAttribute = null;
152            DocumentRouteHeaderValue routeHeader = getRouteHeaderService().getRouteHeader(form.getDocId());
153            boolean canAddNotes = false;
154            if (routeHeader != null) {
155                customNoteAttribute = routeHeader.getCustomNoteAttribute();
156                if (customNoteAttribute != null) {
157                    customNoteAttribute.setUserSession(edlContext.getUserSession());
158                    canAddNotes = customNoteAttribute.isAuthorizedToAddNotes();
159                }
160            }
161            Iterator notesIter = allNotes.iterator();
162            while (notesIter.hasNext()) {
163                Note singleNote = (Note) notesIter.next();
164                singleNote.setNoteCreateLongDate(new Long(singleNote.getNoteCreateDate().getTime()));
165                getAuthorData(singleNote);
166                boolean canEditNote = false;
167                if (customNoteAttribute != null) {
168                    canEditNote = customNoteAttribute.isAuthorizedToEditNote(singleNote);
169                }
170                singleNote.setAuthorizedToEdit(Boolean.valueOf(canEditNote));
171                if (form.getNoteIdNumber() != null
172                        && (StringUtils.equals(form.getNoteIdNumber(), singleNote.getNoteId()))) {
173                    singleNote.setEditingNote(Boolean.TRUE);
174                }
175            }
176            if (form.getSortNotes() != null && form.getSortNotes().booleanValue()) {
177                if (KewApiConstants.Sorting.SORT_SEQUENCE_DSC.equalsIgnoreCase(form.getSortOrder())) {
178                    form.setSortOrder(KewApiConstants.Sorting.SORT_SEQUENCE_ASC);
179                    form.setSortNotes(Boolean.FALSE);
180                } else {
181                    form.setSortOrder(KewApiConstants.Sorting.SORT_SEQUENCE_DSC);
182                    form.setSortNotes(Boolean.FALSE);
183                }
184            } else {
185                form.setSortOrder(form.getSortOrder());
186            }
187            form.setNoteList(sortNotes(allNotes, form.getSortOrder()));
188            form.setNumberOfNotes(new Integer(allNotes.size()));
189            form.setAuthorizedToAdd(new Boolean(canAddNotes));
190            form.setShowAdd(Boolean.TRUE);
191            if (!canAddNotes) {
192                form.setShowAdd(Boolean.FALSE);
193            } else if (form.getNoteList().size() == 0) {
194                //form.setShowAdd(Boolean.TRUE);
195            }
196        }
197    }
198
199    public void editNote(NoteForm form) throws Exception {
200        form.setShowEdit("yes");
201        // Note noteToEdit =
202        // getNoteService().getNoteByNoteId(form.getNoteIdNumber());
203        //form.setNote(noteToEdit);
204        form.getNote().setNoteCreateLongDate(new Long(form.getNote().getNoteCreateDate().getTime()));
205        form.getNote().setNoteText(form.getNoteText());
206        //retrieveNoteList(request, form);
207    }
208
209    public void addNote(NoteForm form) throws Exception {
210        form.setShowEdit("no");
211        form.setNoteIdNumber(null);
212        form.setShowAdd(Boolean.TRUE);
213        //retrieveNoteList(request,form);
214
215    }
216
217    public void cancelEdit(NoteForm form) throws Exception {
218        form.setShowEdit("no");
219        form.setNote(new Note());
220        form.setNoteIdNumber(null);
221        //retrieveNoteList(request, form);
222    }
223
224    public void deleteNote(NoteForm form) throws Exception {
225        Note noteToDelete = getNoteService().getNoteByNoteId(form.getNoteIdNumber());
226        getNoteService().deleteNote(noteToDelete);
227        form.setShowEdit("no");
228        //retrieveNoteList(request, form);
229        form.setNote(new Note());
230        form.setNoteIdNumber(null);
231    }
232
233    public void sortNotes(NoteForm form) throws Exception {
234        form.setShowEdit("no");
235    }
236
237    public void deleteAttachment(NoteForm form) throws Exception {
238        Note note = getNoteService().getNoteByNoteId(form.getNoteIdNumber());
239        getNoteService().deleteAttachment((Attachment) note.getAttachments().remove(0));
240    }
241
242    public void saveNote(NoteForm form, EDLContext edlContext, Document dom) throws Exception {
243        Note noteToSave = null;
244        if (form.getShowEdit() != null && form.getShowEdit().equals("yes")) {
245            //LOG.debug(form.getNoteIdNumber());
246            noteToSave = getNoteService().getNoteByNoteId(form.getNoteIdNumber());
247            String noteText = form.getNoteText();
248            if (noteText != null) {
249                noteToSave.setNoteText(noteText);
250            }
251            //LOG.debug(noteToSave);
252            //LOG.debug(noteToSave.getNoteCreateDate());
253            //noteToSave.setNoteCreateDate(new Timestamp(noteToSave.getNoteCreateLongDate().longValue()));
254        } else {
255            noteToSave = new Note();
256            noteToSave.setNoteId(null);
257            noteToSave.setDocumentId(form.getDocId());
258            noteToSave.setNoteCreateDate(new Timestamp((new Date()).getTime()));
259            noteToSave.setNoteAuthorWorkflowId(edlContext.getUserSession().getPrincipalId());
260            noteToSave.setNoteText(form.getAddText());
261        }
262        CustomNoteAttribute customNoteAttribute = null;
263        DocumentRouteHeaderValue routeHeader = getRouteHeaderService().getRouteHeader(noteToSave.getDocumentId());
264        boolean canEditNote = false;
265        boolean canAddNotes = false;
266        if (routeHeader != null) {
267            customNoteAttribute = routeHeader.getCustomNoteAttribute();
268            if (customNoteAttribute != null) {
269                customNoteAttribute.setUserSession(edlContext.getUserSession());
270                canAddNotes = customNoteAttribute.isAuthorizedToAddNotes();
271                canEditNote = customNoteAttribute.isAuthorizedToEditNote(noteToSave);
272            }
273        }
274        if ((form.getShowEdit() != null && form.getShowEdit().equals("yes") && canEditNote) ||
275                ((form.getShowEdit() == null || !form.getShowEdit().equals("yes")) && canAddNotes)) {
276            FileItem uploadedFile = (FileItem) form.getFile();
277            if (uploadedFile != null && org.apache.commons.lang.StringUtils.isNotBlank(uploadedFile.getName())) {
278                Attachment attachment = new Attachment();
279                attachment.setAttachedObject(uploadedFile.getInputStream());
280                String internalFileIndicator = uploadedFile.getName();
281                int indexOfSlash = internalFileIndicator.lastIndexOf("/");
282                int indexOfBackSlash = internalFileIndicator.lastIndexOf("\\");
283                if (indexOfSlash >= 0) {
284                    internalFileIndicator = internalFileIndicator.substring(indexOfSlash + 1);
285                } else {
286                    if (indexOfBackSlash >= 0) {
287                        internalFileIndicator = internalFileIndicator.substring(indexOfBackSlash + 1);
288                    }
289                }
290                attachment.setFileName(internalFileIndicator);
291                LOG.debug(internalFileIndicator);
292                attachment.setMimeType(uploadedFile.getContentType());
293                attachment.setNote(noteToSave);
294                noteToSave.getAttachments().add(attachment);
295            }
296            if (org.apache.commons.lang.StringUtils.isEmpty(noteToSave.getNoteText())
297                    && noteToSave.getAttachments().size() == 0) {
298                if (form.getShowEdit() != null && form.getShowEdit().equals("yes")) {
299                    form.setNote(new Note());
300                } else {
301                    form.setAddText(null);
302                }
303                form.setShowEdit("no");
304                form.setNoteIdNumber(null);
305                //                      throw new Exception("Note has empty content");
306                EDLXmlUtils.addGlobalErrorMessage(dom, "Note has empty content");
307                return;
308            }
309            getNoteService().saveNote(noteToSave);
310
311            // add ability to send emails when a note is saved. 
312            boolean sendEmailOnNoteSave = false;
313            // Check if edoclite specifies <param name="sendEmailOnNoteSave">
314            Document edlDom = EdlServiceLocator.getEDocLiteService()
315                    .getDefinitionXml(edlContext.getEdocLiteAssociation());
316            XPath xpath = edlContext.getXpath();
317            String xpathExpression = "//config/param[@name='sendEmailOnNoteSave']";
318            try {
319                String match = (String) xpath.evaluate(xpathExpression, edlDom, XPathConstants.STRING);
320                if (!StringUtils.isBlank(match) && match.equals("true")) {
321                    sendEmailOnNoteSave = true;
322                }
323            } catch (XPathExpressionException e) {
324                throw new WorkflowRuntimeException(
325                        "Unable to evaluate sendEmailOnNoteSave xpath expression in NoteConfigComponent saveNote method"
326                                + xpathExpression, e);
327            }
328
329            if (sendEmailOnNoteSave) {
330                xpathExpression = "//data/version[@current='true']/field[@name='emailTo']/value";
331                String emailTo = xpath.evaluate(xpathExpression, dom);
332                if (StringUtils.isBlank(emailTo)) {
333                    EDLXmlUtils.addGlobalErrorMessage(dom,
334                            "No email notifications were sent because EmailTo field was empty.");
335                    return;
336                }
337                // Actually send the emails.
338                if (isProduction()) {
339                    this.to = stringToList(emailTo);
340                } else {
341                    String testAddress = getTestAddress(edlDom);
342                    if (StringUtils.isBlank(testAddress)) {
343                        EDLXmlUtils
344                                .addGlobalErrorMessage(
345                                        dom,
346                                        "No email notifications were sent because testAddress edl param was empty or not specified in a non production environment");
347                        return;
348                    }
349                    this.to = stringToList(getTestAddress(edlDom));
350                }
351                if (!isEmailListValid(this.to)) {
352                    EDLXmlUtils
353                            .addGlobalErrorMessage(
354                                    dom,
355                                    "No email notifications were sent because emailTo field contains invalid email address.");
356                    return;
357                }
358                String noteEmailStylesheet = "";
359                xpathExpression = "//config/param[@name='noteEmailStylesheet']";
360                try {
361                    noteEmailStylesheet = (String) xpath.evaluate(
362                            xpathExpression, edlDom, XPathConstants.STRING);
363                    if (StringUtils.isBlank(noteEmailStylesheet)) {
364                        EDLXmlUtils
365                                .addGlobalErrorMessage(
366                                        dom,
367                                        "No email notifications were sent because noteEmailStylesheet edl param was empty or not specified.");
368                        return;
369                    }
370                } catch (XPathExpressionException e) {
371                    throw new WorkflowRuntimeException(
372                            "Unable to evaluate noteEmailStylesheet xpath expression in NoteConfigComponent method"
373                                    + xpathExpression, e);
374                }
375                this.styleName = noteEmailStylesheet;
376                this.from = DEFAULT_EMAIL_FROM_ADDRESS;
377                Document document = generateXmlInput(form, edlContext, edlDom);
378                if (LOG.isDebugEnabled()) {
379                    LOG.debug("XML input for email tranformation:\n" + XmlJotter.jotNode(document));
380                }
381                Templates style = loadStyleSheet(styleName);
382                EmailContent emailContent = emailStyleHelper
383                        .generateEmailContent(style, document);
384                if (!this.to.isEmpty()) {
385                    CoreApiServiceLocator.getMailer().sendEmail(
386                            new EmailFrom(from), new EmailToList(this.to),
387                            new EmailSubject(emailContent.getSubject()),
388                            new EmailBody(emailContent.getBody()),
389                            new EmailCcList(this.cc), new EmailBcList(this.bc),
390                            emailContent.isHtml());
391                }
392            }
393
394        }
395        if (form.getShowEdit() != null && form.getShowEdit().equals("yes")) {
396            form.setNote(new Note());
397        } else {
398            form.setAddText(null);
399        }
400        form.setShowEdit("no");
401        form.setNoteIdNumber(null);
402    }
403
404    protected String getTestAddress(Document edlDom) {
405        String testAddress = "";
406        XPath xpath = XPathFactory.newInstance().newXPath();
407        String xpathExpression = "//config/param[@name='testAddress']";
408        try {
409            testAddress = (String) xpath.evaluate(xpathExpression, edlDom, XPathConstants.STRING);
410        } catch (XPathExpressionException e) {
411            throw new WorkflowRuntimeException(
412                    "Unable to evaluate testAddressAttributeFound xpath expression in NoteConfigComponent getTestAddress method"
413                            + xpathExpression, e);
414        }
415        return testAddress;
416    }
417
418    protected Document generateXmlInput(NoteForm form, EDLContext edlContext, Document dom) throws Exception {
419        DocumentBuilder db = getDocumentBuilder(true);
420        Document doc = db.newDocument();
421        Element emailNodeElem = doc.createElement("emailNode");
422        doc.appendChild(emailNodeElem);
423        WorkflowDocument document = (WorkflowDocument) edlContext.getRequestParser().getAttribute(
424                RequestParser.WORKFLOW_DOCUMENT_SESSION_KEY);
425
426        /* Upgrade Changes 0914 to 1011 */
427        //RouteHeaderVO routeHeaderVO = document.getRouteHeader();
428        JAXBContext jaxb = JAXBContext.newInstance(org.kuali.rice.kew.api.document.Document.class);
429        Marshaller marshaller = jaxb.createMarshaller();
430        marshaller.marshal(document.getDocument(), emailNodeElem);
431        emailNodeElem.appendChild(doc.importNode(dom.getDocumentElement(), true));
432        Element dConElem = XmlHelper.readXml(document.getDocumentContent().getApplicationContent())
433                .getDocumentElement(); //Add document Content element for
434        emailNodeElem.appendChild(doc.importNode(dConElem, true)); //access by the stylesheet when creating the email
435        return doc;
436    }
437
438    protected DocumentBuilder getDocumentBuilder(boolean coalesce) throws Exception {
439        DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
440        dbf.setCoalescing(coalesce);
441        return dbf.newDocumentBuilder();
442    }
443
444    /* Upgrade Changes 0914 to 1011 */
445    /*
446    protected boolean isProduction() {
447    return EdenConstants.PROD_DEPLOYMENT_CODE.equalsIgnoreCase(Core.getCurrentContextConfig().getEnvironment());
448    }
449    */
450    protected boolean isProduction() {
451        return ConfigContext.getCurrentContextConfig().isProductionEnvironment();
452    }
453
454    protected boolean isEmailListValid(List<String> emailList) {
455        Pattern p = Pattern.compile("^\\.|^\\@");
456        Matcher m = null;
457        for (String emailAddress : emailList) {
458            m = p.matcher(emailAddress);
459            if (m.find()) {
460                //System.err.println("Email addresses don't start with dots or @ signs.");
461                return false;
462            }
463        }
464        p = Pattern.compile("^www\\.");
465        for (String emailAddress : emailList) {
466            m = p.matcher(emailAddress);
467            if (m.find()) {
468                //System.err.println("Email addresses don't start with \"www.\", only web pages do.");
469                return false;
470            }
471        }
472        // find illegal characters.
473        p = Pattern.compile("[^A-Za-z0-9\\.\\@_\\-~#]+");
474        for (String emailAddress : emailList) {
475            // strip comma at end if there is one.
476            String e2 = stripComma(emailAddress);
477            m = p.matcher(e2);
478            if (m.find()) {
479                //System.err.println("Email address contains illegal character(s).");
480                return false;
481            }
482        }
483        // email address should match this pattern.
484        p = Pattern.compile("^([a-zA-Z0-9_\\-\\.]+)\\@([a-zA-Z0-9_\\-\\.]+)\\.([a-zA-Z]{2,5})$");
485        for (String emailAddress : emailList) {
486            String e2 = stripComma(emailAddress);
487            m = p.matcher(e2);
488            if (!m.find()) {
489                //System.err.println("Illegal Email address format.");
490                return false;
491            }
492        }
493        return true;
494    }
495
496    protected String stripComma(String s) {
497        String sNew = "";
498        if (s.endsWith(",")) {
499            int x = s.length() - 1;
500            sNew = s.substring(0, x);
501        } else {
502            sNew = s;
503        }
504        return sNew;
505    }
506
507    protected List<String> stringToList(String to) {
508        List<String> recipientAddresses = new ArrayList<String>();
509        StringTokenizer st = new StringTokenizer(to, " ", false);
510        while (st.hasMoreTokens()) {
511            recipientAddresses.add(st.nextToken());
512        }
513        return recipientAddresses;
514    }
515
516    protected Templates loadStyleSheet(String styleName) {
517        try {
518            Templates style = CoreServiceApiServiceLocator.getStyleService().getStyleAsTranslet(styleName);
519            if (style == null) {
520                throw new WorkflowRuntimeException("Failed to locate stylesheet with name '" + styleName + "'");
521            }
522            return style;
523        } catch (TransformerConfigurationException tce) {
524            throw new WorkflowRuntimeException("Failed to load stylesheet with name '" + styleName + "'");
525        }
526    }
527
528    public static void addNotes(Document doc, NoteForm form) {
529        Element noteForm = EDLXmlUtils.getOrCreateChildElement(doc.getDocumentElement(), "NoteForm", true);
530        if (form.getShowEdit() != null) {
531            Element showEdit = EDLXmlUtils.getOrCreateChildElement(noteForm, "showEdit", true);
532            showEdit.appendChild(doc.createTextNode(form.getShowEdit().toLowerCase()));
533        } else {
534            Element showEdit = EDLXmlUtils.getOrCreateChildElement(noteForm, "showEdit", true);
535            showEdit.appendChild(doc.createTextNode("no"));
536        }
537        if (form.getShowAdd() != null) {
538            Element showAdd = EDLXmlUtils.getOrCreateChildElement(noteForm, "showAdd", true);
539            showAdd.appendChild(doc.createTextNode(form.getShowAdd().toString().toLowerCase()));
540        }
541        if (form.getCurrentUserName() != null) {
542            Element currentUserName = EDLXmlUtils.getOrCreateChildElement(noteForm, "currentUserName", true);
543            currentUserName.appendChild(doc.createTextNode(form.getCurrentUserName()));
544        }
545        if (form.getCurrentDate() != null) {
546            Element currentDate = EDLXmlUtils.getOrCreateChildElement(noteForm, "currentDate", true);
547            currentDate.appendChild(doc.createTextNode(form.getCurrentDate()));
548        }
549        if (form.getNoteIdNumber() != null) {
550            Element noteIdNumber = EDLXmlUtils.getOrCreateChildElement(noteForm, "noteIdNumber", true);
551            noteIdNumber.appendChild(doc.createTextNode(form.getNoteIdNumber().toString()));
552        }
553        if (form.getDocId() != null) {
554            Element docId = EDLXmlUtils.getOrCreateChildElement(noteForm, "docId", true);
555            docId.appendChild(doc.createTextNode((form.getDocId().toString())));
556        }
557        if (form.getSortNotes() != null) {
558            Element sortNotes = EDLXmlUtils.getOrCreateChildElement(noteForm, "sortNotes", true);
559            sortNotes.appendChild(doc.createTextNode(form.getSortNotes().toString().toLowerCase()));
560        }
561        if (form.getSortOrder() != null) {
562            Element sortOrder = EDLXmlUtils.getOrCreateChildElement(noteForm, "sortOrder", true);
563            sortOrder.appendChild(doc.createTextNode(form.getSortOrder().toUpperCase()));
564        }
565        if (form.getNumberOfNotes() != null) {
566            Element numberOfNotes = EDLXmlUtils.getOrCreateChildElement(noteForm, "numberOfNotes", true);
567            numberOfNotes.appendChild(doc.createTextNode(form.getNumberOfNotes().toString()));
568        }
569        if (form.getAuthorizedToAdd() != null) {
570            Element authorizedToAdd = EDLXmlUtils.getOrCreateChildElement(noteForm, "authorizedToAdd", true);
571            authorizedToAdd.appendChild(doc.createTextNode(form.getAuthorizedToAdd().toString().toLowerCase()));
572        }
573        if (form.getNumberOfNotes().intValue() > 0) {
574            Element notes = EDLXmlUtils.getOrCreateChildElement(noteForm, "Notes", true);
575            for (Iterator i = form.getNoteList().iterator(); i.hasNext();) {
576                Note noteObj = (Note) i.next();
577                Element note = notes.getOwnerDocument().createElement("Note");
578                notes.appendChild(note);
579                // Element note = Util.getOrCreateChildElement(notes, "Note",
580                // true);
581                if (noteObj.getNoteId() != null) {
582                    Element noteId = EDLXmlUtils.getOrCreateChildElement(note, "noteId", true);
583                    noteId.appendChild(doc.createTextNode(noteObj.getNoteId().toString()));
584                }
585                if (noteObj.getFormattedCreateDate() != null) {
586                    Element formattedCreateDate = EDLXmlUtils
587                            .getOrCreateChildElement(note, "formattedCreateDate", true);
588                    formattedCreateDate.appendChild(doc.createTextNode(noteObj.getFormattedCreateDate()));
589                }
590                if (noteObj.getFormattedCreateTime() != null) {
591                    Element formattedCreateTime = EDLXmlUtils
592                            .getOrCreateChildElement(note, "formattedCreateTime", true);
593                    formattedCreateTime.appendChild(doc.createTextNode(noteObj.getFormattedCreateTime()));
594                }
595                if (noteObj.getNoteAuthorFullName() != null) {
596                    Element noteAuthorFullName = EDLXmlUtils.getOrCreateChildElement(note, "noteAuthorFullName", true);
597                    noteAuthorFullName.appendChild(doc.createTextNode(noteObj.getNoteAuthorFullName()));
598                }
599                if (noteObj.getNoteText() != null) {
600                    Element noteText = EDLXmlUtils.getOrCreateChildElement(note, "noteText", true);
601                    noteText.appendChild(doc.createTextNode(noteObj.getNoteText()));
602                }
603                if (noteObj.getEditingNote() != null) {
604                    Element editingNote = EDLXmlUtils.getOrCreateChildElement(note, "editingNote", true);
605                    editingNote.appendChild(doc.createTextNode(noteObj.getEditingNote().toString()));
606                }
607                if (noteObj.getAuthorizedToEdit() != null) {
608                    Element authorizedToEdit = EDLXmlUtils.getOrCreateChildElement(note, "authorizedToEdit", true);
609                    authorizedToEdit.appendChild(doc.createTextNode(noteObj.getAuthorizedToEdit().toString()));
610                }
611                if (!noteObj.getAttachments().isEmpty()) {
612                    Element attachments = EDLXmlUtils.getOrCreateChildElement(note, "attachments", true);
613                    for (Iterator j = noteObj.getAttachments().iterator(); j.hasNext();) {
614                        Attachment attachmentObj = (Attachment) j.next();
615                        Element attachment = EDLXmlUtils.getOrCreateChildElement(attachments, "attachment", true);
616                        Element attachmentId = EDLXmlUtils.getOrCreateChildElement(attachment, "attachmentId", true);
617                        attachmentId.appendChild(doc.createTextNode(attachmentObj.getAttachmentId().toString()));
618                        Element fileName = EDLXmlUtils.getOrCreateChildElement(attachment, "fileName", true);
619                        fileName.appendChild(doc.createTextNode(attachmentObj.getFileName()));
620                    }
621                }
622            }
623        }
624
625    }
626
627    private static class NoteForm {
628        private String showEdit;
629        private Boolean showAdd;
630        private String noteIdNumber;
631        private Integer numberOfNotes = new Integer(0);
632        private String sortOrder = "DESCENDING";
633        private Boolean sortNotes;
634        private String currentUserName;
635        private String currentDate;
636        private Boolean authorizedToAdd;
637        private List noteList;
638        private String addText;
639        private Long idInEdit;
640        private Note note;
641        private String noteText;
642        private String docId;
643        private String methodToCall;
644        private FileItem file;
645
646        public NoteForm(RequestParser requestParser) {
647
648            showEdit = requestParser.getParameterValue("showEdit");
649            if (!org.apache.commons.lang.StringUtils.isEmpty(requestParser.getParameterValue("showAdd"))) {
650                showAdd = Boolean.valueOf(requestParser.getParameterValue("showAdd"));
651            }
652            if (!org.apache.commons.lang.StringUtils.isEmpty(requestParser.getParameterValue("noteIdNumber"))) {
653                noteIdNumber = requestParser.getParameterValue("noteIdNumber");
654            }
655            methodToCall = requestParser.getParameterValue("methodToCall");
656            sortOrder = "DESCENDING";
657            if (!org.apache.commons.lang.StringUtils.isEmpty(requestParser.getParameterValue("sortNotes"))) {
658                sortNotes = Boolean.valueOf(requestParser.getParameterValue("sortNotes"));
659            }
660            addText = requestParser.getParameterValue("addText");
661            noteText = requestParser.getParameterValue("noteText");
662            if (!org.apache.commons.lang.StringUtils.isEmpty(requestParser.getParameterValue("idInEdit"))) {
663                idInEdit = Long.valueOf(requestParser.getParameterValue("idInEdit"));
664            }
665            if (noteIdNumber != null) {
666                note = KEWServiceLocator.getNoteService().getNoteByNoteId(noteIdNumber);
667            }
668            if (requestParser.getUploadList() != null && !requestParser.getUploadList().isEmpty()) {
669                file = (FileItem) requestParser.getUploadList().get(0);
670            }
671        }
672
673        public String getAddText() {
674            return addText;
675        }
676
677        public void setAddText(String addText) {
678            this.addText = addText;
679        }
680
681        public Boolean getAuthorizedToAdd() {
682            return authorizedToAdd;
683        }
684
685        public void setAuthorizedToAdd(Boolean authorizedToAdd) {
686            this.authorizedToAdd = authorizedToAdd;
687        }
688
689        public String getCurrentDate() {
690            return currentDate;
691        }
692
693        public void setCurrentDate(String currentDate) {
694            this.currentDate = currentDate;
695        }
696
697        public String getCurrentUserName() {
698            return currentUserName;
699        }
700
701        public void setCurrentUserName(String currentUserName) {
702            this.currentUserName = currentUserName;
703        }
704
705        public Long getIdInEdit() {
706            return idInEdit;
707        }
708
709        public void setIdInEdit(Long idInEdit) {
710            this.idInEdit = idInEdit;
711        }
712
713        public Note getNote() {
714            return note;
715        }
716
717        public void setNote(Note note) {
718            this.note = note;
719        }
720
721        public String getNoteIdNumber() {
722            return noteIdNumber;
723        }
724
725        public void setNoteIdNumber(String noteIdNumber) {
726            this.noteIdNumber = noteIdNumber;
727        }
728
729        public List getNoteList() {
730            return noteList;
731        }
732
733        public void setNoteList(List noteList) {
734            this.noteList = noteList;
735        }
736
737        public String getNoteText() {
738            return noteText;
739        }
740
741        public void setNoteText(String noteText) {
742            this.noteText = noteText;
743        }
744
745        public Integer getNumberOfNotes() {
746            return numberOfNotes;
747        }
748
749        public void setNumberOfNotes(Integer numberOfNotes) {
750            this.numberOfNotes = numberOfNotes;
751        }
752
753        public Boolean getShowAdd() {
754            return showAdd;
755        }
756
757        public void setShowAdd(Boolean showAdd) {
758            this.showAdd = showAdd;
759        }
760
761        public String getShowEdit() {
762            return showEdit;
763        }
764
765        public void setShowEdit(String showEdit) {
766            this.showEdit = showEdit;
767        }
768
769        public Boolean getSortNotes() {
770            return sortNotes;
771        }
772
773        public void setSortNotes(Boolean sortNotes) {
774            this.sortNotes = sortNotes;
775        }
776
777        public String getSortOrder() {
778            return sortOrder;
779        }
780
781        public void setSortOrder(String sortOrder) {
782            this.sortOrder = sortOrder;
783        }
784
785        public String getDocId() {
786            return docId;
787        }
788
789        public void setDocId(String docId) {
790            this.docId = docId;
791        }
792
793        public String getMethodToCall() {
794            return methodToCall;
795        }
796
797        public void setMethodToCall(String methodToCall) {
798            this.methodToCall = methodToCall;
799        }
800
801        public FileItem getFile() {
802            return file;
803        }
804
805        public void setFile(FileItem file) {
806            this.file = file;
807        }
808    }
809
810    /**
811     * Method added for notes editing function. Called by retrieveNoteList method
812     * @param allNotes
813     * @param sortOrder
814     * @return
815     */
816
817    private List sortNotes(List allNotes, String sortOrder) {
818        final int returnCode = KewApiConstants.Sorting.SORT_SEQUENCE_DSC.equalsIgnoreCase(sortOrder) ? -1 : 1;
819
820        try {
821            Collections.sort(allNotes,
822                    new Comparator() {
823                        public int compare(Object o1, Object o2) {
824                            Timestamp date1 = ((Note) o1).getNoteCreateDate();
825                            Timestamp date2 = ((Note) o2).getNoteCreateDate();
826
827                            if (date1.before(date2)) {
828                                return returnCode * -1;
829                            } else if (date1.after(date2)) {
830                                return returnCode;
831                            } else {
832                                return 0;
833                            }
834                        }
835                    });
836        } catch (Throwable e) {
837            LOG.error(e.getMessage(), e);
838        }
839        return allNotes;
840    }
841
842    /**
843     * Method added for notes editing function. Called by retrieveNoteList method
844     * @param note
845     * @throws Exception
846     */
847
848    private void getAuthorData(Note note) throws Exception {
849        Person workflowUser = null;
850        String id = "";
851        if (note != null && note.getNoteAuthorWorkflowId() != null
852                && !"".equalsIgnoreCase(note.getNoteAuthorWorkflowId())) {
853            workflowUser = KimApiServiceLocator.getPersonService().getPerson(note.getNoteAuthorWorkflowId());
854            id = note.getNoteAuthorWorkflowId();
855        }
856        if (workflowUser != null) {
857            note.setNoteAuthorFullName(workflowUser.getName());
858            note.setNoteAuthorEmailAddress(workflowUser.getEmailAddress());
859            note.setNoteAuthorNetworkId(workflowUser.getPrincipalName());
860        } else {
861            note.setNoteAuthorFullName(id + " (Name not Available)");
862            note.setNoteAuthorEmailAddress("Not Available");
863            note.setNoteAuthorNetworkId("Not Available");
864        }
865    }
866
867    public String getCurrentDate() {
868        Date currentDate = new Date();
869        DateFormat dateFormat = RiceConstants.getDefaultDateFormat();
870        return dateFormat.format(currentDate);
871    }
872
873    /**
874     * Method added for notes editing function.
875     * @return
876     */
877    private NoteService getNoteService() {
878        return (NoteService) KEWServiceLocator.getService(KEWServiceLocator.NOTE_SERVICE);
879    }
880
881    /**
882     * Method added for notes editing function.
883     * @return
884     */
885    private RouteHeaderService getRouteHeaderService() {
886        return (RouteHeaderService) KEWServiceLocator.getService(KEWServiceLocator.DOC_ROUTE_HEADER_SRV);
887    }
888}