package com.sleepycat.dbxml.examples.gettingStarted;

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

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

class exampleLoadContainer 
{

  private static void usage()
  {
        String usageMessage = "\nThis program loads the examples XML data into the examples container.\n";
               usageMessage += "Provide the directory where you want to place your database environment, \n";
               usageMessage += "and the path to the xmlData directory (this exists in your DB XML examples\n";
               usageMessage += "directory).\n\n";

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

               usageMessage += "For example:\n";
               usageMessage += "\tjava com.sleepycat.dbxml.examples.gettingStarted.exampleLoadContainer -h examplesEnvironment -p /home/user1/dbxml-1.1.0/examples/xmlData\n";

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

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

     File path2DbEnv = null;
     File filePath = 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;
                  case 'p':
                    filePath = new File(args[++i]);
                    break;
                  default:
                    usage();
                }
            } 
      }


     if (path2DbEnv == null || filePath == null) {
        usage();
     }

     if (! filePath.isDirectory()) {
        usage();
     }

     //This vector will hold a File object for each XML file that we will load
     // into the examples container
     Vector files2add = new Vector();

     //Within .../examples/xmlData there should be two subdirectories, nsData and simpleData.
     // These contain the XML files that we want to load. So check to make sure they exist.
     File nsData = new File(filePath.getPath() + File.separator + "nsData");
     confirmDirectory(nsData);

     File simpleData = new File(filePath.getPath() + File.separator + "simpleData");
     confirmDirectory(simpleData);

     //Load the first set of examples xml files into our vector
     getXmlFiles(nsData, files2add);
     //Add these files to the namespace container.
     loadXmlFiles(path2DbEnv, "namespaceExampleData.dbxml", files2add);

     //Repeat for the XML example data that does not use namespaces
     getXmlFiles(simpleData, files2add);
     loadXmlFiles(path2DbEnv, "simpleExampleData.dbxml", files2add);

   } // End method main()

   
   //Convienance method used to make sure -p points to a directory that exists
   private static void confirmDirectory(File directory)
   {
     if ( ! directory.isDirectory() ) {
         System.out.println( "\nError. Directory " + directory.getPath() + " does not exist.");
         System.out.println( "       -p must point to the xmlData directory.");
         usage();
     } 
   }


   //Find all the xml files in a specified directory and store them in a vector
   private static void getXmlFiles(File filePath, Vector files2add)
   {
     boolean filesFound = false;
     String [] dirContents = filePath.list();
     if (dirContents != null) {
          for (int i = 0; i < dirContents.length; i++) {
             File entry = new File(filePath + File.separator + dirContents[i]);
             if (entry.isFile() && entry.toString().toLowerCase().endsWith(".xml")) {
               files2add.addElement(entry);
               filesFound = true;
             }
          }
     }

     if (! filesFound) {
         System.out.println("\nError: No XML files found at " + filePath.getPath());
         usage();
     }

   }


   //Take a vector of Files and load each element into a DB XML container
   private static void loadXmlFiles(File path2DbEnv, String theContainer, Vector files2add) throws Throwable
   {
     //Open a container in the db environment
     myDbEnv theDBEnv = null;
     myXmlContainer openedContainer = null;
     DbTxn txn = null;
     try
     {
       theDBEnv = new myDbEnv(path2DbEnv);
       openedContainer = new myXmlContainer(theContainer, theDBEnv);

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

       Iterator filesIterator = files2add.iterator();
       while(filesIterator.hasNext()) {
         File file = (File) filesIterator.next();
         String theFile = file.toString();

         //Load the contents of the XML file into a String
         String theLine = null;
         String xmlString = new String();
         FileInputStream fis = new FileInputStream(theFile);
         BufferedReader br = new BufferedReader(new InputStreamReader(fis));
         while((theLine=br.readLine()) != null) {
            xmlString += theLine;
            xmlString += "\n"; 
         }
         br.close();

         //Declare an xml document 
         XmlDocument xmlDoc = new XmlDocument();
         //Set the xml document's content to be the xmlString we just obtained.
         xmlDoc.setContent(xmlString);

         //Set the document name
         xmlDoc.setName(file.getName());

         Date theDate = new Date();
         xmlDoc.setMetaData(mdConst.uri, mdConst.prefix, mdConst.name, new XmlValue(theDate.toString()));


         //Place that document into the container */
         openedContainer.getContainer().putDocument(txn, xmlDoc, null, 0);
         System.out.println("Added " + theFile + " to container" + theContainer);
       }
       txn.commit( 0 );


     //XmlException extends DbException, which in turn extends Exception.
     //  Catching Exception catches them all.
     } catch (Exception e) {

       System.err.println("Error loading files into 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 class exampleLoadData
