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