Coverage Report - org.kuali.rice.kew.xml.EDocLiteXmlParser
 
Classes in this File Line Coverage Branch Coverage Complexity
EDocLiteXmlParser
0%
0/104
0%
0/48
5.333
 
 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.xml;
 18  
 
 19  
 import java.io.InputStream;
 20  
 import java.util.ArrayList;
 21  
 import java.util.Collection;
 22  
 import java.util.Iterator;
 23  
 
 24  
 import javax.xml.parsers.DocumentBuilder;
 25  
 import javax.xml.transform.TransformerException;
 26  
 import javax.xml.xpath.XPath;
 27  
 import javax.xml.xpath.XPathConstants;
 28  
 import javax.xml.xpath.XPathExpressionException;
 29  
 import javax.xml.xpath.XPathFactory;
 30  
 
 31  
 import org.apache.log4j.Logger;
 32  
 import org.kuali.rice.kew.edl.EDLXmlUtils;
 33  
 import org.kuali.rice.kew.edl.bo.EDocLiteAssociation;
 34  
 import org.kuali.rice.kew.edl.bo.EDocLiteDefinition;
 35  
 import org.kuali.rice.kew.edl.bo.EDocLiteStyle;
 36  
 import org.kuali.rice.kew.edl.service.EDocLiteService;
 37  
 import org.kuali.rice.kew.exception.WorkflowServiceErrorException;
 38  
 import org.kuali.rice.kew.exception.WorkflowServiceErrorImpl;
 39  
 import org.kuali.rice.kew.rule.bo.RuleAttribute;
 40  
 import org.kuali.rice.kew.service.KEWServiceLocator;
 41  
 import org.kuali.rice.kew.util.KEWConstants;
 42  
 import org.kuali.rice.kew.util.XmlHelper;
 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  
 
 48  
 
 49  
 /**
 50  
  * An XML parser which parses EDocLite definitions.
 51  
  *
 52  
  * @author Kuali Rice Team (rice.collab@kuali.org)
 53  
  */
 54  0
 public class EDocLiteXmlParser {
 55  
 
 56  0
         private static final Logger LOG = Logger.getLogger(EDocLiteXmlParser.class);
 57  
 
 58  
     public static void loadXml(InputStream inputStream, String principalId) {
 59  0
         DocumentBuilder db = EDLXmlUtils.getDocumentBuilder();
 60  0
         XPath xpath = XPathFactory.newInstance().newXPath();
 61  
         Document doc;
 62  
         // parse and save EDocLiteDefinition, EDocLiteStyle, or EDocLiteAssociation xml from to-be-determined XML format
 63  
         //try {
 64  
         try {
 65  0
             doc = db.parse(inputStream);
 66  0
         } catch (Exception e) {
 67  0
             throw generateException("Error parsing EDocLite XML file", e);
 68  0
         }
 69  
             /*try {
 70  
                 LOG.info(XmlHelper.writeNode(doc.getFirstChild(), true));
 71  
             } catch (TransformerException e) {
 72  
                 LOG.warn("Error displaying document");
 73  
             }*/
 74  
 
 75  
             NodeList edls;
 76  
             try {
 77  0
                 edls = (NodeList) xpath.evaluate("//edoclite", doc.getFirstChild(), XPathConstants.NODESET);
 78  0
             } catch (XPathExpressionException e) {
 79  0
                 throw generateException("Error evaluating XPath expression", e);
 80  0
             }
 81  
 
 82  0
             for (int i = 0; i < edls.getLength(); i++) {
 83  0
                 Node edl = edls.item(i);
 84  0
                 NodeList children = edl.getChildNodes();
 85  0
                 for (int j = 0; j < children.getLength(); j++) {
 86  0
                     Node node = children.item(j);
 87  
                     /*try {
 88  
                         LOG.info(XmlHelper.writeNode(node, true));
 89  
                     } catch (TransformerException te) {
 90  
                         LOG.warn("Error displaying node");
 91  
                     }*/
 92  0
                     if (node.getNodeType() == Node.ELEMENT_NODE) {
 93  0
                         Element e = (Element) node;
 94  0
                         if ("style".equals(node.getNodeName())) {
 95  0
                             LOG.debug("Digesting EDocLiteStyle: " + e.getAttribute("name"));
 96  0
                             EDocLiteStyle style = parseEDocLiteStyle(e);
 97  0
                             getEDLService().saveEDocLiteStyle(style);
 98  0
                         } else if ("edl".equals(node.getNodeName())) {
 99  0
                             LOG.debug("Digesting EDocLiteDefinition: " + e.getAttribute("name"));
 100  0
                             EDocLiteDefinition def = parseEDocLiteDefinition(e);
 101  0
                             getEDLService().saveEDocLiteDefinition(def);
 102  0
                         } else if ("association".equals(node.getNodeName())) {
 103  0
                             LOG.debug("Digesting EDocLiteAssociation: " + e.getAttribute("name"));
 104  0
                             EDocLiteAssociation assoc = parseEDocLiteAssociation(e);
 105  0
                             getEDLService().saveEDocLiteAssociation(assoc);
 106  
                         } else {
 107  
                             // LOG.debug("Unrecognized element '" + node.getNodeName() + "' in EDocLite XML doc");
 108  
                         }
 109  
                     }
 110  
                 }
 111  
             }
 112  
         //} catch (Exception e) {
 113  
         //    throw generateException("Error parsing EDocLite XML file", e);
 114  
         //}
 115  0
     }
 116  
 
 117  
     private static WorkflowServiceErrorException generateException(String error, Throwable cause) {
 118  0
         WorkflowServiceErrorException wsee = new WorkflowServiceErrorException(error, new WorkflowServiceErrorImpl(error, KEWConstants.XML_FILE_PARSE_ERROR));
 119  0
         if (cause != null) {
 120  0
             wsee.initCause(cause);
 121  
         }
 122  0
         return wsee;
 123  
     }
 124  
 
 125  
     /**
 126  
      * Parses an EDocLiteAssocation
 127  
      *
 128  
      * @param e
 129  
      *            element to parse
 130  
      * @return an EDocLiteAssocation
 131  
      */
 132  
     private static EDocLiteAssociation parseEDocLiteAssociation(Element e) {
 133  0
         String docType = EDLXmlUtils.getChildElementTextValue(e, "docType");
 134  0
         if (docType == null) {
 135  0
             throw generateMissingChildException("association", "docType");
 136  
         }
 137  0
         EDocLiteAssociation assoc = new EDocLiteAssociation();
 138  0
         assoc.setEdlName(docType);
 139  0
         assoc.setDefinition(EDLXmlUtils.getChildElementTextValue(e, "definition"));
 140  0
         assoc.setStyle(EDLXmlUtils.getChildElementTextValue(e, "style"));
 141  0
         assoc.setActiveInd(Boolean.valueOf(EDLXmlUtils.getChildElementTextValue(e, "active")));
 142  0
         return assoc;
 143  
     }
 144  
 
 145  
     /**
 146  
      * Parses an EDocLiteStyle
 147  
      *
 148  
      * @param e
 149  
      *            element to parse
 150  
      * @return an EDocLiteStyle
 151  
      */
 152  
     private static EDocLiteStyle parseEDocLiteStyle(Element e) {
 153  0
         String name = e.getAttribute("name");
 154  0
         if (name == null || name.length() == 0) {
 155  0
             throw generateMissingAttribException("style", "name");
 156  
         }
 157  0
         EDocLiteStyle style = new EDocLiteStyle();
 158  0
         style.setName(name);
 159  0
         Element stylesheet = null;
 160  0
         NodeList children = e.getChildNodes();
 161  0
         for (int i = 0; i < children.getLength(); i++) {
 162  0
             Node child = children.item(i);
 163  
             /*
 164  
              * LOG.debug("NodeName: " + child.getNodeName()); LOG.debug("LocalName: " + child.getLocalName()); LOG.debug("Prefix: " + child.getPrefix()); LOG.debug("NS URI: " + child.getNamespaceURI());
 165  
              */
 166  0
             if (child.getNodeType() == Node.ELEMENT_NODE && "xsl:stylesheet".equals(child.getNodeName())) {
 167  0
                 stylesheet = (Element) child;
 168  0
                 break;
 169  
             }
 170  
         }
 171  0
         if (stylesheet == null) {
 172  0
             throw generateMissingChildException("style", "xsl:stylesheet");
 173  
         }
 174  
         try {
 175  0
             style.setXmlContent(XmlHelper.writeNode(stylesheet, true));
 176  0
         } catch (TransformerException te) {
 177  0
             throw generateSerializationException("style", te);
 178  0
         }
 179  0
         return style;
 180  
     }
 181  
 
 182  
     /**
 183  
      * Parses an EDocLiteDefinition
 184  
      *
 185  
      * @param e
 186  
      *            element to parse
 187  
      * @return an EDocLiteDefinition
 188  
      */
 189  
     private static EDocLiteDefinition parseEDocLiteDefinition(Element e) {
 190  0
         EDocLiteDefinition def = new EDocLiteDefinition();
 191  0
         String name = e.getAttribute("name");
 192  0
         if (name == null || name.length() == 0) {
 193  0
             throw generateMissingAttribException(EDLXmlUtils.EDL_E, "name");
 194  
         }
 195  0
         def.setName(name);
 196  
 
 197  
         // do some validation to ensure that any attributes referenced actually exist
 198  
         // blow up if there is a problem
 199  
 
 200  0
         XPath xpath = XPathFactory.newInstance().newXPath();
 201  
         NodeList fields;
 202  
         try {
 203  0
             fields = (NodeList) xpath.evaluate("fieldDef", e, XPathConstants.NODESET);
 204  0
         } catch (XPathExpressionException xpee) {
 205  0
             throw new RuntimeException("Invalid EDocLiteDefinition", xpee);
 206  0
         }
 207  
 
 208  0
         if (fields != null) {
 209  0
             Collection invalidAttributes = new ArrayList(5);
 210  0
             for (int i = 0; i < fields.getLength(); i++) {
 211  0
                 Node node = (Node) fields.item(i);
 212  
                 // they should all be Element...
 213  0
                 if (node instanceof Element) {
 214  0
                     Element field = (Element) node;
 215  
                     // rely on XML validation to ensure this is present
 216  0
                     String fieldName = field.getAttribute("name");
 217  0
                     String attribute = field.getAttribute("attributeName");
 218  0
                     if (attribute != null && attribute.length() > 0) {
 219  0
                         RuleAttribute ruleAttrib = KEWServiceLocator.getRuleAttributeService().findByName(attribute);
 220  0
                         if (ruleAttrib == null) {
 221  0
                             LOG.error("Invalid attribute referenced in EDocLite definition: " + attribute);
 222  0
                             invalidAttributes.add("Attribute '" + attribute + "' referenced in field '" + fieldName + "' not found");
 223  
                         }
 224  
                     }
 225  
                 }
 226  
             }
 227  0
             if (invalidAttributes.size() > 0) {
 228  0
                 LOG.error("Invalid attributes referenced in EDocLite definition");
 229  0
                 StringBuffer message = new StringBuffer("EDocLite definition contains references to non-existent attributes;\n");
 230  0
                 Iterator it = invalidAttributes.iterator();
 231  0
                 while (it.hasNext()) {
 232  0
                     message.append(it.next());
 233  0
                     message.append("\n");
 234  
                 }
 235  0
                 throw new RuntimeException(message.toString());
 236  
             }
 237  
         }
 238  
 
 239  
         try {
 240  0
             def.setXmlContent(XmlHelper.writeNode(e, true));
 241  0
         } catch (TransformerException te) {
 242  0
             throw generateSerializationException(EDLXmlUtils.EDL_E, te);
 243  0
         }
 244  0
         return def;
 245  
     }
 246  
 
 247  
     private static WorkflowServiceErrorException generateMissingAttribException(String element, String attrib) {
 248  0
         return generateException("EDocLite '" + element + "' element must contain a '" + attrib + "' attribute", null);
 249  
     }
 250  
 
 251  
     private static WorkflowServiceErrorException generateMissingChildException(String element, String child) {
 252  0
         return generateException("EDocLite '" + element + "' element must contain a '" + child + "' child element", null);
 253  
     }
 254  
 
 255  
     private static WorkflowServiceErrorException generateSerializationException(String element, TransformerException cause) {
 256  0
         return generateException("Error serializing EDocLite '" + element + "' element", cause);
 257  
     }
 258  
 
 259  
     private static EDocLiteService getEDLService() {
 260  0
             return KEWServiceLocator.getEDocLiteService();
 261  
     }
 262  
 }