View Javadoc
1   /**
2    * Copyright 2005-2014 The Kuali Foundation
3    *
4    * Licensed under the Educational Community License, Version 2.0 (the "License");
5    * you may not use this file except in compliance with the License.
6    * You may obtain a copy of the License at
7    *
8    * http://www.opensource.org/licenses/ecl2.php
9    *
10   * Unless required by applicable law or agreed to in writing, software
11   * distributed under the License is distributed on an "AS IS" BASIS,
12   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13   * See the License for the specific language governing permissions and
14   * limitations under the License.
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   * Parses {@link org.kuali.rice.kew.rule.bo.RuleAttribute}s from XML.
46   *
47   * @see org.kuali.rice.kew.rule.bo.RuleAttribute
48   *
49   * @author Kuali Rice Team (rice.collab@kuali.org)
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 			//throw new XmlException("RuleAttribute must have an attribute type");
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 //		 default description to label
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 }