/* 
	to compile:

	javac -classpath WEB-INF/lib/dom4j-full.jar XPathContextNodeBug.java

	to run:

	java -classpath WEB-INF/lib/dom4j-full.jar\;. XPathContextNodeBug 'ibis:title'

*/
import java.io.*;
import java.util.*;
import org.dom4j.*;
import org.dom4j.io.*;
// import org.jaxen.*;
// import org.jaxen.dom4j.*;

public class XPathContextNodeBug
{
    public XPathContextNodeBug() {}

    public static void main( String[] args )
	throws Throwable
    {

	String theXML1 =
"<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n"+
"<!DOCTYPE issue SYSTEM \"http://www.cognitiveweb.org/xml/HyperIBIS.dtd\">\n"+
"<issue xmlns=\"http://www.cognitiveweb.org/xml/HyperIBIS.dtd\"\n"+
" xmlns:xlink=\"http://www.w3.org/1999/xlink\"\n"+
" dependency=\"none\"\n"+
" >\n"+
" <title/>\n"+
" <positionRef xlink:href=\"http://myOrg.org/position1\"/>\n"+
"</issue>\n"
;

	String theXML2 =
"<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n"+
"<!DOCTYPE issue SYSTEM \"http://www.cognitiveweb.org/xml/HyperIBIS.dtd\">\n"+
"<ibis:issue xmlns:ibis=\"http://www.cognitiveweb.org/xml/HyperIBIS.dtd\"\n"+
" xmlns:xlink=\"http://www.w3.org/1999/xlink\"\n"+
" ibis:dependency=\"none\"\n"+
" >\n"+
" <ibis:title/>\n"+
" <ibis:positionRef xlink:href=\"http://myOrg.org/position1\"/>\n"+
"</ibis:issue>\n"
;
	XPathContextNodeBug driver = new XPathContextNodeBug();
	
	/* Build a dom4j Document from the container XML. */
	SAXReader reader = new SAXReader();
	Document document = reader.read
	    ( new StringReader
	      ( theXML2
		));
	System.err.println( "Document: ["+document.asXML()+"]" );
	Object obj = document;
	for( int i=0; i<args.length; i++ ) {
	    System.err.println( "----------------------------------------" );
	    if( ! ( obj instanceof Document ) &&
		! ( obj instanceof Node ) ) {
		break;		// done.
	    }
	    String theXPath = args[i];
	    System.err.println( "theXPath = \""+theXPath+"\"" );
	    if( obj instanceof Node ) {
		// Show the context node.
		System.err.println( "context-node: ["+((Node)obj).asXML()+"]"
				    );
	    }
	    obj = driver.test
		( document,
		  obj,
		  theXPath
		  );
	    if( obj == null ) {
		System.err.println( "nothing selected." );
		break;		// done.
	    } else if( obj instanceof Node ) {
		System.err.println( "selected: ["+
				    ((Node)obj).asXML()+"]"
				    );
	    } else if( obj instanceof Document ) {
		System.err.println( "selected: ["+
				    ((Document)obj).asXML()+"]"
				    );
	    } else if( obj instanceof List ) {
		int size = ((List)obj).size();
		System.err.println( "node-set has "+size+" members." );
		int nth = 0;
		Iterator itr = ((List)obj).iterator();
		while( itr.hasNext() ) {
		    Node theNode = (Node)itr.next();
		    System.err.println("node["+(nth++)+"] : ["+
				       theNode.asXML()+"]"
				       );
		}
		if( size > 0 ) {
		    System.err.println( "Will use first member of node set."
					);
		    obj = ((List)obj).get( 0 );
				// get the first member of the list.
		}
	    } else {
		System.err.println( "result is "+obj.getClass().getName() );
		break;
	    }
	}
    }

    /* Evaluate the provided XPath against the context node using the
     * Document to compile the XPath.
     * 
     * @note: The way to perform namespace-aware XPath queries is to
     * provide a prefix to namespace mapping to the XPath engine, then
     * use those prefixes in the query. The prefixes provided do not
     * need to be the same as the namespace to prefix mappings in the
     * target document, and they must be non-empty prefixes.
     */

    public Object test( Document doc, Object obj, String theXPath )
	throws Throwable
    {
	XPath xpath = doc.createXPath( theXPath );
	if( true ) {
	    // set namespace mapping for XPath expression.
	    Map uris = new HashMap();
	    uris.put( "ibis",
		      "http://www.cognitiveweb.org/xml/HyperIBIS.dtd"
		      );
	    uris.put( "xlink",
		      "http://www.w3.org/1999/xlink"
		      );
	    xpath.setNamespaceURIs( uris );
	}
 	return xpath.selectNodes
	    ( obj
	      );
    }
    
}
