Coverage Report - org.kuali.rice.core.impl.style.StyleXmlParserImpl
 
Classes in this File Line Coverage Branch Coverage Complexity
StyleXmlParserImpl
0%
0/55
0%
0/22
3.2
StyleXmlParserImpl$1
0%
0/6
N/A
3.2
 
 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.core.impl.style;
 17  
 
 18  
 import org.apache.log4j.Logger;
 19  
 import org.kuali.rice.core.api.impex.xml.XmlConstants;
 20  
 import org.kuali.rice.core.api.impex.xml.XmlIngestionException;
 21  
 import org.kuali.rice.core.api.style.Style;
 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.w3c.dom.Document;
 26  
 import org.w3c.dom.Element;
 27  
 import org.w3c.dom.Node;
 28  
 import org.w3c.dom.NodeList;
 29  
 
 30  
 import javax.xml.parsers.DocumentBuilder;
 31  
 import javax.xml.parsers.DocumentBuilderFactory;
 32  
 import javax.xml.parsers.ParserConfigurationException;
 33  
 import javax.xml.xpath.XPath;
 34  
 import javax.xml.xpath.XPathConstants;
 35  
 import javax.xml.xpath.XPathExpressionException;
 36  
 import javax.xml.xpath.XPathFactory;
 37  
 import java.io.InputStream;
 38  
 import java.util.ArrayList;
 39  
 import java.util.List;
 40  
 
 41  
 
 42  
 /**
 43  
  * Parser for Style content type, managed by StyleService
 44  
  * @author Kuali Rice Team (rice.collab@kuali.org)
 45  
  */
 46  0
 public class StyleXmlParserImpl implements StyleXmlParser {
 47  0
         private static final Logger LOG = Logger.getLogger(StyleXmlParserImpl.class);
 48  
 
 49  
         private StyleService styleService;
 50  
         
 51  0
     private static ThreadLocal<DocumentBuilder> DOCUMENT_BUILDER = new ThreadLocal<DocumentBuilder>() {
 52  
         protected DocumentBuilder initialValue() {
 53  
             try {
 54  0
                 return DocumentBuilderFactory.newInstance().newDocumentBuilder();
 55  0
             } catch (ParserConfigurationException pce) {
 56  
                 // well folks, there is not much we can do if we get a ParserConfigurationException
 57  
                 // so might as well isolate the evilness here, and just balk if this occurs
 58  0
                 String message = "Error obtaining document builder";
 59  0
                 LOG.error(message, pce);
 60  0
                 throw new RuntimeException(message, pce);
 61  
             }
 62  
         }
 63  
     };
 64  
 
 65  
     /**
 66  
      * Returns a valid DocumentBuilder
 67  
      * @return a valid DocumentBuilder
 68  
      */
 69  
     private static DocumentBuilder getDocumentBuilder() {
 70  0
         return (DocumentBuilder) DOCUMENT_BUILDER.get();
 71  
     }
 72  
 
 73  
     public void loadXml(InputStream inputStream, String principalId) {
 74  0
             List<Style> styles = parseStyles(inputStream);
 75  0
             for (Style style : styles) {
 76  0
                     styleService.saveStyle(style);
 77  
             }
 78  0
     }
 79  
     
 80  
     public List<Style> parseStyles(InputStream inputStream) {
 81  0
             DocumentBuilder db = getDocumentBuilder();
 82  0
         XPath xpath = XPathFactory.newInstance().newXPath();
 83  
         Document doc;
 84  
         try {
 85  0
             doc = db.parse(inputStream);
 86  0
         } catch (Exception e) {
 87  0
             throw generateException("Error parsing Style XML file", e);
 88  0
         }
 89  
         NodeList styles;
 90  
         try {
 91  0
                 styles = (NodeList) xpath.evaluate("//" + XmlConstants.STYLE_STYLES, doc.getFirstChild(), XPathConstants.NODESET);
 92  0
         } catch (XPathExpressionException e) {
 93  0
                 throw generateException("Error evaluating XPath expression", e);
 94  0
         }
 95  
 
 96  0
         List<Style> parsedStyles = new ArrayList<Style>();
 97  0
         for (int i = 0; i < styles.getLength(); i++) {
 98  0
                 Node edl = styles.item(i);
 99  0
                 NodeList children = edl.getChildNodes();
 100  0
                 for (int j = 0; j < children.getLength(); j++) {
 101  0
                         Node node = children.item(j);
 102  0
                         if (node.getNodeType() == Node.ELEMENT_NODE) {
 103  0
                                 Element e = (Element) node;
 104  0
                                 if (XmlConstants.STYLE_STYLE.equals(node.getNodeName())) {
 105  0
                                         LOG.debug("Digesting style: " + e.getAttribute("name"));
 106  0
                                         Style.Builder styleBuilder = parseStyle(e);
 107  0
                                         parsedStyles.add(styleBuilder.build());
 108  
                                 }
 109  
                 }
 110  
             }
 111  
         }
 112  0
         return parsedStyles;
 113  
     }
 114  
     
 115  
     /**
 116  
      * Parses an EDocLiteStyle
 117  
      *
 118  
      * @param e
 119  
      *            element to parse
 120  
      * @return an EDocLiteStyle
 121  
      */
 122  
     private static Style.Builder parseStyle(Element e) {
 123  0
         String name = e.getAttribute("name");
 124  0
         if (name == null || name.length() == 0) {
 125  0
             throw generateMissingAttribException(XmlConstants.STYLE_STYLE, "name");
 126  
         }
 127  0
         Style.Builder style = Style.Builder.create(name);
 128  0
         Element stylesheet = null;
 129  0
         NodeList children = e.getChildNodes();
 130  0
         for (int i = 0; i < children.getLength(); i++) {
 131  0
             Node child = children.item(i);
 132  0
             if (child.getNodeType() == Node.ELEMENT_NODE && "xsl:stylesheet".equals(child.getNodeName())) {
 133  0
                 stylesheet = (Element) child;
 134  0
                 break;
 135  
             }
 136  
         }
 137  0
         if (stylesheet == null) {
 138  0
             throw generateMissingChildException(XmlConstants.STYLE_STYLE, "xsl:stylesheet");
 139  
         }
 140  
         try {
 141  0
             style.setXmlContent(XmlJotter.jotNode(stylesheet, true));
 142  0
         } catch (XmlException te) {
 143  0
             throw generateSerializationException(XmlConstants.STYLE_STYLE, te);
 144  0
         }
 145  0
         return style;
 146  
     }
 147  
 
 148  
     private static XmlIngestionException generateMissingAttribException(String element, String attrib) {
 149  0
         return generateException("Style '" + element + "' element must contain a '" + attrib + "' attribute", null);
 150  
     }
 151  
 
 152  
     private static XmlIngestionException generateMissingChildException(String element, String child) {
 153  0
         return generateException("Style '" + element + "' element must contain a '" + child + "' child element", null);
 154  
     }
 155  
 
 156  
     private static XmlIngestionException generateSerializationException(String element, XmlException cause) {
 157  0
         return generateException("Error serializing Style '" + element + "' element", cause);
 158  
     }
 159  
     
 160  
     private static XmlIngestionException generateException(String error, Throwable cause) {
 161  0
             return new XmlIngestionException(error, cause);
 162  
     }
 163  
     
 164  
     public void setStyleService(StyleService styleService) {
 165  0
             this.styleService = styleService;
 166  0
     }
 167  
 
 168  
 }