package com.sleepycat.dbxml.examples.gettingStarted;

import java.io.*;
import com.sleepycat.dbxml.examples.gettingStarted.myDbEnv;
import com.sleepycat.dbxml.examples.gettingStarted.myXmlContainer;


import com.sleepycat.dbxml.*;
import com.sleepycat.db.*;

class queryForDocumentValue
{
    
    private static String theContainer = "namespaceExampleData.dbxml";
    private static void usage()
    {
         String usageMessage = "\nThis program retrieves DBXML documents and then retrieves information of\n";
                usageMessage += "interest from the retrieved document(s). You should run exampleLoadContainer\n";
                usageMessage += "before running this example. You are only required to pass this command the path\n";
                usageMessage += "location of the database environment that you specified when you loaded the\n";
                usageMessage += "examples data:\n\n";

                usageMessage += "\t-h <dbenv directory>\n";

                usageMessage += "For example:\n";
                usageMessage += "\tjava com.sleepycat.dbxml.examples.gettingStarted.queryForDocumentValue -h examplesEnvironment\n";

         System.out.println(usageMessage);
         System.exit( -1 );
    }

    private static String getValue( XmlDocument theDocument, String XPath, XmlQueryContext context ) throws Throwable
    {
        /////////////////////////////////////////////////////////////////////////////////
        ///////////    Return specific information from a document. ///////////////////// 
        ///////////          Assumes a result set of size 1         /////////////////////
        /////////////////////////////////////////////////////////////////////////////////


        //We don't want a document, we want a specific value. So set the
        //return type to Result Values
        context.setReturnType(XmlQueryContext.ResultValues);

        //Perform the query
        XmlResults result = theDocument.queryWithXPath(XPath, context);

        //We require a result set size of 1.
        if (result.size() != 1) {
              System.err.println("Error! XPath query '" + XPath + "' returned a result size size != 1");
              throw new Exception( "getValue found result set not equal to 1.");
        }

        //Get the value. If we allowed the result set to be larger than size 1,
        // we would have to loop through the results, processing each as is
        // required by our application.
        XmlValue value = result.next();

        //Set the result type back to Result Document
        context.setReturnType(XmlQueryContext.ResultDocuments);
        return value.asString(null);
    }

    private static void getDetails(XmlContainer container, String XPath, XmlQueryContext context) throws Throwable
    {
       //Perform a single query against the referenced container using
       // the referenced context.
       System.out.println("Exercising query: '" + XPath + "'.");
       System.out.println("Return to continue: ");
       System.in.read();

       //Perform the query
       XmlResults results = container.queryWithXPath(null, XPath, context, 0);

       //We're going to iterate over the results using an XmlDocument
       XmlDocument document = new XmlDocument();

       System.out.println("\n\tProduct : Price : Inventory Level\n");

       while (results.next(document)) {
            //Obtain information of interest from the document. Note that the 
            //  wildcard in the XPath expression allows us to not worry about what
            //  namespace this document uses.
            String item = getValue(document, "/*/product/text()", context);
            String price = getValue(document, "/*/inventory/price/text()", context);
            String inventory = getValue(document, "/*/inventory/inventory/text()", context);

            System.out.println("\t" + item + " : " + price + " : " + inventory);
       }
       System.out.println(results.size() + " results returned for query '" + XPath + "'.");
    }


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

       File path2DbEnv = null;

       for(int i = 0; i < args.length; ++i) {
            if (args[i].startsWith("-")) {
               switch(args[i].charAt(1)) {
                    case 'h':
                         path2DbEnv = new File(args[++i]);
                         break;
                    default:
                    usage();
               }
            } 
       }


       if (path2DbEnv == null || ! path2DbEnv.isDirectory()) {
            usage();
       }


       myDbEnv theDBEnv = null;
       myXmlContainer openedContainer = null;
       try
       {
            //Open the database environment
            theDBEnv = new myDbEnv(path2DbEnv);
            //Open a container in that environment
            openedContainer = new myXmlContainer(theContainer, theDBEnv);

            //Create a context and declare the namespaces
            XmlQueryContext context = new XmlQueryContext(XmlQueryContext.ResultDocuments, XmlQueryContext.Eager);
            context.setNamespace("fruits", "http://groceryItem.dbxml/fruits");
            context.setNamespace("vegetables", "http://groceryItem.dbxml/vegetables");
            context.setNamespace("desserts", "http://groceryItem.dbxml/desserts");


            //Get details on Zulu Nuts
            getDetails(openedContainer.getContainer(), "/fruits:item/product[text() = 'Zulu Nut']", context);

            //Get details on all fruits that start with 'A'
            getDetails(openedContainer.getContainer(), "/vegetables:item/product[starts-with(text(),'A')]", context);

       } catch (Exception e) {

            System.err.println("Error performing query against " + theContainer);
            System.err.println("   Message: " + e.getMessage());
            throw e;

       } finally {
            if (openedContainer != null) {
               openedContainer.cleanup();
            }
    
            if (theDBEnv != null) {
               theDBEnv.cleanup();
            }
       }

    } //End main

}
