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 deleteDocument
{
    
    private static String theContainer = "namespaceExampleData.dbxml";
    private static void usage()
    {
         String usageMessage = "\nThis program deletes an XML document from a DBXML container.\n";
                usageMessage += "You should run exampleLoadContainer before running this example.\n";
                usageMessage += "You are only required to pass this command the path location of the\n";
                usageMessage += "database environment that you specified when you loaded the examples data:\n\n";

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

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

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

    //Method that deletes all documents from a DB XML container that match a given
    // XPath query.
    private static void doDeleteDocument( XmlContainer container, String XPath, 
                                          XmlQueryContext context, DbTxn txn ) throws Throwable
    {
         System.out.println("Deleting documents for expression: '" + XPath + "'.");
         System.out.println("Return to continue: ");
         System.in.read();

         //Perform our query. We'll delete any document contained in this result set.
         XmlResults results = container.queryWithXPath(txn, XPath, context, 0);
         System.out.println("Found " + results.size() + " matching the expression '" + XPath + "'.");

         XmlDocument document = new XmlDocument();
         while (results.next(document)){
             //Obtain a unique feature off the document for reporting purposes
             String item = getValue(document, "/*/product/text()", context);
             System.out.println("Deleting document: " + item + ".");
             //Peform the delete
	     //             container.deleteDocument( txn, document, null, 0 );
             container.deleteDocument( txn, 42, null, 0 );
             System.out.println("Deleted document: " + item + ".");
         }
      
    }

    //Utility method that we use to obtain a specific value off of a XML document
    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 the result set size is something else, 
        // then either the XML schema isn't what we expected or we got the XPath query
        // expression wrong.
        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);
    }

    //Utility method that we use to make sure the documents that we thought were deleted from the container
    // are in fact deleted. 
    private static void confirmDelete( XmlContainer container, String XPath, XmlQueryContext context ) throws Throwable
    {
       System.out.println("Confirming the delete.");
       System.out.println("The query: '" + XPath + "' should return result set size 0.");
       XmlResults results = container.queryWithXPath(null, XPath, context, 0);
       if ( results.size() == 0) {
            System.out.println("Result set size is 0. Deletion confirmed.");
       } else {
            System.out.println("Result set size is " + results.size() + ". Deletion failed.");
       }
    }

 
    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;
       DbTxn txn = null;
       try
       {
            //Get a database environment
            theDBEnv = new myDbEnv(path2DbEnv);
            //Open a container in that environment
            openedContainer = new myXmlContainer(theContainer, theDBEnv);

            //Get a transaction
            txn = theDBEnv.getDbEnv().txnBegin(null, 0);

            //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");

            //Delete the document that describes Mabolo (a fruit)
            String query = "/fruits:item[product = 'Mabolo']";

            //If doDeleteDocument throws an exception we want to abort the transaction.
            // Otherwise, we want to commit the transaction and continue with other
            // activities. 
            try {
                doDeleteDocument(openedContainer.getContainer(), query, context, txn);
            } catch (Exception e)
            {
               // The database is left in the same state as it was in before
               // we started this operation.
               txn.abort();
               throw e;
            }

            //Commit the writes. This causes the container write operations
            //  to be saved to the container.
            txn.commit(0);

            //The document should now no longer exist in the container. Just for fun,
            //  confirm the delete.
            confirmDelete (openedContainer.getContainer(), query, context);

       } catch (Exception e) {

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

       } finally {
           //Closes the container if it exists.
           if (openedContainer != null) {
              openedContainer.cleanup();
           }

           //Closes the environment if it exists.
           if (theDBEnv != null) {
              theDBEnv.cleanup();
           }
       }

    } //End main

}
