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