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