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