001 /**
002 * Copyright 2005-2012 The Kuali Foundation
003 *
004 * Licensed under the Educational Community License, Version 2.0 (the "License");
005 * you may not use this file except in compliance with the License.
006 * You may obtain a copy of the License at
007 *
008 * http://www.opensource.org/licenses/ecl2.php
009 *
010 * Unless required by applicable law or agreed to in writing, software
011 * distributed under the License is distributed on an "AS IS" BASIS,
012 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
013 * See the License for the specific language governing permissions and
014 * limitations under the License.
015 */
016 package org.kuali.rice.kew.xml;
017
018 import org.apache.commons.lang.StringUtils;
019 import org.kuali.rice.core.api.impex.xml.XmlConstants;
020 import org.kuali.rice.core.api.util.xml.XmlException;
021 import org.kuali.rice.core.api.util.xml.XmlJotter;
022 import org.kuali.rice.kew.rule.bo.RuleAttribute;
023 import org.kuali.rice.kew.rule.xmlrouting.XPathHelper;
024 import org.kuali.rice.kew.service.KEWServiceLocator;
025 import org.kuali.rice.kew.api.KewApiConstants;
026 import org.w3c.dom.Element;
027 import org.w3c.dom.Node;
028 import org.w3c.dom.NodeList;
029 import org.xml.sax.InputSource;
030
031 import javax.xml.parsers.DocumentBuilderFactory;
032 import javax.xml.xpath.XPath;
033 import javax.xml.xpath.XPathConstants;
034 import javax.xml.xpath.XPathExpressionException;
035 import java.io.IOException;
036 import java.io.InputStream;
037 import java.util.ArrayList;
038 import java.util.Iterator;
039 import java.util.List;
040
041 import static org.kuali.rice.core.api.impex.xml.XmlConstants.APPLICATION_ID;
042
043
044 /**
045 * Parses {@link org.kuali.rice.kew.rule.bo.RuleAttribute}s from XML.
046 *
047 * @see org.kuali.rice.kew.rule.bo.RuleAttribute
048 *
049 * @author Kuali Rice Team (rice.collab@kuali.org)
050 */
051 public class RuleAttributeXmlParser {
052 private static final org.apache.log4j.Logger LOG = org.apache.log4j.Logger.getLogger(RuleAttributeXmlParser.class);
053
054
055 private static final String XPATH_RULE_ATTRIBUTES = "//" + XmlConstants.RULE_ATTRIBUTES + "/" + XmlConstants.RULE_ATTRIBUTE;
056 private static final String NAME = "name";
057 private static final String CLASS_NAME = "className";
058 private static final String LABEL = "label";
059 private static final String DESCRIPTION = "description";
060 private static final String TYPE = "type";
061 private static final String CONFIG = "configuration";
062
063 public List parseRuleAttributes(InputStream input) throws IOException, XmlException {
064 try {
065 Element root = DocumentBuilderFactory.newInstance().newDocumentBuilder().parse(new InputSource(input)).getDocumentElement();
066 return parseRuleAttributes(root);
067 } catch (Exception e) {
068 throw new XmlException("error parsing xml data", e);
069 }
070 }
071
072 public List parseRuleAttributes(Element element) throws XmlException {
073 List ruleAttributes = new ArrayList();
074 try {
075 XPath xpath = XPathHelper.newXPath();
076 NodeList nodeList = (NodeList)xpath.evaluate(XPATH_RULE_ATTRIBUTES, element, XPathConstants.NODESET);
077 for (int i = 0; i < nodeList.getLength(); i++) {
078 Node ruleAttributeNode = nodeList.item(i);
079 ruleAttributes.add(parseRuleAttribute(ruleAttributeNode));
080 }
081
082 for (Iterator iterator = ruleAttributes.iterator(); iterator.hasNext();) {
083 RuleAttribute ruleAttribute = (RuleAttribute) iterator.next();
084 try {
085 RuleAttribute existingAttribute = KEWServiceLocator.getRuleAttributeService().findByName(ruleAttribute.getName());
086 if (existingAttribute != null) {
087 ruleAttribute.setId(existingAttribute.getId());
088 ruleAttribute.setVersionNumber(existingAttribute.getVersionNumber());
089 }
090 KEWServiceLocator.getRuleAttributeService().save(ruleAttribute);
091 } catch (Exception e) {
092 LOG.error("Error saving rule attribute entered by XML", e);
093 }
094 }
095 } catch (XPathExpressionException e1) {
096 throw new XmlException("Could not find a rule attribute.", e1);
097 }
098 return ruleAttributes;
099 }
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 }