Coverage Report - org.kuali.rice.kew.edl.service.impl.EDocLiteServiceImpl
 
Classes in this File Line Coverage Branch Coverage Complexity
EDocLiteServiceImpl
0%
0/134
0%
0/46
2.25
 
 1  
 /*
 2  
  * Copyright 2005-2008 The Kuali Foundation
 3  
  *
 4  
  *
 5  
  * Licensed under the Educational Community License, Version 2.0 (the "License");
 6  
  * you may not use this file except in compliance with the License.
 7  
  * You may obtain a copy of the License at
 8  
  *
 9  
  * http://www.opensource.org/licenses/ecl2.php
 10  
  *
 11  
  * Unless required by applicable law or agreed to in writing, software
 12  
  * distributed under the License is distributed on an "AS IS" BASIS,
 13  
  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 14  
  * See the License for the specific language governing permissions and
 15  
  * limitations under the License.
 16  
  */
 17  
 package org.kuali.rice.kew.edl.service.impl;
 18  
 
 19  
 import java.io.InputStream;
 20  
 import java.io.StringReader;
 21  
 import java.util.ArrayList;
 22  
 import java.util.Collection;
 23  
 import java.util.Iterator;
 24  
 import java.util.List;
 25  
 
 26  
 import javax.xml.parsers.DocumentBuilderFactory;
 27  
 import javax.xml.transform.Templates;
 28  
 import javax.xml.transform.TransformerConfigurationException;
 29  
 import javax.xml.transform.TransformerException;
 30  
 import javax.xml.xpath.XPath;
 31  
 import javax.xml.xpath.XPathConstants;
 32  
 import javax.xml.xpath.XPathExpressionException;
 33  
 import javax.xml.xpath.XPathFactory;
 34  
 
 35  
 import org.apache.log4j.Logger;
 36  
 import org.kuali.rice.core.config.ConfigContext;
 37  
 import org.kuali.rice.kew.edl.EDLController;
 38  
 import org.kuali.rice.kew.edl.EDLControllerFactory;
 39  
 import org.kuali.rice.kew.edl.EDLGlobalConfig;
 40  
 import org.kuali.rice.kew.edl.EDLGlobalConfigFactory;
 41  
 import org.kuali.rice.kew.edl.EDLXmlUtils;
 42  
 import org.kuali.rice.kew.edl.bo.EDocLiteAssociation;
 43  
 import org.kuali.rice.kew.edl.bo.EDocLiteDefinition;
 44  
 import org.kuali.rice.kew.edl.bo.EDocLiteStyle;
 45  
 import org.kuali.rice.kew.edl.dao.EDocLiteDAO;
 46  
 import org.kuali.rice.kew.edl.service.EDocLiteService;
 47  
 import org.kuali.rice.kew.edl.service.StyleService;
 48  
 import org.kuali.rice.kew.exception.WorkflowRuntimeException;
 49  
 import org.kuali.rice.kew.exception.WorkflowServiceErrorException;
 50  
 import org.kuali.rice.kew.exception.WorkflowServiceErrorImpl;
 51  
 import org.kuali.rice.kew.export.ExportDataSet;
 52  
 import org.kuali.rice.kew.routeheader.DocumentRouteHeaderValue;
 53  
 import org.kuali.rice.kew.rule.bo.RuleAttribute;
 54  
 import org.kuali.rice.kew.service.KEWServiceLocator;
 55  
 import org.kuali.rice.kew.util.KEWConstants;
 56  
 import org.kuali.rice.kew.util.XmlHelper;
 57  
 import org.kuali.rice.kew.xml.EDocLiteXmlParser;
 58  
 import org.kuali.rice.kew.xml.export.EDocLiteXmlExporter;
 59  
 import org.w3c.dom.Document;
 60  
 import org.w3c.dom.Element;
 61  
 import org.w3c.dom.Node;
 62  
 import org.w3c.dom.NodeList;
 63  
 import org.xml.sax.InputSource;
 64  
 
 65  
 
 66  
 /**
 67  
  * DAO-based EDocLiteService implementation
 68  
  *
 69  
  * @author Kuali Rice Team (rice.collab@kuali.org)
 70  
  */
 71  0
 public class EDocLiteServiceImpl implements EDocLiteService {
 72  0
     private static final Logger LOG = Logger.getLogger(EDocLiteServiceImpl.class);
 73  
 
 74  
         private EDLGlobalConfig edlGlobalConfig;
 75  
     /**
 76  
      * The Spring-wired DAO bean
 77  
      */
 78  
     private EDocLiteDAO dao;
 79  
     /**
 80  
      * Spring wired StyleService bean
 81  
      */
 82  
     private StyleService styleService;
 83  
 
 84  
     // ---- Spring DAO setters
 85  
 
 86  
     public void setEDocLiteDAO(EDocLiteDAO dao) {
 87  0
         this.dao = dao;
 88  0
     }
 89  
 
 90  
     public void setStyleService(StyleService styleService) {
 91  0
         this.styleService = styleService;
 92  0
     }
 93  
 
 94  
         public EDLController getEDLController(String edlName) {
 95  0
                 EDocLiteAssociation edlAssociation = this.dao.getEDocLiteAssociation(edlName);
 96  0
         if (edlAssociation == null) {
 97  0
             throw new WorkflowRuntimeException("No document association active for EDL: " + edlName);
 98  
         }
 99  0
                 if (edlGlobalConfig == null) {
 100  0
                         initEDLGlobalConfig();
 101  
                 }
 102  0
                 return EDLControllerFactory.createEDLController(edlAssociation, edlGlobalConfig);
 103  
         }
 104  
 
 105  
         public EDLController getEDLController(Long documentId) {
 106  0
                 DocumentRouteHeaderValue document = KEWServiceLocator.getRouteHeaderService().getRouteHeader(documentId);
 107  0
                 String edlName = document.getAppDocId();//components working with workflow docs will need to know this, perhaps through a document utils.
 108  0
                 if (edlName == null) {
 109  0
                         edlName = document.getDocumentType().getName();
 110  
                 }
 111  0
                 EDocLiteAssociation edlAssociation = this.dao.getEDocLiteAssociation(edlName);
 112  0
         if (edlAssociation == null) {
 113  0
             throw new WorkflowRuntimeException("No document association active for EDL: " + edlName);
 114  
         }
 115  0
                 if (edlGlobalConfig == null) {
 116  0
                         initEDLGlobalConfig();
 117  
                 }
 118  0
                 return EDLControllerFactory.createEDLController(edlAssociation, edlGlobalConfig, document);
 119  
         }
 120  
 
 121  
         public void initEDLGlobalConfig() {
 122  
                 try {
 123  0
                         this.edlGlobalConfig = EDLGlobalConfigFactory.createEDLGlobalConfig(ConfigContext.getCurrentContextConfig().getEDLConfigLocation());
 124  0
                 } catch (Exception e) {
 125  0
                         throw new WorkflowRuntimeException(e);
 126  0
                 }
 127  0
         }
 128  
 
 129  
         public Document getDefinitionXml(EDocLiteAssociation edlAssociation) {
 130  
                 try {
 131  0
                         Document def = DocumentBuilderFactory.newInstance().newDocumentBuilder().parse(new InputSource(
 132  
                         new StringReader(getEDocLiteDefinition(edlAssociation.getDefinition()).getXmlContent())));
 133  0
                         return def;
 134  0
                 } catch (Exception e) {
 135  0
                         throw new WorkflowRuntimeException("Caught exception parsing EDL definition " + edlAssociation.getDefinition(), e);
 136  
                 }
 137  
         }
 138  
 
 139  
         private static WorkflowServiceErrorException generateException(String error, Throwable cause) {
 140  0
         WorkflowServiceErrorException wsee = new WorkflowServiceErrorException(error, new WorkflowServiceErrorImpl(error, KEWConstants.XML_FILE_PARSE_ERROR));
 141  0
         if (cause != null) {
 142  0
             wsee.initCause(cause);
 143  
         }
 144  0
         return wsee;
 145  
     }
 146  
 
 147  
     private static WorkflowServiceErrorException generateMissingAttribException(String element, String attrib) {
 148  0
         return generateException("EDocLite '" + element + "' element must contain a '" + attrib + "' attribute", null);
 149  
     }
 150  
 
 151  
     private static WorkflowServiceErrorException generateMissingChildException(String element, String child) {
 152  0
         return generateException("EDocLite '" + element + "' element must contain a '" + child + "' child element", null);
 153  
     }
 154  
 
 155  
     private static WorkflowServiceErrorException generateSerializationException(String element, TransformerException cause) {
 156  0
         return generateException("Error serializing EDocLite '" + element + "' element", cause);
 157  
     }
 158  
 
 159  
     /**
 160  
      * Parses an arbitrary XML stream
 161  
      *
 162  
      * @param stream
 163  
      *            stream containing XML doc content
 164  
      * @return parsed Document object
 165  
      */
 166  
     private static Document parse(InputStream stream) {
 167  
         try {
 168  0
             return DocumentBuilderFactory.newInstance().newDocumentBuilder().parse(stream);
 169  0
         } catch (Exception e) {
 170  0
             WorkflowServiceErrorException wsee = new WorkflowServiceErrorException("Error parsing EDocLite XML file", new WorkflowServiceErrorImpl("Error parsing XML file.", KEWConstants.XML_FILE_PARSE_ERROR));
 171  0
             wsee.initCause(e);
 172  0
             throw wsee;
 173  
         }
 174  
     }
 175  
 
 176  
     /**
 177  
      * Parses an EDocLiteAssocation
 178  
      *
 179  
      * @param e
 180  
      *            element to parse
 181  
      * @return an EDocLiteAssocation
 182  
      */
 183  
     private static EDocLiteAssociation parseEDocLiteAssociation(Element e) {
 184  0
         String docType = EDLXmlUtils.getChildElementTextValue(e, "docType");
 185  0
         if (docType == null) {
 186  0
             throw generateMissingChildException("association", "docType");
 187  
         }
 188  0
         EDocLiteAssociation assoc = new EDocLiteAssociation();
 189  0
         assoc.setEdlName(docType);
 190  0
         assoc.setDefinition(EDLXmlUtils.getChildElementTextValue(e, "definition"));
 191  0
         assoc.setStyle(EDLXmlUtils.getChildElementTextValue(e, "style"));
 192  0
         assoc.setActiveInd(Boolean.valueOf(EDLXmlUtils.getChildElementTextValue(e, "active")));
 193  0
         return assoc;
 194  
     }
 195  
 
 196  
     /**
 197  
      * Parses an EDocLiteDefinition
 198  
      *
 199  
      * @param e
 200  
      *            element to parse
 201  
      * @return an EDocLiteDefinition
 202  
      */
 203  
     private static EDocLiteDefinition parseEDocLiteDefinition(Element e) {
 204  0
         EDocLiteDefinition def = new EDocLiteDefinition();
 205  0
         String name = e.getAttribute("name");
 206  0
         if (name == null || name.length() == 0) {
 207  0
             throw generateMissingAttribException(EDLXmlUtils.EDL_E, "name");
 208  
         }
 209  0
         def.setName(name);
 210  
 
 211  
         // do some validation to ensure that any attributes referenced actually exist
 212  
         // blow up if there is a problem
 213  
 
 214  0
         XPath xpath = XPathFactory.newInstance().newXPath();
 215  
         NodeList fields;
 216  
         try {
 217  0
             fields = (NodeList) xpath.evaluate("fieldDef", e, XPathConstants.NODESET);
 218  0
         } catch (XPathExpressionException xpee) {
 219  0
             throw new RuntimeException("Invalid EDocLiteDefinition", xpee);
 220  0
         }
 221  
 
 222  0
         if (fields != null) {
 223  0
             Collection invalidAttributes = new ArrayList(5);
 224  0
             for (int i = 0; i < fields.getLength(); i++) {
 225  0
                 Node node = (Node) fields.item(i);
 226  
                 // they should all be Element...
 227  0
                 if (node instanceof Element) {
 228  0
                     Element field = (Element) node;
 229  
                     // rely on XML validation to ensure this is present
 230  0
                     String fieldName = field.getAttribute("name");
 231  0
                     String attribute = field.getAttribute("attributeName");
 232  0
                     if (attribute != null && attribute.length() > 0) {
 233  0
                         RuleAttribute ruleAttrib = KEWServiceLocator.getRuleAttributeService().findByName(attribute);
 234  0
                         if (ruleAttrib == null) {
 235  0
                             LOG.error("Invalid attribute referenced in EDocLite definition: " + attribute);
 236  0
                             invalidAttributes.add("Attribute '" + attribute + "' referenced in field '" + fieldName + "' not found");
 237  
                         }
 238  
                     }
 239  
                 }
 240  
             }
 241  0
             if (invalidAttributes.size() > 0) {
 242  0
                 LOG.error("Invalid attributes referenced in EDocLite definition");
 243  0
                 StringBuffer message = new StringBuffer("EDocLite definition contains references to non-existent attributes;\n");
 244  0
                 Iterator it = invalidAttributes.iterator();
 245  0
                 while (it.hasNext()) {
 246  0
                     message.append(it.next());
 247  0
                     message.append("\n");
 248  
                 }
 249  0
                 throw new RuntimeException(message.toString());
 250  
             }
 251  
         }
 252  
 
 253  
         try {
 254  0
             def.setXmlContent(XmlHelper.writeNode(e, true));
 255  0
         } catch (TransformerException te) {
 256  0
             throw generateSerializationException(EDLXmlUtils.EDL_E, te);
 257  0
         }
 258  0
         return def;
 259  
     }
 260  
 
 261  
     // ---- helper methods
 262  
 
 263  
     public void saveEDocLiteStyle(EDocLiteStyle data) {
 264  0
         styleService.saveStyle(data);
 265  0
     }
 266  
 
 267  
     public void saveEDocLiteDefinition(EDocLiteDefinition data) {
 268  0
         EDocLiteDefinition existingData = getEDocLiteDefinition(data.getName());
 269  0
         if (existingData != null) {
 270  0
             existingData.setActiveInd(Boolean.FALSE);
 271  0
             dao.saveEDocLiteDefinition(existingData);
 272  
         }
 273  
         // if not specified (from xml), mark it as active
 274  0
         if (data.getActiveInd() == null) {
 275  0
             data.setActiveInd(Boolean.TRUE);
 276  
         }
 277  0
         dao.saveEDocLiteDefinition(data);
 278  0
         removeDefinitionFromCache(data.getName());
 279  0
     }
 280  
 
 281  
     public void saveEDocLiteAssociation(EDocLiteAssociation assoc) {
 282  0
         EDocLiteAssociation existingData = getEDocLiteAssociation(assoc.getEdlName());
 283  0
         if (existingData != null) {
 284  0
             existingData.setActiveInd(Boolean.FALSE);
 285  0
             dao.saveEDocLiteAssociation(existingData);
 286  
         }
 287  
         // if not specified (from xml), mark it as active
 288  0
         if (assoc.getActiveInd() == null) {
 289  0
             assoc.setActiveInd(Boolean.TRUE);
 290  
         }
 291  0
         dao.saveEDocLiteAssociation(assoc);
 292  0
     }
 293  
 
 294  
     // ---- EDocLiteService interface implementation
 295  
 
 296  
     public void saveEDocLiteStyle(InputStream xml) {
 297  0
         styleService.saveStyle(xml);
 298  0
     }
 299  
 
 300  
     public void saveEDocLiteDefinition(InputStream xml) {
 301  
         // convert xml to EDocLiteDefinition
 302  0
         EDocLiteDefinition data = parseEDocLiteDefinition(parse(xml).getDocumentElement());
 303  0
         saveEDocLiteDefinition(data);
 304  0
     }
 305  
 
 306  
     public void saveEDocLiteAssociation(InputStream xml) {
 307  
         // convert xml to EDocLiteAssociation
 308  0
         EDocLiteAssociation assoc = parseEDocLiteAssociation(parse(xml).getDocumentElement());
 309  0
         saveEDocLiteAssociation(assoc);
 310  0
     }
 311  
 
 312  
     public EDocLiteStyle getEDocLiteStyle(String styleName) {
 313  0
         return styleService.getStyle(styleName);
 314  
     }
 315  
 
 316  
     public EDocLiteDefinition getEDocLiteDefinition(String definitionName) {
 317  0
         return dao.getEDocLiteDefinition(definitionName);
 318  
     }
 319  
 
 320  
     public EDocLiteAssociation getEDocLiteAssociation(String docTypeName) {
 321  0
         return dao.getEDocLiteAssociation(docTypeName);
 322  
     }
 323  
 
 324  
     public List<String> getEDocLiteStyles() {
 325  0
         return styleService.getStyleNames();
 326  
     }
 327  
 
 328  
     public List getEDocLiteDefinitions() {
 329  0
         return dao.getEDocLiteDefinitions();
 330  
     }
 331  
 
 332  
     public List getEDocLiteAssociations() {
 333  0
         return dao.getEDocLiteAssociations();
 334  
     }
 335  
 
 336  
     public Templates getStyleAsTranslet(String name) throws TransformerConfigurationException {
 337  0
         if (name == null || "null".equals(name)) { //"name".equals(name) - from a null value in the lookupable
 338  0
             name = "Default";
 339  
         }
 340  
 
 341  0
         return styleService.getStyleAsTranslet(name);
 342  
     }
 343  
 
 344  
     public void removeStyleFromCache(String styleName) {
 345  0
         styleService.removeStyleFromCache(styleName);
 346  0
     }
 347  
 
 348  
     public void removeDefinitionFromCache(String defName) {
 349  0
         LOG.info("Removing definition " + defName + " from cache");
 350  0
         EDLControllerFactory.flushDefinitionFromConfigCache(defName);
 351  0
     }
 352  
 
 353  
     public List search(EDocLiteAssociation edocLite) {
 354  0
         return this.dao.search(edocLite);
 355  
     }
 356  
 
 357  
     public EDocLiteAssociation getEDocLiteAssociation(Long associationId) {
 358  0
         return dao.getEDocLiteAssociation(associationId);
 359  
     }
 360  
 
 361  
     // ---- XmlLoader interface implementation
 362  
 
 363  
     public void loadXml(InputStream inputStream, String principalId) {
 364  0
             EDocLiteXmlParser.loadXml(inputStream, principalId);
 365  0
     }
 366  
 
 367  
     // ---- XmlExporter interface implementation
 368  
         public org.jdom.Element export(ExportDataSet dataSet) {
 369  0
                 return new EDocLiteXmlExporter().export(dataSet);
 370  
         }
 371  
 
 372  
 }