001    /**
002     * Copyright 2005-2014 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 javax.xml.xpath.XPath;
019    import javax.xml.xpath.XPathFactory;
020    import javax.xml.xpath.XPathFunctionResolver;
021    
022    import org.kuali.rice.kew.api.WorkflowRuntimeException;
023    import org.w3c.dom.Node;
024    
025    
026    /**
027     * Provides utilities for obtaining XPath instances which are "good-to-go" with access to the Workflow
028     * namespace and custom XPath functions.
029     * 
030     * @author Kuali Rice Team (rice.collab@kuali.org)
031     */
032    public class XPathHelper {
033    
034            /**
035             * Creates a new XPath instance and initializes it with the WorkflowNamespaceContext and the
036             * WorkflowFunctionResolver.
037             */
038            public static XPath newXPath() {
039                    XPath xPath = XPathFactory.newInstance().newXPath();
040                    xPath.setNamespaceContext(new WorkflowNamespaceContext());
041                    WorkflowFunctionResolver resolver = new WorkflowFunctionResolver();
042                    xPath.setXPathFunctionResolver(resolver); 
043                    resolver.setXpath(xPath);
044                    return xPath;
045            }
046    
047            /**
048             * Creates a new XPath instances and initializes it with the WorkflowNamespaceContext and the
049             * WorkflowFunctionResolver.  Also sets the root node on the WorkflowFunctionResolver to 
050             * the given Node.  This is required for some of the functions in the function resolver
051             * to perform properly.
052             */
053            public static XPath newXPath(Node rootNode) {
054                    XPath xPath = newXPath();
055                    WorkflowFunctionResolver resolver = extractFunctionResolver(xPath);
056                    resolver.setRootNode(rootNode);
057                    return xPath;
058            }
059            
060            /**
061             * A utility to extract the WorkflowFunctionResolver from the given XPath instances.  If the XPath instance
062             * does not contain a WorkflowFunctionResolver, then this method will throw a WorkflowRuntimeException.
063             * 
064             * @throws WorkflowRuntimeException if the given XPath instance does not contain a WorklflowFunctionResolver
065             */
066            public static WorkflowFunctionResolver extractFunctionResolver(XPath xPath) {
067                    XPathFunctionResolver resolver = xPath.getXPathFunctionResolver();
068                    if (!hasWorkflowFunctionResolver(xPath)) {
069                            throw new WorkflowRuntimeException("The XPathFunctionResolver on the given XPath instance is not an instance of WorkflowFunctionResolver, was: " + resolver);
070                    }
071                    return (WorkflowFunctionResolver)resolver;
072            }
073            
074            /**
075             * Returns true if the given XPath instance has a WorkflowFunctionResolver, false otherwise.
076             */
077            public static boolean hasWorkflowFunctionResolver(XPath xPath) {
078                    return xPath.getXPathFunctionResolver() instanceof WorkflowFunctionResolver;
079            }
080            
081    }