1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16 package org.kuali.rice.coreservice.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.coreservice.api.style.Style;
22 import org.kuali.rice.coreservice.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
44
45
46 public class StyleXmlParserImpl implements StyleXmlParser {
47 private static final Logger LOG = Logger.getLogger(StyleXmlParserImpl.class);
48
49 private StyleService styleService;
50
51
52
53
54
55 private static DocumentBuilder getDocumentBuilder() {
56 try {
57 return DocumentBuilderFactory.newInstance().newDocumentBuilder();
58 } catch (ParserConfigurationException pce) {
59
60
61 String message = "Error obtaining document builder";
62 LOG.error(message, pce);
63 throw new RuntimeException(message, pce);
64 }
65 }
66
67 public void loadXml(InputStream inputStream, String principalId) {
68 List<Style> styles = parseStyles(inputStream);
69 for (Style style : styles) {
70 styleService.saveStyle(style);
71 }
72 }
73
74 public List<Style> parseStyles(InputStream inputStream) {
75 DocumentBuilder db = getDocumentBuilder();
76 XPath xpath = XPathFactory.newInstance().newXPath();
77 Document doc;
78 try {
79 doc = db.parse(inputStream);
80 } catch (Exception e) {
81 throw generateException("Error parsing Style XML file", e);
82 }
83 NodeList styles;
84 try {
85 styles = (NodeList) xpath.evaluate("//" + XmlConstants.STYLE_STYLES, doc.getFirstChild(), XPathConstants.NODESET);
86 } catch (XPathExpressionException e) {
87 throw generateException("Error evaluating XPath expression", e);
88 }
89
90 List<Style> parsedStyles = new ArrayList<Style>();
91 for (int i = 0; i < styles.getLength(); i++) {
92 Node edl = styles.item(i);
93 NodeList children = edl.getChildNodes();
94 for (int j = 0; j < children.getLength(); j++) {
95 Node node = children.item(j);
96 if (node.getNodeType() == Node.ELEMENT_NODE) {
97 Element e = (Element) node;
98 if (XmlConstants.STYLE_STYLE.equals(node.getNodeName())) {
99 LOG.debug("Digesting style: " + e.getAttribute("name"));
100 Style.Builder styleBuilder = parseStyle(e);
101 parsedStyles.add(styleBuilder.build());
102 }
103 }
104 }
105 }
106 return parsedStyles;
107 }
108
109
110
111
112
113
114
115
116 private static Style.Builder parseStyle(Element e) {
117 String name = e.getAttribute("name");
118 if (name == null || name.length() == 0) {
119 throw generateMissingAttribException(XmlConstants.STYLE_STYLE, "name");
120 }
121 Style.Builder style = Style.Builder.create(name);
122 Element stylesheet = null;
123 NodeList children = e.getChildNodes();
124 for (int i = 0; i < children.getLength(); i++) {
125 Node child = children.item(i);
126 if (child.getNodeType() == Node.ELEMENT_NODE && "xsl:stylesheet".equals(child.getNodeName())) {
127 stylesheet = (Element) child;
128 break;
129 }
130 }
131 if (stylesheet == null) {
132 throw generateMissingChildException(XmlConstants.STYLE_STYLE, "xsl:stylesheet");
133 }
134 try {
135 style.setXmlContent(XmlJotter.jotNode(stylesheet, true));
136 } catch (XmlException te) {
137 throw generateSerializationException(XmlConstants.STYLE_STYLE, te);
138 }
139 return style;
140 }
141
142 private static XmlIngestionException generateMissingAttribException(String element, String attrib) {
143 return generateException("Style '" + element + "' element must contain a '" + attrib + "' attribute", null);
144 }
145
146 private static XmlIngestionException generateMissingChildException(String element, String child) {
147 return generateException("Style '" + element + "' element must contain a '" + child + "' child element", null);
148 }
149
150 private static XmlIngestionException generateSerializationException(String element, XmlException cause) {
151 return generateException("Error serializing Style '" + element + "' element", cause);
152 }
153
154 private static XmlIngestionException generateException(String error, Throwable cause) {
155 return new XmlIngestionException(error, cause);
156 }
157
158 public void setStyleService(StyleService styleService) {
159 this.styleService = styleService;
160 }
161
162 }