View Javadoc

1   /**
2    * Copyright 2005-2012 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.rule;
17  
18  import org.apache.commons.lang.StringUtils;
19  import org.kuali.rice.kew.api.KewApiConstants;
20  import org.kuali.rice.kew.api.WorkflowRuntimeException;
21  import org.kuali.rice.kew.api.extension.ExtensionDefinition;
22  import org.kuali.rice.kew.api.identity.Id;
23  import org.kuali.rice.kew.engine.RouteContext;
24  import org.kuali.rice.kew.routeheader.DocumentContent;
25  import org.kuali.rice.kew.rule.xmlrouting.GenericXMLRuleAttribute;
26  import org.kuali.rice.kew.rule.xmlrouting.XPathHelper;
27  import org.w3c.dom.Element;
28  import org.w3c.dom.NodeList;
29  import org.xml.sax.InputSource;
30  
31  import javax.xml.xpath.XPath;
32  import javax.xml.xpath.XPathConstants;
33  import javax.xml.xpath.XPathExpressionException;
34  import java.io.StringReader;
35  import java.util.ArrayList;
36  import java.util.HashMap;
37  import java.util.List;
38  import java.util.Map;
39  
40  /**
41   * A generic Role Attribute superclass that can be used to route to an ID. Can
42   * take as configuration the label to use for the element name in the XML. This
43   * allows for re-use of this component in different contexts.
44   * 
45   * @author Kuali Rice Team (rice.collab@kuali.org)
46   */
47  public abstract class AbstractIdRoleAttribute extends AbstractRoleAttribute
48  		implements GenericXMLRuleAttribute {
49  
50  	private static final String XML_ELEMENT_LABEL = "xmlElementLabel";
51  	private static final String ROLE_NAME_LABEL = "roleNameLabel";
52  
53  	private String idValue;
54  	private Map paramMap = new HashMap();
55  	private ExtensionDefinition extensionDefinition;
56  
57  	protected abstract String getAttributeElementName();
58  
59  	protected abstract Id resolveId(String id);
60  
61  	protected abstract String getIdName();
62  
63  	/**
64  	 * Returns qualified role names based on IDs in the XML. Each returned
65  	 * qualified Role contains a single ID.
66  	 * 
67  	 * @see org.kuali.rice.kew.rule.RoleAttribute#getQualifiedRoleNames(java.lang.String,
68  	 *      org.kuali.rice.kew.routeheader.DocumentContent)
69  	 */
70  	public List<String> getQualifiedRoleNames(String roleName,
71  			DocumentContent documentContent) {
72  		try {
73  			readConfiguration();
74  			String elementName = (String) getParamMap().get(XML_ELEMENT_LABEL);
75  			List<String> qualifiedRoleNames = new ArrayList<String>();
76  			XPath xPath = XPathHelper.newXPath();
77  			NodeList idNodes = (NodeList) xPath.evaluate("//"
78  					+ getAttributeElementName() + "/" + elementName,
79  					documentContent.getDocument(), XPathConstants.NODESET);
80  			for (int index = 0; index < idNodes.getLength(); index++) {
81  				Element idElement = (Element) idNodes.item(index);
82  				String id = idElement.getTextContent();
83  				qualifiedRoleNames.add(id);
84  			}
85  			return qualifiedRoleNames;
86  		} catch (XPathExpressionException e) {
87  			throw new WorkflowRuntimeException(
88  					"Failed to evaulate XPath expression to find ids.", e);
89  		}
90  	}
91  
92  	/**
93  	 * Takes the given qualified role which contains an ID and returns a
94  	 * resolved role for the entity with that id.
95  	 * 
96  	 * @see org.kuali.rice.kew.rule.RoleAttribute#resolveQualifiedRole(org.kuali.rice.kew.engine.RouteContext,
97  	 *      java.lang.String, java.lang.String)
98  	 */
99  	public ResolvedQualifiedRole resolveQualifiedRole(
100 			RouteContext routeContext, String roleName, String qualifiedRole) {
101 		String roleNameLabel = (String) getParamMap().get(ROLE_NAME_LABEL);
102 		if (roleNameLabel == null) {
103 			readConfiguration();
104 			roleNameLabel = (String) getParamMap().get(ROLE_NAME_LABEL);
105 		}
106 		ResolvedQualifiedRole resolvedRole = new ResolvedQualifiedRole();
107 		resolvedRole.setQualifiedRoleLabel(roleNameLabel);
108 		resolvedRole.getRecipients().add(resolveId(qualifiedRole));
109 		return resolvedRole;
110 	}
111 
112 	/**
113 	 * Generates XML containing the ID on this attribute.
114 	 * 
115 	 * @see org.kuali.rice.kew.rule.AbstractWorkflowAttribute#getDocContent()
116 	 */
117 	@Override
118 	public String getDocContent() {
119 		readConfiguration();
120 		if (!StringUtils.isBlank(getIdValue())) {
121 			String elementName = (String) getParamMap().get(XML_ELEMENT_LABEL);
122 			return "<" + getAttributeElementName() + "><" + elementName + ">"
123 					+ getIdValue() + "</" + elementName + "></"
124 					+ getAttributeElementName() + ">";
125 		}
126 		return "";
127 	}
128 
129 	/**
130 	 * Reads any configured values in the XML of the RuleAttribute and adds them
131 	 * to the paramMap.
132 	 * 
133 	 */
134 	protected void readConfiguration() {
135 		String idInMap = (String) getParamMap().get(getIdName());
136 		if (getIdValue() == null) {
137 			setIdValue(idInMap);
138 		}
139 		if (getIdValue() != null) {
140 			getParamMap().put(getIdName(), getIdValue());
141 		}
142 		if (extensionDefinition != null) {
143 			String xmlConfigData = extensionDefinition.getConfiguration().get(KewApiConstants.ATTRIBUTE_XML_CONFIG_DATA);
144 			if (!StringUtils.isBlank(xmlConfigData)) {
145 				XPath xPath = XPathHelper.newXPath();
146 				try {
147 					String xmlElementLabel = xPath.evaluate("/configuration/"
148 							+ XML_ELEMENT_LABEL, new InputSource(
149 							new StringReader(xmlConfigData)));
150 					String roleNameLabel = xPath.evaluate("/configuration/"
151 							+ ROLE_NAME_LABEL, new InputSource(
152 							new StringReader(xmlConfigData)));
153 					if (!StringUtils.isBlank(xmlElementLabel)) {
154 						getParamMap().put(XML_ELEMENT_LABEL, xmlElementLabel);
155 					}
156 					if (!StringUtils.isBlank(roleNameLabel)) {
157 						getParamMap().put(ROLE_NAME_LABEL, roleNameLabel);
158 					}
159 
160 				} catch (XPathExpressionException e) {
161 					throw new WorkflowRuntimeException(
162 							"Failed to locate Rule Attribute configuration.");
163 				}
164 			}
165 		}
166 		// setup default values if none were defined in XML
167 		if (StringUtils.isBlank((String) getParamMap().get(XML_ELEMENT_LABEL))) {
168 			getParamMap().put(XML_ELEMENT_LABEL, getIdName());
169 		}
170 		if (getParamMap().get(ROLE_NAME_LABEL) == null) {
171 			getParamMap().put(ROLE_NAME_LABEL, "");
172 		}
173 	}
174 
175 	public String getIdValue() {
176 		return this.idValue;
177 	}
178 
179 	public void setIdValue(String idValue) {
180 		this.idValue = idValue;
181 	}
182 
183 	public Map getParamMap() {
184 		return paramMap;
185 	}
186 
187 	public void setParamMap(Map paramMap) {
188 		this.paramMap = paramMap;
189 	}
190 
191 	public void setExtensionDefinition(ExtensionDefinition extensionDefinition) {
192 		this.extensionDefinition = extensionDefinition;
193 	}
194 
195 }