View Javadoc

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