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