/*
 * Licensed to the Apache Software Foundation (ASF) under one
 * or more contributor license agreements. See the NOTICE file
 * distributed with this work for additional information
 * regarding copyright ownership. The ASF licenses this file
 * to you under the Apache License, Version 2.0 (the  "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

import javax.xml.namespace.*;
import javax.xml.xpath.*;
import java.util.Iterator;

/**
 * JAXP 1.3 XPath API sample.
 * 
 * This sample demonstrates the use of NamespaceContext, XPathFunctionResolver
 * and XPathVariableResolver. The evaluated XPath expression ("ex:addFunc(2, 3) + $xyz")
 * contains an extension function and a variable reference. The extension function
 * and variable are evaluated using our customized XPathFunctionResolver and
 * XPathVariableResolver respectively. A NamespaceContext implementation is also
 * needed to map the prefix in the extension function to a valid namespace uri. 
 */
public class XPathResolver
{
    /**
     * The XPath expression to evaluate, which contains an extension
     * function and a variable reference.
     */
    private static final String EXPR = "ex:addFunc(2, 3) + $xyz";
    
    /**
     * The NamespaceContext implementation is used to map the prefix "ex"
     * to the namespace uri "http://ex.com".
     */
    public static class MyNamespaceContext implements NamespaceContext
    {
        public String getNamespaceURI(String prefix)
        {
            if (prefix == null)
              throw new IllegalArgumentException("The prefix cannot be null.");
            
            if (prefix.equals("ex"))
                return "http://ex.com";
            else
                return null;
        }
        
        public String getPrefix(String namespace)
        {
            if (namespace == null)
              throw new IllegalArgumentException("The namespace uri cannot be null.");
            if (namespace.equals("http://ex.com"))
              return "ex";
            else
              return null;
        }

        public Iterator getPrefixes(String namespace)
        {
            return null;
        }
    }
    
    /**
     * The XPathFunctionResolver implementation is used to evaluate
     * the extension function "ex:addFunc(2, 3)".
     */
    public static class MyFunctionResolver implements XPathFunctionResolver
    {
    	/**
    	 * This method returns a customized XPathFunction implementation
    	 * for the extension function "ex:addFunc()".
    	 */
    	public XPathFunction resolveFunction(QName fname, int arity)
    	{
    	  if (fname == null)
    	    throw new NullPointerException("The function name cannot be null.");
    	  
    	  // We only recognize one function, i.e. ex:addFunc().
    	  if (fname.equals(new QName("http://ex.com", "addFunc", "ex")))
    	    /** 
    	     * Return a customized implementation of XPathFunction. We need
    	     * to implement the evaluate(List) method.
    	     */
    	    return new XPathFunction() {
    	      /**
    	       * The actual implementation of the extension function.
    	       * Just cast two arguments to Double and add them together.
    	       */
    	      public Object evaluate(java.util.List args) {
    	        if (args.size() == 2) {
    	          Double arg1 = (Double)args.get(0);
    	          Double arg2 = (Double)args.get(1);
    	          return new Double(arg1.doubleValue() + arg2.doubleValue());
    	        }
    	        else
    	          return null;
    	      }
    	    };
    	  else
    	    return null;
    	}
    }
    
    /**
     * Our own implementation of XPathVariableResolver, which resolves the 
     * variable "xyz" to a double value 4.0.
     */
    public static class MyVariableResolver implements XPathVariableResolver
    {
      public Object resolveVariable(QName varName)
      {
        if (varName == null)
          throw new NullPointerException("The variable name cannot be null.");
        
        if (varName.equals(new QName("", "xyz")))
          return new Double(4.0);
        else
          return null;        	
      }
    }

    
    public static void main(String[] args)
    {    	        
        XPathFactory factory = XPathFactory.newInstance();
        XPath xpath = factory.newXPath();
        // Set the NamespaceContext
        xpath.setNamespaceContext(new MyNamespaceContext());
        // Set the function resolver
        xpath.setXPathFunctionResolver(new MyFunctionResolver());
        // Set the variable resolver
        xpath.setXPathVariableResolver(new MyVariableResolver());
        
        Object result = null;
        try {
          result = xpath.evaluate(EXPR, (Object)null, XPathConstants.NUMBER);
        }
        catch (Exception e) {
            e.printStackTrace();
        }
        
        // The evaluation result is 9.0.
        System.out.println("The evaluation result: " + result);
    }
    
}
