View Javadoc

1   /*
2    * Copyright 2005-2008 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.edl.components;
18  
19  import javax.xml.xpath.XPath;
20  import javax.xml.xpath.XPathConstants;
21  import javax.xml.xpath.XPathExpressionException;
22  
23  import org.apache.commons.lang.StringUtils;
24  import org.kuali.rice.kew.edl.EDLContext;
25  import org.kuali.rice.kew.edl.EDLModelComponent;
26  import org.kuali.rice.kew.rule.xmlrouting.XPathHelper;
27  import org.w3c.dom.Document;
28  import org.w3c.dom.Element;
29  import org.w3c.dom.Node;
30  import org.w3c.dom.NodeList;
31  
32  
33  
34  /**
35   * Looks at a field definition for a select field and attempts to analyze and resolve any valuesGroups based on document data.
36   * The result of this is to take a fieldDef that has a valuesGroup and either remove it if it does not match or replace the
37   * <valuesGroup> element with a series of <values> elements that include the values contained with the values group.
38   * 
39   * <p>This allows for <select> fields to be dependent upon one another. 
40   * 
41   * @author Kuali Rice Team (rice.collab@kuali.org)
42   */
43  public class SelectControlEDLComponent implements EDLModelComponent {
44  
45  	public void updateDOM(Document dom, Element currentDefinitionElement, EDLContext edlContext) {
46  	    Element currentVersion = VersioningPreprocessor.findCurrentVersion(dom);
47  	    XPath xPath = XPathHelper.newXPath(dom);
48  	    try {
49  		NodeList selectFieldDefs = (NodeList)xPath.evaluate("//fieldDef[display/type = 'select' and display/valuesGroup] | //fieldDef[display/type = 'select_refresh' and display/valuesGroup]", dom, XPathConstants.NODESET);
50  		for (int fIndex = 0; fIndex < selectFieldDefs.getLength(); fIndex++) {
51  		    Element fieldDef = (Element)selectFieldDefs.item(fIndex);
52  		NodeList valuesGroups = (NodeList)xPath.evaluate("./display/valuesGroup", fieldDef, XPathConstants.NODESET);
53  		for (int index = 0; index < valuesGroups.getLength(); index++) {
54  		    Element valuesGroupElem = (Element)valuesGroups.item(index);
55  		    NodeList dependsOnFields = (NodeList)xPath.evaluate("./dependsOn/field", valuesGroupElem, XPathConstants.NODESET);
56  		    String fieldEvalExpression = "";
57  		    for (int dIndex = 0; dIndex < dependsOnFields.getLength(); dIndex++) {
58  			if (!StringUtils.isBlank(fieldEvalExpression)) {
59  			    fieldEvalExpression += " and ";
60  			}
61  			Element fieldElem = (Element)dependsOnFields.item(dIndex);
62  			String name = fieldElem.getAttribute("name");
63  			String value = fieldElem.getTextContent();
64  			fieldEvalExpression += "./field[@name='" + name + "']/value = '" + value + "'";
65  		    }
66  		    if ((Boolean)xPath.evaluate(fieldEvalExpression, currentVersion, XPathConstants.BOOLEAN)) {
67  			includeValuesGroup(valuesGroupElem);
68  		    } else {
69  			// remove the valuesGroup as it did not match
70  			valuesGroupElem.getParentNode().removeChild(valuesGroupElem);
71  		    }
72  		}
73  		}
74  	    } catch (XPathExpressionException e) {
75  		throw new RuntimeException("Failed to evaluate xpath expression.", e);
76  	    }
77  	}
78  	
79  	protected void includeValuesGroup(Element valuesGroupElem) {
80  	    Element valuesGroupParent = (Element)valuesGroupElem.getParentNode();
81  	    NodeList valuesGroupChildren = valuesGroupElem.getChildNodes();
82  	    
83  	    for (int index = 0; index < valuesGroupChildren.getLength(); index++) {
84  		Node item = valuesGroupChildren.item(index);
85  		if (Node.ELEMENT_NODE == item.getNodeType() && item.getNodeName().equals("values")) {
86  		    valuesGroupParent.insertBefore(item, valuesGroupElem);
87  		}
88  	    }
89  	    valuesGroupParent.removeChild(valuesGroupElem);
90  	}	
91  	
92  }