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 addIndex
{
    
    private static String theContainer = "namespaceExampleData.dbxml";
    private static void usage()
    {
         String usageMessage = "\nThis program adds several indexes to 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 database\n";
                usageMessage += "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.addIndex -h examplesEnvironment\n";

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

    private static void addIndex( XmlContainer container, String URI, String nodeName,
                                  String indexType, DbTxn txn ) throws Throwable
    {
       System.out.println("Adding index type " + indexType + " to node " + nodeName);

       //Retrieve the index specification from the container
       XmlIndexSpecification idxSpec = container.getIndexSpecification(txn);

       //See what indexes exist on the container
       String uri = new String();
       String name = new String();
       String index = new String();

       int count = 0;
       System.out.println("Before index add.");
       XmlIndexDeclaration idxDecl = null;
       while((idxDecl = (idxSpec.next())) != null) {
           System.out.println("\tFor node '" + idxDecl.name + "', found index: '" + idxDecl.index + "'.");
           count ++;
       }

       System.out.println(count + " indexes found.");

       //Add the index to the specification.
       //If it already exists, then this does nothing.
       idxSpec.addIndex(URI, nodeName, indexType);

       //Set the specification back to the container
       container.setIndexSpecification(txn, idxSpec);

       //Look at the indexes again to make sure our replacement took.
       count = 0;
       idxSpec.reset();
       System.out.println("After index add.");
       while((idxDecl = ( idxSpec.next() ) ) != null) {
           System.out.println("\tFor node '" + idxDecl.name + "', found index: '" + idxDecl.index + "'.");
           count ++;
       }

       System.out.println(count + " indexes found.");
    }


    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);
            //Get open a container.
            openedContainer = new myXmlContainer(theContainer, theDBEnv);

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

            //Add an string equality index for the "product" element node.
            addIndex( openedContainer.getContainer(), "", "product", "node-element-equality-string", txn );
            //Add an edge presence index for the product node
            addIndex( openedContainer.getContainer(), "", "product", "edge-element-presence", txn );

            //Commit the index adds
            txn.commit(0);

       } catch (Exception e) {

          //Both DB XML and Berkeley DB throw exceptions that are inherited from
          // Exception. Therefore, catching Exception catches everything.
          System.err.println("Error adding index to container " + theContainer);
          System.err.println("   Message: " + e.getMessage() );
          //In the event of an error, we abort the operation
          // The database is left in the same state as it was in before
          // we started this operation.
          if ( txn != null ) {
             txn.abort();
          }
          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

}
