
/*
 * dbXML License, Version 1.0
 *
 *
 * Copyright (c) 1999-2001 The dbXML Group, L.L.C.
 * All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 *
 * 1. Redistributions of source code must retain the above copyright
 *    notice, this list of conditions and the following disclaimer.
 *
 * 2. Redistributions in binary form must reproduce the above copyright
 *    notice, this list of conditions and the following disclaimer in
 *    the documentation and/or other materials provided with the
 *    distribution.
 *
 * 3. The end-user documentation included with the redistribution,
 *    if any, must include the following acknowledgment:
 *       "This product includes software developed by
 *        The dbXML Group (http://www.dbxml.com/)."
 *    Alternately, this acknowledgment may appear in the software
 *    itself, if and wherever such third-party acknowledgments normally
 *    appear.
 *
 * 4. The names "dbXML" and "The dbXML Group" must not be used to
 *    endorse or promote products derived from this software without
 *    prior written permission. For written permission, please contact
 *    info@dbxml.com.
 *
 * 5. Products derived from this software may not be called "dbXML",
 *    nor may "dbXML" appear in their name, without prior written
 *    permission of The dbXML Group.
 *
 * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
 * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
 * DISCLAIMED.  IN NO EVENT SHALL THE DBXML GROUP OR ITS CONTRIBUTORS
 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY,
 * OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT
 * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
 * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
 * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
 * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 *
 * $Id: CollectionManagerTest.java,v 1.6 2001/08/15 20:06:48 tom Exp $
 */
 
import java.io.*;

import junit.framework.*;

import org.xmldb.api.*;
import org.xmldb.api.base.*;
import org.xmldb.api.modules.*;
import org.dbxml.core.corba.db.EncodedBuffer;

import org.dbxml.core.corba.db.*;
import org.dbxml.core.corba.db.Collection;

import org.dbxml.xml.dom.*;
import org.w3c.dom.*;


public class CollectionManagerTest extends CorbaAPITestCase {
   
   private boolean exceptioncaught = false ;
   
   public CollectionManagerTest(String name) {
      super(name);
   }

   public static junit.framework.Test suite() {
      System.out.println("In CollectionManagerTest.suite() ");
      return new junit.framework.TestSuite(CollectionManagerTest.class);
   }
   
   public void testGetName() {
      try {
         assertTrue( colman.getName().equals("tests") );
      } catch( Exception e ) {
         fail(e.getMessage() );
      }
   
   }
   
   public void testGetCanonicalName() {
      try {
         assertTrue( colman.getCanonicalName().equals("/db/tests") );
      } catch( Exception e ) {
         fail(e.getMessage() );
      }
   
   }
   
   public void testCreateCollection() {
   
      Collection tempcol = null;
   
      try {
      
         // Name of the valid collection to create
         String newcolname = "testchild";
         // Config XML for valid collection created
         String colconf = "<collection compressed=\"true\" name=\"" + newcolname + "\" >" ;
            colconf = colconf + "<filer class=\"org.dbxml.core.filer.BTreeFiler\" gzip=\"true\"/>" ;
            colconf = colconf + "</collection>" ;
         EncodedBuffer colconfbuf = new EncodedBuffer(-1, EmptyBytes, colconf.getBytes() );
         
         // Create the collection
         tempcol = colman.createCollection(newcolname, colconfbuf);
         
         // Verify that collection created, and that name was set correctly
         assertTrue( tempcol.getName().equals( newcolname ) );

         // Now drop the collection
         colman.dropCollection( newcolname );
                 
         // Attempt to create a collection with an empty configuration
         try {
            exceptioncaught = false;
            String empty = "";
            EncodedBuffer emptybuf = new EncodedBuffer(-1, EmptyBytes, empty.getBytes() );
            tempcol = colman.createCollection("NullConfig", emptybuf );
            
         } catch( APIException e ) {
            exceptioncaught = true;
            assertTrue( e.faultCode == FaultCodes.JAVA_RUNTIME_ERROR );
         } finally {
            assertTrue( exceptioncaught );
         }
         
         // Attempt to create a collection with a malformed configuration
         try {
            exceptioncaught = false;
            
            // Bad configuration file
            String malconf = "<bad config>lkjasf";
            EncodedBuffer malconfbuf = new EncodedBuffer(-1, EmptyBytes, malconf.getBytes() );
            
            // Attempt to create the collection
            tempcol = colman.createCollection("malconf", malconfbuf );
            
         } catch( APIException e ) {
            exceptioncaught = true;
            assertTrue( e.faultCode == FaultCodes.JAVA_RUNTIME_ERROR );
         } finally {
            assertTrue( exceptioncaught );
         }

         // Attempt to create a collection with an invalid configuration, missing name attribute
         try {
            exceptioncaught = false;
            
            // Bad configuration file
            String invalidconf = "<collection>" ;
            invalidconf = invalidconf + "<filer class=\"org.dbxml.core.filer.BTreeFiler\" gzip=\"true\"/>" ;
            invalidconf = invalidconf + "</collection>" ;
            
            EncodedBuffer invalidconfbuf = new EncodedBuffer(-1, EmptyBytes, invalidconf.getBytes() );
            
            // Attempt to create the collection
            tempcol = colman.createCollection("invalid", invalidconfbuf );
            
            // Test that the collection was created by calling getName() on it
            assertTrue( tempcol.getName().equals("invalid") );
            
            colman.dropCollection("invalid");
            
         } catch( APIException e ) {
            exceptioncaught = true;
            assertTrue( e.faultCode == FaultCodes.COL_CANNOT_CREATE );
         } finally {
            assertTrue( exceptioncaught );
         }

         // Attempt to create a collection without a filer attribute, this should be allowed

         exceptioncaught = false;
         
         String nofilerconf = "<collection name=\"nofiler\">" ;
         nofilerconf = nofilerconf + "</collection>" ;
         
         EncodedBuffer nofilerconfbuf = new EncodedBuffer(-1, EmptyBytes, nofilerconf.getBytes() );
         
         // Attempt to create the collection
         tempcol = colman.createCollection("nofiler", nofilerconfbuf );
         
         colman.dropCollection("nofiler");
         
      } catch( Exception e ) {
         e.printStackTrace();
         fail(e.getMessage() );
      } finally {
         // Remove collection added so that we don't break other tests, release recources for tempcol
         tempcol.remove();
      }
   
   }

   public void testDropCollection() {
      Collection tempcol = null;
   
      try {

         // Name of the valid collection to create
         String newcolname = "coltodrop";
         // Config XML for valid collection created
         String colconf = "<collection compressed=\"true\" name=\"" + newcolname + "\">" ;
            colconf = colconf + "<filer class=\"org.dbxml.core.filer.BTreeFiler\" gzip=\"true\"/>" ;
            colconf = colconf + "</collection>" ;
         EncodedBuffer colconfbuf = new EncodedBuffer(-1, EmptyBytes, colconf.getBytes() );
         
         // Create a collection
         tempcol = colman.createCollection(newcolname, colconfbuf);
         // Verify that collection created, and that name was set correctly
         assertTrue( tempcol.getName().equals( newcolname ) );
         
         // Drop the collection
         colman.dropCollection(newcolname);

         // Try dropping the collection we just dropped
         try {
            exceptioncaught = false;
            colman.dropCollection(newcolname);
         } catch( APIException e ) {
            assertTrue( e.faultCode == FaultCodes.COL_COLLECTION_NOT_FOUND );
         }
         
         // Try dropping a collection that doesn't exist
         try {
            exceptioncaught = false;
            colman.dropCollection("boguscollectionname");
         } catch( APIException e ) {
            assertTrue( e.faultCode == FaultCodes.COL_COLLECTION_NOT_FOUND );
         }
         
         // Try dropping a collection with the empty string for a name
         try {
            exceptioncaught = false;
            colman.dropCollection("");
         } catch( APIException e ) {
            assertTrue( e.faultCode == FaultCodes.COL_COLLECTION_NOT_FOUND );
         }
               
      } catch( Exception e ) {
         e.printStackTrace();
         fail(e.getMessage() );
      } finally {
         tempcol.remove();
      }
   
   }

   public void testCreateIndexer() {
      
      try {

         // Try adding a normal index
         try {
         
            String indexconf = "<index class=\"org.dbxml.core.indexer.ValueIndexer\" name=\"goodindex\" pattern=\"goodindex\" />";
            EncodedBuffer indexconfbuf = new EncodedBuffer(-1, EmptyBytes, indexconf.getBytes() );
            colman.createIndexer( indexconfbuf );
                       
         } catch( APIException e ) {
            fail( e.getMessage() );
         }

         // Try re-adding the same index, should thow IDX_DUPLICATE_INDEX
         try {
            exceptioncaught = false ;
            String indexconf = "<index class=\"org.dbxml.core.indexer.ValueIndexer\" name=\"goodindex\" pattern=\"goodindex\" />";
            EncodedBuffer indexconfbuf = new EncodedBuffer(-1, EmptyBytes, indexconf.getBytes() );
            colman.createIndexer( indexconfbuf );
                       
         } catch( APIException e ) {
            exceptioncaught = true ;
            assertTrue( e.faultCode == FaultCodes.IDX_DUPLICATE_INDEX );
         } finally {
            assertTrue( exceptioncaught == true );
         }

         // Try adding an index without a name in the configuration, IDX_CANNOT_CREATE
         try {
            
            exceptioncaught = false;
            String nonameindexconf = "<index class=\"org.dbxml.core.indexer.ValueIndexer\" pattern=\"nonameindex\" />";
            EncodedBuffer nonameindexconfbuf = new EncodedBuffer(-1, EmptyBytes, nonameindexconf.getBytes() );
            colman.createIndexer( nonameindexconfbuf );
            
         } catch( APIException e ) {
            exceptioncaught = true;
            assertTrue( e.faultCode == FaultCodes.IDX_CANNOT_CREATE );
         } finally {
            assertTrue( exceptioncaught == true );
         }
         
         // Try adding an index without a class
         try {
            exceptioncaught = false;
            String noclassindexconf = "<index name=\"noclass\" pattern=\"noclassindex\" />";
            EncodedBuffer noclassindexconfbuf = new EncodedBuffer(-1, EmptyBytes, noclassindexconf.getBytes() );
            colman.createIndexer( noclassindexconfbuf );
            
         } catch( APIException e ) {
            exceptioncaught = true;
            assertTrue( e.faultCode == FaultCodes.IDX_CANNOT_CREATE );
         } finally {
            assertTrue( exceptioncaught == true );
         }
      
      } catch( Exception e ) {
         fail(e.getMessage() );
      }
           
   }

   public void testListIndexers() {
      try {
      
         // Should start out with 0 indexers
         assertTrue( colman.listIndexers().length == 0 );
         
         // Add an 5 indexers, verify that 5 were added, try to retrieve each of them by name
         for( int i = 1 ; i < 6 ; i++ ) {
            String indexname = "index" + i ;
            String indexconf = "<index class=\"org.dbxml.core.indexer.ValueIndexer\" name=\"" + indexname + "\" pattern=\"goodindex\" />";
            EncodedBuffer indexconfbuf = new EncodedBuffer(-1, EmptyBytes, indexconf.getBytes() );
            colman.createIndexer( indexconfbuf );
            
            assertTrue( colman.listIndexers().length == i );
            
            // Since we are not gauranteed the order these are returned in we must loop over each
            boolean found = false;
            for( int x=0 ; x < colman.listIndexers().length ; x++ ) {
               if( colman.listIndexers()[x].equals(indexname) ) {
                  found=true;
               }
            }
            assertTrue( found == true );
         }
         
         // Remove all indexers, verify that none are listed
         String[] colindexes = colman.listIndexers();
         for ( int i=0 ; i < colindexes.length ; i++ ) {
            colman.dropIndexer( colindexes[i] );
         }
         
         assertTrue( colman.listIndexers().length == 0 );
      
      } catch( Exception e ) {
         e.printStackTrace();
         fail(e.getMessage() );
      }
   
   }
   
   public void testdropIndexer() {
      try {
         int numindexes = 5 ;

         // Add an 5 indexers
         for( int i = 1 ; i <= numindexes ; i++ ) {
            String indexname = "index" + i ;
            String indexconf = "<index class=\"org.dbxml.core.indexer.ValueIndexer\" name=\"" + indexname + "\" pattern=\"goodindex\" />";
            EncodedBuffer indexconfbuf = new EncodedBuffer(-1, EmptyBytes, indexconf.getBytes() );
            colman.createIndexer( indexconfbuf );
         }
         
         // Remove each indexer individually, verify the count and that it is deleted
         for( int i = 1 ; i <= numindexes ; i++ ) {
            String indexname = "index" + i ;
            colman.dropIndexer( indexname );
            
            // Verify the index count
            assertTrue( colman.listIndexers().length == (numindexes - i) );
            
            // Loop over each index, making sure that the name is not returned by listIndexers()
            boolean notfound = true;
            for( int x=0 ; x < colman.listIndexers().length ; x++ ) {
               if( colman.listIndexers()[x].equals(indexname) ) {
                  notfound=false;
               }
            }
            assertTrue( notfound );
         }
      
         // Try dropping an index that does not exist
         try {
            exceptioncaught = false;
            colman.dropIndexer("BogusName");
         } catch( APIException e ) {
            exceptioncaught = true;
            assertTrue( e.faultCode == FaultCodes.IDX_INDEX_NOT_FOUND );
         } finally {
            assertTrue( exceptioncaught );
         }
      
      } catch( Exception e ) {
         fail(e.getMessage() );
      }
   }

   public void testCreateXMLObject() {
      try {
      
         // Create a normal XMLObject
         String objectconf = "<xmlobject class=\"org.dbxml.tests.TestXmlObject\" name=\"testxmlobject\"/>";
         EncodedBuffer objectconfbuf = new EncodedBuffer(-1, EmptyBytes, objectconf.getBytes() );
         colman.createXMLObject( objectconfbuf );
      
         // Try re-adding the same XMLObject, should throw OBJ_DUPLICATE_OBJECT
         try {
         
            exceptioncaught = false;
            colman.createXMLObject( objectconfbuf );
            
         } catch( APIException e) {
            exceptioncaught = true;
            assertTrue( e.faultCode == FaultCodes.OBJ_DUPLICATE_OBJECT );
         } finally {
            assertTrue( exceptioncaught );
         }
         
         // Try to add an object with no name in configuration
         try {
         
            // Create an XMLObject w/o name attribute
            String nonameobjectconf = "<xmlobject class=\"org.dbxml.tests.TestXmlObject\" />";
            EncodedBuffer nonameobjectconfbuf = new EncodedBuffer(-1, EmptyBytes, nonameobjectconf.getBytes() );
            colman.createXMLObject( nonameobjectconfbuf );
            
         } catch( APIException e) {
            exceptioncaught = true;
            assertTrue( e.faultCode == FaultCodes.OBJ_CANNOT_CREATE );
         } finally {
            assertTrue( exceptioncaught );
         }

         // Try to add an object with no class in configuration
         try {
         
            // Create an XMLObject w/o class attribute
            String nonameobjectconf = "<xmlobject name=\"noclassxmlobject\"/>";
            EncodedBuffer nonameobjectconfbuf = new EncodedBuffer(-1, EmptyBytes, nonameobjectconf.getBytes() );
            colman.createXMLObject( nonameobjectconfbuf );
            
         } catch( APIException e) {
            exceptioncaught = true;
            assertTrue( e.faultCode == FaultCodes.OBJ_CANNOT_CREATE );
         } finally {
            assertTrue( exceptioncaught );
         }

         // Try to add an object with a blank configuration
         try {
         
            // Create an XMLObject w/o class attribute
            String nonameobjectconf = "";
            EncodedBuffer nonameobjectconfbuf = new EncodedBuffer(-1, EmptyBytes, nonameobjectconf.getBytes() );
            colman.createXMLObject( nonameobjectconfbuf );
            
         } catch( APIException e) {
            exceptioncaught = true;
            assertTrue( e.faultCode == FaultCodes.JAVA_RUNTIME_ERROR );
         } finally {
            assertTrue( exceptioncaught );
         }
      
      } catch( Exception e ) {
         fail(e.getMessage() );
      }
   
   }
   
   public void testListXMLObjects() {
      try {

         int numobjects = 10;
         
         // Verify that we have no XMLObjects
         assertTrue( colman.listXMLObjects().length == 0 );
      
      
         // Create XMLObjects, verify that they were added, try to retrieve each of them by name
         for( int i = 1 ; i < 6 ; i++ ) {
            String objectname = "xmlobject" + i ;
            String objectconf = "<xmlobject class=\"org.dbxml.tests.TestXmlObject\" name=\"" + objectname + "\" />";
            EncodedBuffer objectconfbuf = new EncodedBuffer(-1, EmptyBytes, objectconf.getBytes() );
            colman.createXMLObject( objectconfbuf );

            assertTrue( colman.listXMLObjects().length == i );
            
            // Since we are not gauranteed the order these are returned in we must loop over each
            boolean found = false;
            for( int x=0 ; x < colman.listXMLObjects().length ; x++ ) {
               if( colman.listXMLObjects()[x].equals(objectname) ) {
                  found=true;
               }
            }
            
            assertTrue( found == true );
         }

         // Loop over all XMLObjects in the collection and remove
         String[] colxmlobjects = colman.listXMLObjects();
         for ( int i=0 ; i < colxmlobjects.length ; i++ ) {
            colman.dropXMLObject( colxmlobjects[i] );
         }

         // Verify that no XMLObjects remain
         assertTrue( colman.listXMLObjects().length == 0 );
            
      } catch( Exception e ) {
         fail(e.getMessage() );
      }
   
   }

   public void testDropXMLObject() {
      try {
         
         // Add an XMLObject to drop
         String objectconf = "<xmlobject class=\"org.dbxml.tests.TestXmlObject\" name=\"droptest\" />";
         EncodedBuffer objectconfbuf = new EncodedBuffer(-1, EmptyBytes, objectconf.getBytes() );
         colman.createXMLObject( objectconfbuf );
      
         // Drop the object
         colman.dropXMLObject( "droptest" );
         
         // Try to drop the same object again
         try {
         
            exceptioncaught = false ;
            colman.dropXMLObject( "droptest" );
         
         } catch ( APIException e ) {
            exceptioncaught = true;
            assertTrue( e.faultCode == FaultCodes.OBJ_OBJECT_NOT_FOUND );
         } finally {
            assertTrue( exceptioncaught);
         }

         // Try to drop a non-existent object
         try {
         
            exceptioncaught = false ;
            colman.dropXMLObject( "bogusobject" );
         
         } catch ( APIException e ) {
            exceptioncaught = true;
            assertTrue( e.faultCode == FaultCodes.OBJ_OBJECT_NOT_FOUND );
         } finally {
            assertTrue( exceptioncaught);
         }
         
         // Try to drop with an empty name
         try {
         
            exceptioncaught = false ;
            colman.dropXMLObject( "" );
         
         } catch ( APIException e ) {
            exceptioncaught = true;
            assertTrue( e.faultCode == FaultCodes.OBJ_OBJECT_NOT_FOUND );
         } finally {
            assertTrue( exceptioncaught);
         }
      
      } catch( Exception e ) {
         fail(e.getMessage() );
      }
   
   }
   
}


