/*
 * 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 java.io.OutputStreamWriter;

import javax.xml.namespace.*;
import javax.xml.transform.*;
import javax.xml.transform.dom.DOMSource;
import javax.xml.transform.stream.StreamResult;
import javax.xml.xpath.*;
import org.xml.sax.*;
import org.w3c.dom.*;

/**
 * JAXP 1.3 XPath API sample.
 * 
 * Basic utility for applying an XPath expression to an input xml file and printing
 * the evaluation result, using JAXP 1.3 XPath API.
 * 
 * Takes 3 arguments:
 * (1) an xml file name
 * (2) an XPath expression to apply to the input document
 * (3) the return type, which is one of the following Strings:
 *     num, bool, str, node, nodeset
 * 
 * Examples:
 * 	java ApplyXPathJAXP foo.xml /doc/name[1]/@last str
 * 	java ApplyXPathJAXP foo.xml /doc/name nodeset
 */
public class ApplyXPathJAXP
{
    public static void main(String[] args)
    {
    	QName returnType = null;
    	
        if (args.length != 3)
        {
            System.err.println("Usage: java ApplyXPathAPI xml_file xpath_expression type");
        }
        
        InputSource xml = new InputSource(args[0]);
        String expr = args[1];
        
        // set the return type
        if (args[2].equals("num")) returnType = XPathConstants.NUMBER;
        else if (args[2].equals("bool")) returnType = XPathConstants.BOOLEAN;
        else if (args[2].equals("str")) returnType = XPathConstants.STRING;
        else if (args[2].equals("node")) returnType = XPathConstants.NODE;
        else if (args[2].equals("nodeset")) returnType = XPathConstants.NODESET;
        else
          System.err.println("Invalid return type: " + args[2]);
        
        // Create a new XPath
        XPathFactory factory = XPathFactory.newInstance();
        XPath xpath = factory.newXPath();
        
        Object result = null;
        try {
          // compile the XPath expression
          XPathExpression xpathExpr = xpath.compile(expr);
          
          // Evaluate the XPath expression against the input document
          result = xpathExpr.evaluate(xml, returnType);
          
          // Print the result to System.out.
          printResult(result);
        }
        catch (Exception e) {
          e.printStackTrace();
        }        
    }
    
    /**
     * Print the type and value of the evaluation result.
     */
    static void printResult(Object result)
      throws Exception
    {
        if (result instanceof Double) {
            System.out.println("Result type: double");
            System.out.println("Value: " + result);
        }
        else if (result instanceof Boolean) {
            System.out.println("Result type: boolean");
            System.out.println("Value: " + ((Boolean)result).booleanValue());
        }	
        else if (result instanceof String) {
            System.out.println("Result type: String");
             System.out.println("Value: " + result);
        }
        else if (result instanceof Node) {
            Node node = (Node)result;
            System.out.println("Result type: Node");
            System.out.println("<output>");
            printNode(node);
            System.out.println("</output>");
        }
        else if (result instanceof NodeList) {
            NodeList nodelist = (NodeList)result;
            System.out.println("Result type: NodeList");
            System.out.println("<output>");
            printNodeList(nodelist);
            System.out.println("</output>");
        }
    }

    /** Decide if the node is text, and so must be handled specially */
    static boolean isTextNode(Node n) 
    {
      if (n == null)
        return false;
      short nodeType = n.getNodeType();
      return nodeType == Node.CDATA_SECTION_NODE || nodeType == Node.TEXT_NODE;
    }
    
    static void printNode(Node node) 
      throws Exception
    {
      if (isTextNode(node)) {
        System.out.println(node.getNodeValue());       
      }
      else {
        // Set up an identity transformer to use as serializer.
        Transformer serializer = TransformerFactory.newInstance().newTransformer();
        serializer.setOutputProperty(OutputKeys.OMIT_XML_DECLARATION, "yes");
        serializer.transform(new DOMSource(node), new StreamResult(new OutputStreamWriter(System.out)));
      }        
       
    }
    
    static void printNodeList(NodeList nodelist) 
      throws Exception
    {
      Node n;
      
      // Set up an identity transformer to use as serializer.
      Transformer serializer = TransformerFactory.newInstance().newTransformer();
      serializer.setOutputProperty(OutputKeys.OMIT_XML_DECLARATION, "yes");
      
      for (int i = 0; i < nodelist.getLength(); i++)
      {         
	n = nodelist.item(i);
	if (isTextNode(n)) {
	    // DOM may have more than one node corresponding to a 
	    // single XPath text node.  Coalesce all contiguous text nodes
	    // at this level
	    StringBuffer sb = new StringBuffer(n.getNodeValue());
	    for (
	      Node nn = n.getNextSibling(); 
	      isTextNode(nn);
	      nn = nn.getNextSibling()
	    ) {
	      sb.append(nn.getNodeValue());
	    }
	    System.out.print(sb);
	}
	else {
         serializer.transform(new DOMSource(n), new StreamResult(new OutputStreamWriter(System.out)));
	}
        System.out.println();
      }
    }
}
