Coverage Report - org.kuali.rice.kew.mail.service.impl.StyleableEmailContentServiceImpl
 
Classes in this File Line Coverage Branch Coverage Complexity
StyleableEmailContentServiceImpl
0%
0/231
0%
0/48
2.955
 
 1  
 /**
 2  
  * Copyright 2005-2011 The Kuali Foundation
 3  
  *
 4  
  * Licensed under the Educational Community License, Version 2.0 (the "License");
 5  
  * you may not use this file except in compliance with the License.
 6  
  * You may obtain a copy of the License at
 7  
  *
 8  
  * http://www.opensource.org/licenses/ecl2.php
 9  
  *
 10  
  * Unless required by applicable law or agreed to in writing, software
 11  
  * distributed under the License is distributed on an "AS IS" BASIS,
 12  
  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 13  
  * See the License for the specific language governing permissions and
 14  
  * limitations under the License.
 15  
  */
 16  
 package org.kuali.rice.kew.mail.service.impl;
 17  
 
 18  
 import java.io.StringWriter;
 19  
 import java.util.Collection;
 20  
 import java.util.Date;
 21  
 import java.util.Map;
 22  
 
 23  
 import javax.xml.parsers.DocumentBuilder;
 24  
 import javax.xml.parsers.DocumentBuilderFactory;
 25  
 import javax.xml.parsers.ParserConfigurationException;
 26  
 import javax.xml.transform.Templates;
 27  
 import javax.xml.transform.TransformerConfigurationException;
 28  
 import javax.xml.transform.TransformerException;
 29  
 import javax.xml.transform.TransformerFactory;
 30  
 import javax.xml.transform.dom.DOMSource;
 31  
 import javax.xml.transform.stream.StreamResult;
 32  
 import javax.xml.transform.stream.StreamSource;
 33  
 
 34  
 import org.apache.commons.lang.StringUtils;
 35  
 import org.apache.log4j.Logger;
 36  
 import org.kuali.rice.core.api.style.StyleService;
 37  
 import org.kuali.rice.core.api.util.RiceConstants;
 38  
 import org.kuali.rice.core.api.util.xml.XmlHelper;
 39  
 import org.kuali.rice.core.api.util.xml.XmlJotter;
 40  
 import org.kuali.rice.core.mail.EmailContent;
 41  
 import org.kuali.rice.kew.api.WorkflowRuntimeException;
 42  
 import org.kuali.rice.kew.api.action.ActionItem;
 43  
 import org.kuali.rice.kew.api.util.CodeTranslator;
 44  
 import org.kuali.rice.kew.doctype.bo.DocumentType;
 45  
 import org.kuali.rice.kew.feedback.web.FeedbackForm;
 46  
 import org.kuali.rice.kew.mail.CustomEmailAttribute;
 47  
 import org.kuali.rice.kew.mail.EmailStyleHelper;
 48  
 import org.kuali.rice.kew.routeheader.DocumentRouteHeaderValue;
 49  
 import org.kuali.rice.kew.routeheader.service.RouteHeaderService;
 50  
 import org.kuali.rice.kew.service.KEWServiceLocator;
 51  
 import org.kuali.rice.kew.user.UserUtils;
 52  
 import org.kuali.rice.kew.api.KewApiConstants;
 53  
 import org.kuali.rice.kim.api.identity.Person;
 54  
 import org.kuali.rice.kim.api.identity.principal.Principal;
 55  
 import org.kuali.rice.kim.api.services.KimApiServiceLocator;
 56  
 import org.kuali.rice.krad.util.GlobalVariables;
 57  
 import org.springframework.core.io.DefaultResourceLoader;
 58  
 import org.w3c.dom.Document;
 59  
 import org.w3c.dom.Element;
 60  
 import org.w3c.dom.Node;
 61  
 
 62  
 
 63  
 
 64  
 /**
 65  
  * EmailContentService that serves EmailContent customizable via XSLT style sheets
 66  
  * The global email style name is: kew.email.style
 67  
  * If this style is not found, the resource 'defaultEmailStyle.xsl' will be retrieved
 68  
  * relative to this class.
 69  
  * @author Kuali Rice Team (rice.collab@kuali.org)
 70  
  */
 71  0
 public class StyleableEmailContentServiceImpl extends BaseEmailContentServiceImpl {
 72  0
     private static final Logger LOG = Logger.getLogger(StyleableEmailContentServiceImpl.class);
 73  
 
 74  0
     protected final String DEFAULT_EMAIL_STYLESHEET_RESOURCE_LOC = "defaultEmailStyle.xsl";
 75  
 
 76  
     protected StyleService styleService;
 77  0
     protected EmailStyleHelper styleHelper = new EmailStyleHelper();
 78  0
     protected String globalEmailStyleSheet = KewApiConstants.EMAIL_STYLESHEET_NAME;
 79  
 
 80  
     protected RouteHeaderService routeHeaderService;
 81  
 
 82  
     public void setStyleService(StyleService styleService) {
 83  0
         this.styleService = styleService;
 84  0
     }
 85  
 
 86  
     public void setGlobalEmailStyleSheet(String globalEmailStyleSheet) {
 87  0
         this.globalEmailStyleSheet = globalEmailStyleSheet;
 88  0
     }
 89  
 
 90  
     protected static DocumentBuilder getDocumentBuilder(boolean coalesce) {
 91  
         try {
 92  0
             DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
 93  0
             dbf.setCoalescing(coalesce);
 94  0
             return dbf.newDocumentBuilder();
 95  0
         } catch (ParserConfigurationException e) {
 96  0
             String message = "Error constructing document builder";
 97  0
             LOG.error(message, e);
 98  0
             throw new WorkflowRuntimeException(message, e);
 99  
         }
 100  
     }
 101  
 
 102  
     protected static void addObjectXML(Document doc, Object o, Node node, String name) throws Exception {
 103  0
         Element element = XmlHelper.propertiesToXml(doc, o, name);
 104  
 
 105  0
         if (LOG.isDebugEnabled()) {
 106  0
             LOG.debug(XmlJotter.jotNode(element));
 107  
         }
 108  
 
 109  0
         if (node == null) {
 110  0
             node = doc;
 111  
         }
 112  
 
 113  0
         node.appendChild(element);
 114  0
     }
 115  
 
 116  
     protected static void addTextElement(Document doc, Element baseElement, String elementName, Object elementData) {
 117  0
         Element element = doc.createElement(elementName);
 118  0
         String dataValue = "";
 119  0
         if (elementData != null) {
 120  0
                 dataValue = elementData.toString();
 121  
         }
 122  0
         element.appendChild(doc.createTextNode(dataValue));
 123  0
         baseElement.appendChild(element);
 124  0
     }
 125  
 
 126  
     protected static void addCDataElement(Document doc, Element baseElement, String elementName, Object elementData) {
 127  0
         Element element = doc.createElement(elementName);
 128  0
         String dataValue = "";
 129  0
         if (elementData != null) {
 130  0
             dataValue = elementData.toString();
 131  
         }
 132  0
         element.appendChild(doc.createCDATASection(dataValue));
 133  0
         baseElement.appendChild(element);
 134  0
     }
 135  
 
 136  
     protected static void addTimestampElement(Document doc, Element baseElement, String elementName, Date elementData) {
 137  0
         addTextElement(doc, baseElement, elementName, RiceConstants.getDefaultDateFormat().format(elementData));
 138  0
     }
 139  
 
 140  
     protected static void addDelegatorElement(Document doc, Element baseElement, ActionItem actionItem) {
 141  0
         Element delegatorElement = doc.createElement("delegator");
 142  0
         if ( (actionItem.getDelegatorPrincipalId() != null) && (actionItem.getDelegatorPrincipalId() != null) ) {
 143  
             // add empty delegator element
 144  0
             baseElement.appendChild(delegatorElement);
 145  0
             return;
 146  
         }
 147  0
         String delegatorType = "";
 148  0
         String delegatorId = "";
 149  0
         String delegatorDisplayValue = "";
 150  0
         if (actionItem.getDelegatorPrincipalId() != null) {
 151  0
             delegatorType = "user";
 152  0
             delegatorId = actionItem.getDelegatorPrincipalId();
 153  0
             Principal delegator = KimApiServiceLocator.getIdentityService().getPrincipal(delegatorId);
 154  
             
 155  0
             if (delegator == null) {
 156  0
                     LOG.error("Cannot find user for id " + delegatorId);
 157  0
                     delegatorDisplayValue = "USER NOT FOUND";
 158  
             } else {
 159  0
                     delegatorDisplayValue = UserUtils.getTransposedName(GlobalVariables.getUserSession(), delegator);
 160  
             }
 161  0
         } else if (actionItem.getDelegatorPrincipalId() != null) {
 162  0
             delegatorType = "workgroup";
 163  0
             delegatorId = actionItem.getDelegatorGroupId().toString();
 164  0
             delegatorDisplayValue = KimApiServiceLocator.getGroupService().getGroup(actionItem.getDelegatorGroupId()).getName();
 165  
         }
 166  0
         delegatorElement.setAttribute("type", delegatorType);
 167  
         // add the id element
 168  0
         Element idElement = doc.createElement("id");
 169  0
         idElement.appendChild(doc.createTextNode(delegatorId));
 170  0
         delegatorElement.appendChild(idElement);
 171  
         // add the display value element
 172  0
         Element displayValElement = doc.createElement("displayValue");
 173  0
         displayValElement.appendChild(doc.createTextNode(delegatorDisplayValue));
 174  0
         delegatorElement.appendChild(displayValElement);
 175  0
         baseElement.appendChild(delegatorElement);
 176  0
     }
 177  
 
 178  
     protected static void addWorkgroupRequestElement(Document doc, Element baseElement, ActionItem actionItem) {
 179  0
         Element workgroupElement = doc.createElement("workgroupRequest");
 180  0
         if (actionItem.getGroupId() != null) {
 181  
             // add the id element
 182  0
             Element idElement = doc.createElement("id");
 183  0
             idElement.appendChild(doc.createTextNode(actionItem.getGroupId()));
 184  0
             workgroupElement.appendChild(idElement);
 185  
             // add the display value element
 186  0
             Element displayValElement = doc.createElement("displayValue");
 187  0
             displayValElement.appendChild(doc.createTextNode(actionItem.getGroupId()));
 188  0
             workgroupElement.appendChild(displayValElement);
 189  
         }
 190  0
         baseElement.appendChild(workgroupElement);
 191  0
     }
 192  
 
 193  
     /**
 194  
      * This method is used to add the given {@link ActionItem} to the given {@link org.w3c.dom.Document} in a summarized
 195  
      * form for use in weekly or daily type reminder e-mails.
 196  
      *
 197  
      * @param doc - Document to have the ActionItem added to
 198  
      * @param actionItem - the action item being added
 199  
      * @param user - the current user
 200  
      * @param node - the node object to add the actionItem XML to (defaults to the doc variable if null is passed in)
 201  
      * @throws Exception
 202  
      */
 203  
     protected void addSummarizedActionItem(Document doc, ActionItem actionItem, Person user, Node node, DocumentRouteHeaderValue routeHeader) throws Exception {
 204  0
         if (node == null) {
 205  0
             node = doc;
 206  
         }
 207  
 
 208  0
         Element root = doc.createElement("summarizedActionItem");
 209  
 
 210  
         // add in all items from action list as preliminary default dataset
 211  0
         addTextElement(doc, root, "documentId", actionItem.getDocumentId());
 212  0
         addTextElement(doc, root, "docName", actionItem.getDocName());
 213  0
         addCDataElement(doc, root, "docLabel", actionItem.getDocLabel());
 214  0
         addCDataElement(doc, root, "docTitle", actionItem.getDocTitle());
 215  
         //DocumentRouteHeaderValue routeHeader = getRouteHeader(actionItem);
 216  0
         addTextElement(doc, root, "docRouteStatus", routeHeader.getDocRouteStatus());
 217  0
         addCDataElement(doc, root, "routeStatusLabel", routeHeader.getRouteStatusLabel());
 218  0
         addTextElement(doc, root, "actionRequestCd", actionItem.getActionRequestCd());
 219  0
         addTextElement(doc, root, "actionRequestLabel", CodeTranslator.getActionRequestLabel(
 220  
                 actionItem.getActionRequestCd()));
 221  0
         addDelegatorElement(doc, root, actionItem);
 222  0
         addTimestampElement(doc, root, "createDate", routeHeader.getCreateDate());
 223  0
         addWorkgroupRequestElement(doc, root, actionItem);
 224  0
         if (actionItem.getDateTimeAssigned() != null)
 225  0
             addTimestampElement(doc, root, "dateAssigned", actionItem.getDateTimeAssigned().toDate());
 226  
 
 227  0
         node.appendChild(root);
 228  0
     }
 229  
 
 230  
     public DocumentRouteHeaderValue getRouteHeader(ActionItem actionItem) {
 231  0
             if (routeHeaderService == null) {
 232  0
                     routeHeaderService = KEWServiceLocator.getRouteHeaderService();
 233  
             }
 234  0
         return routeHeaderService.getRouteHeader(actionItem.getDocumentId());
 235  
     }
 236  
 
 237  
     protected Map<String,DocumentRouteHeaderValue> getRouteHeaders(Collection<ActionItem> actionItems) {
 238  0
             if (routeHeaderService == null) {
 239  0
                     routeHeaderService = KEWServiceLocator.getRouteHeaderService();
 240  
             }
 241  0
             return routeHeaderService.getRouteHeadersForActionItems(actionItems);
 242  
     }
 243  
     
 244  
     protected static String transform(Templates style, Document doc) {
 245  0
         StringWriter writer = new StringWriter();
 246  0
         StreamResult result = new StreamResult(writer);
 247  
 
 248  
         try {
 249  0
             style.newTransformer().transform(new DOMSource(doc), result);
 250  0
             return writer.toString();
 251  0
         } catch (TransformerException te) {
 252  0
             String message = "Error transforming DOM";
 253  0
             LOG.error(message, te);
 254  0
             throw new WorkflowRuntimeException(message, te);
 255  
         }
 256  
     }
 257  
 
 258  
     /**
 259  
      * This method retrieves the style from the system using the given name. If none is found the default style xsl file
 260  
      * defined by {@link #DEFAULT_EMAIL_STYLESHEET_RESOURCE_LOC} is used.
 261  
      *
 262  
      * @param styleName
 263  
      * @return a valid {@link javax.xml.transform.Templates} using either the given styleName or the default xsl style file
 264  
      */
 265  
     protected Templates getStyle(String styleName) {
 266  0
         Templates style = null;
 267  
         try {
 268  0
             style = styleService.getStyleAsTranslet(styleName);
 269  0
         } catch (TransformerConfigurationException tce) {
 270  0
             String message = "Error obtaining style '" + styleName + "', using default";
 271  0
             LOG.error(message, tce);
 272  
             // throw new WorkflowRuntimeException("Error obtaining style '" + styleName + "'", tce);
 273  0
         }
 274  
 
 275  0
         if (style == null) {
 276  0
             LOG.warn("Could not find specified style, " + styleName + ", using default");
 277  
             try {
 278  
 
 279  0
                 style = TransformerFactory.newInstance().newTemplates(new StreamSource(new DefaultResourceLoader().getResource("classpath:org/kuali/rice/kew/mail/" + DEFAULT_EMAIL_STYLESHEET_RESOURCE_LOC).getInputStream()));
 280  0
             } catch (Exception tce) {
 281  0
                 String message = "Error obtaining default style from resource: " + DEFAULT_EMAIL_STYLESHEET_RESOURCE_LOC;
 282  0
                 LOG.error(message, tce);
 283  0
                 throw new WorkflowRuntimeException("Error obtaining style '" + styleName + "'", tce);
 284  0
             }
 285  
         }
 286  0
         return style;
 287  
     }
 288  
 
 289  
     protected EmailContent generateEmailContent(String styleName, Document doc) {
 290  0
         Templates style = getStyle(styleName);
 291  0
         return styleHelper.generateEmailContent(style, doc);
 292  
     }
 293  
 
 294  
     protected EmailContent generateReminderForActionItems(Person user, Collection<ActionItem> actionItems, String name, String style) {
 295  0
         DocumentBuilder db = getDocumentBuilder(false);
 296  0
         Document doc = db.newDocument();
 297  0
         Element element = doc.createElement(name);
 298  0
         Map<String,DocumentRouteHeaderValue> routeHeaders = getRouteHeaders(actionItems);
 299  
         
 300  0
         setStandardAttributes(element);
 301  0
         doc.appendChild(element);
 302  
 
 303  
         try {
 304  0
             addObjectXML(doc, user, element, "user");
 305  0
             for (ActionItem actionItem: actionItems) {
 306  
                 try {
 307  0
                     addSummarizedActionItem(doc, actionItem, user, element, routeHeaders.get(actionItem.getDocumentId()));
 308  0
                 } catch (Exception e) {
 309  0
                     String message = "Error generating XML for action item: " + actionItem;
 310  0
                     LOG.error(message, e);
 311  0
                     throw new WorkflowRuntimeException(e);
 312  0
                 }
 313  
             }
 314  
 
 315  0
         } catch (Exception e) {
 316  0
             String message = "Error generating XML for action items: " + actionItems;
 317  0
             LOG.error(message, e);
 318  0
             throw new WorkflowRuntimeException(e);
 319  0
         }
 320  
 
 321  0
         return generateEmailContent(style, doc);
 322  
     }
 323  
 
 324  
     protected void setStandardAttributes(Element e) {
 325  0
         e.setAttribute("env", getDeploymentEnvironment());
 326  0
         e.setAttribute("applicationEmailAddress", getApplicationEmailAddress());
 327  0
         e.setAttribute("actionListUrl", getActionListUrl());
 328  0
         e.setAttribute("preferencesUrl", getPreferencesUrl());
 329  0
     }
 330  
 
 331  
     /**
 332  
      * This method generates an {@link EmailContent} object using the given parameters.  Part of this operation includes
 333  
      * serializing the given {@link ActionItem} to XML. The following objects and methods are included in the serialization:
 334  
      *
 335  
      * <ul>
 336  
      * <li>{@link Person}</li>
 337  
      * <li>{@link Person#getPrincipalName()}</li>
 338  
      * <li>{@link DocumentRouteHeaderValue}</li>
 339  
      * <li>{@link DocumentRouteHeaderValue#getInitiatorUser()}</li>
 340  
      * <li>{@link DocumentRouteHeaderValue#getDocumentType()}</li>
 341  
      * <li>{@link Person}</li>
 342  
      * </ul>
 343  
      *
 344  
      * @param user - the current user
 345  
      * @param actionItem - the action item being added
 346  
      * @param documentType - the document type that the custom email style sheet will come from
 347  
      * @param node - the node object to add the actionItem XML to (defaults to the doc variable if null is passed in)
 348  
      * @throws Exception
 349  
      */
 350  
     @Override
 351  
         public EmailContent generateImmediateReminder(Person user, ActionItem actionItem, DocumentType documentType) {
 352  
             
 353  0
             LOG.info("Starting generation of immediate email reminder...");
 354  0
             LOG.info("Action Id: " + actionItem.getId() +
 355  
                              ";  ActionRequestId: " + actionItem.getActionRequestId() + 
 356  
                              ";  Action Item Principal Id: " + actionItem.getPrincipalId());
 357  0
             LOG.info("User Principal Id: " + user.getPrincipalId());
 358  
         // change style name based on documentType when configurable email style on document is implemented...
 359  0
         String styleSheet = documentType.getCustomEmailStylesheet();
 360  0
         LOG.debug(documentType.getName() + " style: " + styleSheet);
 361  0
         if (styleSheet == null) {
 362  0
             styleSheet = globalEmailStyleSheet;
 363  
         }
 364  
 
 365  0
         LOG.info("generateImmediateReminder using style sheet: "+ styleSheet + " for Document Type " + documentType.getName());
 366  
 //        return generateReminderForActionItems(user, actionItems, "immediateReminder", styleSheet);
 367  0
         DocumentBuilder db = getDocumentBuilder(false);
 368  0
         Document doc = db.newDocument();
 369  0
         Element element = doc.createElement("immediateReminder");
 370  0
         setStandardAttributes(element);
 371  0
         doc.appendChild(element);
 372  
 
 373  
         try {
 374  0
             addObjectXML(doc, user, element, "user");
 375  
 //            addActionItem(doc, actionItem, user, node);
 376  0
             Node node = element;
 377  0
             if (node == null) {
 378  0
                 node = doc;
 379  
             }
 380  
 
 381  0
             Element root = doc.createElement("actionItem");
 382  
             // append the custom body and subject if they exist
 383  
             try {
 384  0
                 CustomEmailAttribute customEmailAttribute = getCustomEmailAttribute(user, actionItem);
 385  0
                 if (customEmailAttribute != null) {
 386  0
                     String customBody = customEmailAttribute.getCustomEmailBody();
 387  0
                     if (!org.apache.commons.lang.StringUtils.isEmpty(customBody)) {
 388  0
                         Element bodyElement = doc.createElement("customBody");
 389  0
                         bodyElement.appendChild(doc.createTextNode(customBody));
 390  0
                         root.appendChild(bodyElement);
 391  
                     }
 392  0
                     String customEmailSubject = customEmailAttribute.getCustomEmailSubject();
 393  0
                     if (!org.apache.commons.lang.StringUtils.isEmpty(customEmailSubject)) {
 394  0
                         Element subjectElement = doc.createElement("customSubject");
 395  0
                         subjectElement.appendChild(doc.createTextNode(customEmailSubject));
 396  0
                         root.appendChild(subjectElement);
 397  
                     }
 398  
                 }
 399  0
             } catch (Exception e) {
 400  0
                 LOG.error("Error when checking for custom email body and subject.", e);
 401  0
             }
 402  0
             Person person = KimApiServiceLocator.getPersonService().getPerson(actionItem.getPrincipalId());
 403  0
             DocumentRouteHeaderValue header = getRouteHeader(actionItem);
 404  
             // keep adding stuff until we have all the xml we need to formulate the message :/
 405  0
             addObjectXML(doc, actionItem, root, "actionItem");
 406  0
             addObjectXML(doc, person, root, "actionItemPerson");
 407  0
             addTextElement(doc, root, "actionItemPrincipalId", person.getPrincipalId());
 408  0
             addTextElement(doc, root, "actionItemPrincipalName", person.getPrincipalName());
 409  0
             addDocumentHeaderXML(doc, header, root, "doc");
 410  0
             addObjectXML(doc, header.getInitiatorPrincipal(), root, "docInitiator");
 411  0
             addTextElement(doc, root, "docInitiatorDisplayName", header.getInitiatorDisplayName());
 412  0
             addObjectXML(doc, header.getDocumentType(), root, "documentType");
 413  
 
 414  0
             node.appendChild(root);
 415  0
         } catch (Exception e) {
 416  0
             String message = "Error generating immediate reminder XML for action item: " + actionItem;
 417  0
             LOG.error(message, e);
 418  0
             throw new WorkflowRuntimeException(e);
 419  0
         }
 420  0
         LOG.info("Leaving generation of immeidate email reminder...");
 421  
             /**
 422  
              * End IU customization
 423  
              */
 424  0
         return generateEmailContent(styleSheet, doc);
 425  
     }
 426  
     
 427  
     /**
 428  
      * This method handles converting the DocumentRouteHeaderValue into an XML representation.  The reason we can't just use
 429  
      * propertiesToXml like we have elsewhere is because the doc header has a String attached to it that has the XML document
 430  
      * content in it.  The default serialization of this will serialize this as a String so we will end up with escaped XML
 431  
      * in our output which we won't be able to process with the email stylesheet.  So we need to read the xml content from
 432  
      * the document and parse it into a DOM object so it can be appended to our output.
 433  
      */
 434  
     protected void addDocumentHeaderXML(Document document, DocumentRouteHeaderValue documentHeader, Node node, String elementName) throws Exception {
 435  0
             Element element = XmlHelper.propertiesToXml(document, documentHeader, elementName);
 436  
             // now we need to "fix" the xml document content because it's going to be in there as escaped XML
 437  0
             Element docContentElement = (Element)element.getElementsByTagName("docContent").item(0);
 438  0
             String documentContent = docContentElement.getTextContent();
 439  
             
 440  0
             if (!StringUtils.isBlank(documentContent) && documentContent.startsWith("<")) {
 441  0
                     Document documentContentXML = XmlHelper.readXml(documentContent);
 442  0
                     Element documentContentElement = documentContentXML.getDocumentElement();
 443  0
                     documentContentElement = (Element)document.importNode(documentContentElement, true);
 444  
             
 445  
                     // remove the old, bad text content
 446  0
                     docContentElement.removeChild(docContentElement.getFirstChild());
 447  
             
 448  
                     // replace with actual XML
 449  0
                     docContentElement.appendChild(documentContentElement);
 450  0
             } else {
 451  
                     // in this case it means that the XML is encrypted, unfortunately, we have no way to decrypt it since
 452  
                     // the key is stored in the client application.  We will just include the doc content since none of our
 453  
                     // current IU clients will be using this feature right away
 454  
 
 455  
                     // remove the old, bad text content
 456  0
                     docContentElement.removeChild(docContentElement.getFirstChild());
 457  
             }
 458  
             
 459  0
             if (LOG.isDebugEnabled()) {
 460  0
             LOG.debug(XmlJotter.jotNode(element));
 461  
         }
 462  
 
 463  0
         node.appendChild(element);
 464  0
     }
 465  
 
 466  
     @Override
 467  
         public EmailContent generateWeeklyReminder(Person user, Collection<ActionItem> actionItems) {
 468  0
         return generateReminderForActionItems(user, actionItems, "weeklyReminder", globalEmailStyleSheet);
 469  
     }
 470  
 
 471  
     @Override
 472  
         public EmailContent generateDailyReminder(Person user, Collection<ActionItem> actionItems) {
 473  0
         return generateReminderForActionItems(user, actionItems, "dailyReminder", globalEmailStyleSheet);
 474  
     }
 475  
 
 476  
     @Override
 477  
         public EmailContent generateFeedback(FeedbackForm form) {
 478  0
         DocumentBuilder db = getDocumentBuilder(true);
 479  0
         Document doc = db.newDocument();
 480  0
         String styleSheet = globalEmailStyleSheet;
 481  
 
 482  
         // if the doc type is specified, see if that doc has a custom email stylesheet and use it
 483  
         // NOTE: do we need to do this for feedback? presumably feedback will be going back to admins
 484  
         /*String docTypeName = form.getDocumentType();
 485  
         if (!StringUtils.isBlank(docTypeName)) {
 486  
             DocumentType docType = KEWServiceLocator.getDocumentTypeService().findByName(docTypeName);
 487  
             if (docType == null) {
 488  
                 LOG.error("User specified document type '" + docTypeName + "' in feedback form, but the document type was not found in the system");
 489  
             } else {
 490  
                 if (docType.getCustomEmailStylesheet() != null) {
 491  
                     styleSheet = docType.getCustomEmailStylesheet();
 492  
                 }
 493  
             }
 494  
         }*/
 495  0
         LOG.info("form: " + form.getDocumentId());
 496  
         try {
 497  0
             addObjectXML(doc, form, null, "feedback");
 498  0
         } catch (Exception e) {
 499  0
             String message = "Error generating XML for feedback form: " + form;
 500  0
             LOG.error(message, e);
 501  0
             throw new WorkflowRuntimeException(message, e);
 502  0
         }
 503  0
         setStandardAttributes(doc.getDocumentElement());
 504  
 
 505  0
         return generateEmailContent(styleSheet, doc);
 506  
     }
 507  
 }