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