1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17 package org.kuali.rice.kew.xml;
18
19 import java.io.IOException;
20 import java.io.InputStream;
21 import java.util.ArrayList;
22 import java.util.Iterator;
23 import java.util.List;
24
25 import javax.xml.parsers.DocumentBuilderFactory;
26 import javax.xml.transform.TransformerException;
27 import javax.xml.xpath.XPath;
28 import javax.xml.xpath.XPathConstants;
29 import javax.xml.xpath.XPathExpressionException;
30
31 import org.apache.commons.lang.StringUtils;
32 import org.kuali.rice.kew.exception.InvalidXmlException;
33 import org.kuali.rice.kew.rule.bo.RuleAttribute;
34 import org.kuali.rice.kew.rule.xmlrouting.XPathHelper;
35 import org.kuali.rice.kew.service.KEWServiceLocator;
36 import org.kuali.rice.kew.util.KEWConstants;
37 import org.kuali.rice.kew.util.Utilities;
38 import org.kuali.rice.kew.util.XmlHelper;
39 import org.w3c.dom.Element;
40 import org.w3c.dom.Node;
41 import org.w3c.dom.NodeList;
42 import org.xml.sax.InputSource;
43
44
45
46
47
48
49
50
51
52 public class RuleAttributeXmlParser implements XmlConstants {
53 private static final org.apache.log4j.Logger LOG = org.apache.log4j.Logger.getLogger(RuleAttributeXmlParser.class);
54
55
56 private static final String XPATH_RULE_ATTRIBUTES = "//" + RULE_ATTRIBUTES + "/" + RULE_ATTRIBUTE;
57 private static final String NAME = "name";
58 private static final String CLASS_NAME = "className";
59 private static final String LABEL = "label";
60 private static final String DESCRIPTION = "description";
61 private static final String TYPE = "type";
62 private static final String CONFIG = "configuration";
63
64 public List parseRuleAttributes(InputStream input) throws IOException, InvalidXmlException {
65 try {
66 Element root = DocumentBuilderFactory.newInstance().newDocumentBuilder().parse(new InputSource(input)).getDocumentElement();
67 return parseRuleAttributes(root);
68 } catch (Exception e) {
69 throw new InvalidXmlException("error parsing xml data", e);
70 }
71 }
72
73 public List parseRuleAttributes(Element element) throws InvalidXmlException {
74 List ruleAttributes = new ArrayList();
75 try {
76 XPath xpath = XPathHelper.newXPath();
77 NodeList nodeList = (NodeList)xpath.evaluate(XPATH_RULE_ATTRIBUTES, element, XPathConstants.NODESET);
78 for (int i = 0; i < nodeList.getLength(); i++) {
79 Node ruleAttributeNode = nodeList.item(i);
80 ruleAttributes.add(parseRuleAttribute(ruleAttributeNode));
81 }
82
83 for (Iterator iterator = ruleAttributes.iterator(); iterator.hasNext();) {
84 RuleAttribute ruleAttribute = (RuleAttribute) iterator.next();
85 try {
86 RuleAttribute existingAttribute = KEWServiceLocator.getRuleAttributeService().findByName(ruleAttribute.getName());
87 if (existingAttribute != null) {
88 ruleAttribute.setRuleAttributeId(existingAttribute.getRuleAttributeId());
89 ruleAttribute.setVersionNumber(existingAttribute.getVersionNumber());
90 }
91 KEWServiceLocator.getRuleAttributeService().save(ruleAttribute);
92 } catch (Exception e) {
93 LOG.error("Error saving rule attribute entered by XML", e);
94 }
95 }
96 } catch (XPathExpressionException e1) {
97 throw new InvalidXmlException("Could not find a rule attribute.", e1);
98 }
99 return ruleAttributes;
100 }
101
102 private RuleAttribute parseRuleAttribute(Node ruleAttributeNode) throws InvalidXmlException {
103 String name = "";
104 String className = "";
105 String label = "";
106 String description = "";
107 String type = "";
108 String serviceNamespace = null;
109 Node xmlConfig = null;
110 for (int i = 0; i < ruleAttributeNode.getChildNodes().getLength(); i++) {
111 Node childNode = ruleAttributeNode.getChildNodes().item(i);
112 if(NAME.equals(childNode.getNodeName())){
113 name = childNode.getFirstChild().getNodeValue();
114 } else if(CLASS_NAME.equals(childNode.getNodeName())){
115 className = childNode.getFirstChild().getNodeValue();
116 } else if(LABEL.equals(childNode.getNodeName())){
117 label = childNode.getFirstChild().getNodeValue();
118 } else if(DESCRIPTION.equals(childNode.getNodeName())){
119 description = childNode.getFirstChild().getNodeValue();
120 } else if(TYPE.equals(childNode.getNodeName())){
121 type = childNode.getFirstChild().getNodeValue();
122 } else if(ROUTING_CONFIG.equals(childNode.getNodeName()) || SEARCHING_CONFIG.equals(childNode.getNodeName()) ||
123 SEARCH_RESULT_CONFIG.equals(childNode.getNodeName()) || RESOLVER_CONFIG.equals(childNode.getNodeName()) ||
124 CONFIG.equals(childNode.getNodeName())){
125 xmlConfig = childNode;
126 } else if (SERVICE_NAMESPACE.equals(childNode.getNodeName())) {
127 serviceNamespace = childNode.getFirstChild().getNodeValue();
128 }
129 }
130 if (Utilities.isEmpty(name)) {
131 throw new InvalidXmlException("RuleAttribute must have a name");
132 }
133 if (Utilities.isEmpty(className)) {
134 throw new InvalidXmlException("RuleAttribute must have a className");
135 }
136 if (Utilities.isEmpty(label)) {
137 LOG.warn("Label empty defaulting to name");
138 label = name;
139 }
140 if (Utilities.isEmpty(type)) {
141 LOG.debug("No type specified, default to " + KEWConstants.RULE_ATTRIBUTE_TYPE);
142 type = KEWConstants.RULE_ATTRIBUTE_TYPE;
143
144 }
145 RuleAttribute ruleAttribute = new RuleAttribute();
146 ruleAttribute.setName(name.trim());
147 ruleAttribute.setClassName(className.trim());
148 ruleAttribute.setType(type.trim());
149 ruleAttribute.setLabel(label.trim());
150
151 if (StringUtils.isEmpty(description)) {
152 description = label;
153 }
154 ruleAttribute.setDescription(description.trim());
155 if (serviceNamespace != null)
156 {
157 serviceNamespace = serviceNamespace.trim();
158 }
159 ruleAttribute.setServiceNamespace(serviceNamespace);
160
161 if(xmlConfig != null){
162 try {
163 ruleAttribute.setXmlConfigData(XmlHelper.writeNode(xmlConfig));
164 } catch (TransformerException e) {
165 throw new InvalidXmlException("XML config is invalid", e);
166 }
167 } else {
168 if(KEWConstants.RULE_XML_ATTRIBUTE_TYPE.equals(type)){
169 throw new InvalidXmlException("A routing config must be present to be of type: "+type);
170 } else if(KEWConstants.SEARCHABLE_XML_ATTRIBUTE_TYPE.equals(type)){
171 throw new InvalidXmlException("A searching config must be present to be of type: "+type);
172 } else if(KEWConstants.SEARCH_RESULT_XML_PROCESSOR_ATTRIBUTE_TYPE.equals(type)){
173 throw new InvalidXmlException("A searching config must be present to be of type: "+type);
174 }
175 }
176 return ruleAttribute;
177 }
178 }