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.rule.xmlrouting;
017
018 import org.apache.commons.lang.StringUtils;
019 import org.kuali.rice.kew.api.WorkflowRuntimeException;
020 import org.kuali.rice.kew.api.rule.RuleExtension;
021 import org.kuali.rice.kew.xml.xstream.XStreamSafeSearchFunction;
022 import org.w3c.dom.Node;
023
024 import javax.xml.namespace.QName;
025 import javax.xml.xpath.XPath;
026 import javax.xml.xpath.XPathFunction;
027 import javax.xml.xpath.XPathFunctionResolver;
028 import java.util.List;
029 import java.util.Map;
030
031 /**
032 * A function resolver for XPath functions provided by KEW.
033 *
034 * @author Kuali Rice Team (rice.collab@kuali.org)
035 */
036 public class WorkflowFunctionResolver implements XPathFunctionResolver {
037
038 private List<RuleExtension> ruleExtensions;
039 private Node rootNode;
040 private XPath xpath;
041
042
043 public XPathFunction resolveFunction(QName fname, int arity) {
044 if (fname == null) {
045 throw new NullPointerException("The function name cannot be null.");
046 }
047 if (fname.equals(new QName("http://nothingfornowwf.com", "ruledata", "wf"))) {
048 if (ruleExtensions == null) {
049 throw new IllegalArgumentException("There are no rule extensions.");
050 }
051 return new XPathFunction() {
052 public Object evaluate(List args) {
053 if (args.size() == 1) {
054 String name = (String) args.get(0);
055 for (RuleExtension ruleExtension : ruleExtensions) {
056 for (Map.Entry<String, String> entry : ruleExtension.getExtensionValuesMap().entrySet()) {
057 if (entry.getKey().equals(name)) {
058 return entry.getValue();
059 }
060 }
061 }
062 }
063 return "";
064 }
065 };
066 } else if (fname.equals(new QName("http://nothingfornowwf.com", "xstreamsafe", "wf"))) {
067 return new XStreamSafeSearchFunction(rootNode, this.getXpath());
068 } else if (fname.equals(new QName("http://nothingfornowwf.com", "upper-case", "wf"))) {
069 return new UpperCaseFunction();
070 } else if (fname.equals(new QName("http://nothingfornowwf.com", "field", "wf"))) {
071 return new XPathFunction() {
072 public Object evaluate(java.util.List args) {
073 if (args.size() == 1) {
074 String name = (String) args.get(0);
075 try {
076 return field(name);
077 } catch (Exception e) {
078 throw new WorkflowRuntimeException("Failed to find field to validate.", e);
079 }
080 }
081 return "";
082 }
083 };
084 } else if (fname.equals(new QName("http://nothingfornowwf.com", "empty", "wf"))) {
085 return new XPathFunction() {
086 public Object evaluate(java.util.List args) {
087 return empty(args.get(0));
088 }
089 };
090 } else {
091 return null;
092 }
093 }
094
095 public String field(String fieldName) throws Exception {
096 return xpath.evaluate("//edlContent/data/version[@current='true']/field[@name='" + fieldName + "']/value", rootNode);
097 }
098
099
100 public boolean empty(Object object) {
101 if (object instanceof String) {
102 return StringUtils.isBlank((String)object);
103 }
104 return object == null;
105 }
106
107 public List<RuleExtension> getRuleExtensions() {
108 return this.ruleExtensions;
109 }
110
111 public void setRuleExtensions(List<RuleExtension> ruleExtensions) {
112 this.ruleExtensions = ruleExtensions;
113 }
114
115 public Node getRootNode() {
116 return rootNode;
117 }
118
119 public void setRootNode(Node rootNode) {
120 this.rootNode = rootNode;
121 }
122
123
124 public XPath getXpath() {
125 return xpath;
126 }
127
128 public void setXpath(XPath xpath) {
129 this.xpath = xpath;
130 }
131 }