001    /**
002     * Copyright 2005-2013 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    }