001/**
002 * Copyright 2005-2017 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 */
016package org.kuali.rice.kew.rule.xmlrouting;
017
018import org.apache.commons.lang.StringUtils;
019import org.kuali.rice.kew.api.WorkflowRuntimeException;
020import org.kuali.rice.kew.api.rule.RuleExtension;
021import org.kuali.rice.kew.xml.xstream.XStreamSafeSearchFunction;
022import org.w3c.dom.Node;
023
024import javax.xml.namespace.QName;
025import javax.xml.xpath.XPath;
026import javax.xml.xpath.XPathFunction;
027import javax.xml.xpath.XPathFunctionResolver;
028import java.util.List;
029import 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 */
036public 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}