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