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