kevinross    2003/07/14 12:07:16

  Modified:    java/src/org/apache/xindice/util Configurable.java
                        XindiceRuntimeException.java XindiceException.java
                        ConfigurationException.java
               java/src/org/apache/xindice/core DBObject.java
                        MetaSystemCollection.java DBObserver.java
                        FaultCodes.java DocumentCache.java DBException.java
                        Container.java Database.java Collection.java
                        SystemCollection.java CollectionManager.java
               java/src/org/apache/xindice/client/xmldb/embed
                        DatabaseImpl.java
  Log:
  refactoring for javabeans coding conventions including:
  -naming
  -accessibility of members.
  -javadoc comments
  
  
  Revision  Changes    Path
  1.3       +15 -17    
xml-xindice/java/src/org/apache/xindice/util/Configurable.java
  
  Index: Configurable.java
  ===================================================================
  RCS file: 
/home/cvs/xml-xindice/java/src/org/apache/xindice/util/Configurable.java,v
  retrieving revision 1.2
  retrieving revision 1.3
  diff -u -r1.2 -r1.3
  --- Configurable.java 31 Oct 2002 07:01:45 -0000      1.2
  +++ Configurable.java 14 Jul 2003 19:07:14 -0000      1.3
  @@ -59,8 +59,6 @@
    * $Id$
    */
   
  -
  -
   /**
    * Configurable is a simple interface used to pass configuration information
    * to an object.  The implementing object is ultimately responsible for
  @@ -77,19 +75,19 @@
    */
   
   public interface Configurable {
  -   /**
  -    * setConfig sets the configuration information for the Configurable
  -    * object instance.
  -    *
  -    * @param config The configuration Node
  -    */
  -   void setConfig(Configuration config) throws XindiceException;
  +    /**
  +     * setConfig sets the configuration information for the Configurable
  +     * object instance.
  +     *
  +     * @param config The configuration Node
  +     */
  +    void setConfig(Configuration config) throws XindiceException;
   
  -   /**
  -    * getConfig retrieves the configuration information for the
  -    * Configurable object instance.
  -    *
  -    * @return The configuration Node
  -    */
  -   Configuration getConfig();
  +    /**
  +     * getConfig retrieves the configuration information for the
  +     * Configurable object instance.
  +     *
  +     * @return The configuration Node
  +     */
  +    Configuration getConfig();
   }
  
  
  
  1.2       +6 -1      
xml-xindice/java/src/org/apache/xindice/util/XindiceRuntimeException.java
  
  Index: XindiceRuntimeException.java
  ===================================================================
  RCS file: 
/home/cvs/xml-xindice/java/src/org/apache/xindice/util/XindiceRuntimeException.java,v
  retrieving revision 1.1
  retrieving revision 1.2
  diff -u -r1.1 -r1.2
  --- XindiceRuntimeException.java      14 Jul 2003 18:28:45 -0000      1.1
  +++ XindiceRuntimeException.java      14 Jul 2003 19:07:14 -0000      1.2
  @@ -74,6 +74,11 @@
                super(message);
        }
   
  +     public XindiceRuntimeException(Throwable cause) {
  +             super();
  +             this.cause = cause;
  +     }
  +
        public XindiceRuntimeException(String message, Throwable cause) {
                super(message);
                this.cause = cause;
  
  
  
  1.6       +7 -2      
xml-xindice/java/src/org/apache/xindice/util/XindiceException.java
  
  Index: XindiceException.java
  ===================================================================
  RCS file: 
/home/cvs/xml-xindice/java/src/org/apache/xindice/util/XindiceException.java,v
  retrieving revision 1.5
  retrieving revision 1.6
  diff -u -r1.5 -r1.6
  --- XindiceException.java     14 Jul 2003 18:28:45 -0000      1.5
  +++ XindiceException.java     14 Jul 2003 19:07:14 -0000      1.6
  @@ -74,7 +74,12 @@
        public XindiceException(String message) {
                super(message);
        }
  -
  +     
  +     public XindiceException(Throwable cause) {
  +             super();
  +             this.cause = cause;
  +     }
  +     
        public XindiceException(String message, Throwable cause) {
                super(message);
                this.cause = cause;
  
  
  
  1.2       +4 -0      
xml-xindice/java/src/org/apache/xindice/util/ConfigurationException.java
  
  Index: ConfigurationException.java
  ===================================================================
  RCS file: 
/home/cvs/xml-xindice/java/src/org/apache/xindice/util/ConfigurationException.java,v
  retrieving revision 1.1
  retrieving revision 1.2
  diff -u -r1.1 -r1.2
  --- ConfigurationException.java       14 Jul 2003 18:28:45 -0000      1.1
  +++ ConfigurationException.java       14 Jul 2003 19:07:14 -0000      1.2
  @@ -26,4 +26,8 @@
        public ConfigurationException(String message, Throwable cause) {
                super(message, cause);
        }
  +     
  +     public ConfigurationException(Throwable cause) {
  +             super(cause);
  +     }       
   }
  
  
  
  1.3       +48 -50    
xml-xindice/java/src/org/apache/xindice/core/DBObject.java
  
  Index: DBObject.java
  ===================================================================
  RCS file: 
/home/cvs/xml-xindice/java/src/org/apache/xindice/core/DBObject.java,v
  retrieving revision 1.2
  retrieving revision 1.3
  diff -u -r1.2 -r1.3
  --- DBObject.java     31 Oct 2002 06:59:56 -0000      1.2
  +++ DBObject.java     14 Jul 2003 19:07:14 -0000      1.3
  @@ -59,8 +59,6 @@
    * $Id$
    */
   
  -
  -
   /**
    * DBObject is the interface implemented by all Xindice database objects.
    * DBObjects are typically objects that can be managed using XML
  @@ -71,51 +69,51 @@
    */
   
   public interface DBObject {
  -   /**
  -    * create creates a new DBObject and any associated resources for the new
  -    * DBObject, such as disk files, etc.
  -    *
  -    * @return Whether or not the DBObject was created
  -    */
  -   boolean create() throws DBException;
  -
  -   /**
  -    * open opens the DBObject
  -    *
  -    * @return Whether or not the DBObject was opened
  -    */
  -   boolean open() throws DBException;
  -
  -   /**
  -    * isOpened returns whether or not the DBObject is opened for business.
  -    *
  -    * @return The open status of the DBObject
  -    */
  -   boolean isOpened() throws DBException;
  -
  -   /**
  -    * exists returns whether or not a physical representation of this
  -    * DBObject actually exists.  In the case of a HashFiler, this would
  -    * check for the file, and in the case of an FTPFiler, it might
  -    * perform a connection check.
  -    *
  -    * @return Whether or not the physical resource exists
  -    */
  -   boolean exists() throws DBException;
  -
  -   /**
  -    * drop instructs the DBObjectimplementation to remove itself from
  -    * existence.  The DBObject's parent is responsible for removing any
  -    * references to the DBObject in its own context.
  -    *
  -    * @return Whether or not the DBObject was dropped
  -    */
  -   boolean drop() throws DBException;
  -
  -   /**
  -    * close closes the DBObject
  -    *
  -    * @return Whether or not the DBObject was closed
  -    */
  -   boolean close() throws DBException;
  +    /**
  +     * create creates a new DBObject and any associated resources for the new
  +     * DBObject, such as disk files, etc.
  +     *
  +     * @return Whether or not the DBObject was created
  +     */
  +    boolean create() throws DBException;
  +
  +    /**
  +     * open opens the DBObject
  +     *
  +     * @return Whether or not the DBObject was opened
  +     */
  +    boolean open() throws DBException;
  +
  +    /**
  +     * isOpened returns whether or not the DBObject is opened for business.
  +     *
  +     * @return The open status of the DBObject
  +     */
  +    boolean isOpened() throws DBException;
  +
  +    /**
  +     * exists returns whether or not a physical representation of this
  +     * DBObject actually exists.  In the case of a HashFiler, this would
  +     * check for the file, and in the case of an FTPFiler, it might
  +     * perform a connection check.
  +     *
  +     * @return Whether or not the physical resource exists
  +     */
  +    boolean exists() throws DBException;
  +
  +    /**
  +     * drop instructs the DBObjectimplementation to remove itself from
  +     * existence.  The DBObject's parent is responsible for removing any
  +     * references to the DBObject in its own context.
  +     *
  +     * @return Whether or not the DBObject was dropped
  +     */
  +    boolean drop() throws DBException;
  +
  +    /**
  +     * close closes the DBObject
  +     *
  +     * @return Whether or not the DBObject was closed
  +     */
  +    boolean close() throws DBException;
   }
  
  
  
  1.3       +61 -96    
xml-xindice/java/src/org/apache/xindice/core/MetaSystemCollection.java
  
  Index: MetaSystemCollection.java
  ===================================================================
  RCS file: 
/home/cvs/xml-xindice/java/src/org/apache/xindice/core/MetaSystemCollection.java,v
  retrieving revision 1.2
  retrieving revision 1.3
  diff -u -r1.2 -r1.3
  --- MetaSystemCollection.java 27 Mar 2003 07:05:32 -0000      1.2
  +++ MetaSystemCollection.java 14 Jul 2003 19:07:14 -0000      1.3
  @@ -59,7 +59,6 @@
    * $Id$
    */
   
  -
   import java.util.StringTokenizer;
   
   import org.apache.commons.logging.Log;
  @@ -69,52 +68,48 @@
   import org.apache.xindice.xml.dom.DOMParser;
   import org.w3c.dom.Document;
   
  -
  -
   /**
    * MetaSystemCollection represents the Meta System Collection.  Beyond
    * standard Collection operations, this class will provide facilities
    * for Meta data management.
    */
  -public final class MetaSystemCollection extends Collection
  -{
  -    public static final String METACOL      = "meta";
  -    public static final String METAS        = "Metas";
  +public final class MetaSystemCollection extends Collection {
  +    public static final String METACOL = "meta";
  +    public static final String METAS = "Metas";
       public static final String COLLECTION_META_DATA = "_META_DATA_";
   
       private String dbCanonicalName;
       private String metaCanonicalName;
  -     private static Log log = LogFactory.getLog("org.apache.xindice.core");
  +    private static Log log = LogFactory.getLog("org.apache.xindice.core");
   
  -    public MetaSystemCollection(Database db)
  -    {
  +    public MetaSystemCollection(Database db) {
           super(db);
       }
   
  -    public void init() throws DBException
  -    {
  +    public void init() throws DBException {
           // Bootstrap the System Collection
   
  -        String MetaCol =
  -         "<collection name=\""+METACOL+"\">"
  -         // Meta System Collections
  -       + "   <collections>"
  -         // Meta Collections
  -       + "      <collection name=\""+METAS+"\" compressed=\"true\">"
  -       + "         <filer class=\"org.apache.xindice.core.filer.BTreeFiler\" 
/>"
  -       + "      </collection>"
  -
  -       + "   </collections>"
  -       + "</collection>";
  +        String MetaCol = 
  +             "<collection name=\"" + METACOL + "\">"
  +            // Meta System Collections
  +     +"   <collections>"
  +            // Meta Collections
  +     +"      <collection name=\""
  +        + METAS
  +        + "\" compressed=\"true\">"
  +        + "         <filer 
class=\"org.apache.xindice.core.filer.BTreeFiler\" />"
  +        + "      </collection>"
  +        + "   </collections>"
  +        + "</collection>";
   
           try {
               Document metaDoc = DOMParser.toDocument(MetaCol);
               Configuration metaCfg = new Configuration(metaDoc, false);
               setConfig(metaCfg);
           }
  -        catch ( Exception e ) {
  -                     if (log.isFatalEnabled()) {
  -                log.fatal("FATAL ERROR: Generating System Collection 
'"+METACOL+"'", e);
  +        catch (Exception e) {
  +            if (log.isFatalEnabled()) {
  +                log.fatal("FATAL ERROR: Generating System Collection '" + 
METACOL + "'", e);
               }
               System.exit(1);
           }
  @@ -127,58 +122,47 @@
       /**
        * Returns the corresponding Meta Collection for the given
        * collection, optionally creating the hierarchy
  -      *
  -      * @param collection the collection whose meta you want
  -      * @param create whether or not to create the meta if its missing
  -      * @return collection the meta collection for the requested collection
  +     *
  +     * @param collection the collection whose meta you want
  +     * @param create whether or not to create the meta if its missing
  +     * @return collection the meta collection for the requested collection
        */
  -    public Collection getMetaCollection(Collection collection,
  -        boolean create)
  -    throws DBException
  -    {
  +    public Collection getMetaCollection(Collection collection, boolean 
create) throws DBException {
           String path = collection.getCanonicalName();
   
           // different database
  -        if( !path.startsWith(dbCanonicalName) )
  +        if (!path.startsWith(dbCanonicalName))
               return null;
   
           // this is a meta collection
  -        if( path.startsWith(metaCanonicalName) )
  +        if (path.startsWith(metaCanonicalName))
               return null;
   
           Collection current = getCollection(METAS);
  -        StringTokenizer st = new StringTokenizer(
  -            path.substring(dbCanonicalName.length()), "/");
  +        StringTokenizer st = new 
StringTokenizer(path.substring(dbCanonicalName.length()), "/");
   
  -        while( current != null && st.hasMoreTokens() )
  -        {
  +        while (current != null && st.hasMoreTokens()) {
               String segment = st.nextToken().trim();
  -            if ( segment.length() == 0 )
  -               continue;
  +            if (segment.length() == 0)
  +                continue;
   
               Collection childcol = current.getCollection(segment);
  -            if( null == childcol )
  -            {
  -                if( !create )
  +            if (null == childcol) {
  +                if (!create)
                       return null;
   
                   String cfgText =
  -                "<collection name=\""+segment+"\" compressed=\"true\">" +
  -                "  <filer class=\"org.apache.xindice.core.filer.BTreeFiler\" 
/>" +
  -                "</collection>";
  +                    "<collection name=\"" + segment + "\" 
compressed=\"true\">" + "  <filer 
class=\"org.apache.xindice.core.filer.BTreeFiler\" />" + "</collection>";
   
  -                try
  -                {
  +                try {
                       Document cfgDoc = DOMParser.toDocument(cfgText);
                       Configuration cfg = new Configuration(cfgDoc, false);
                       childcol = current.createCollection(segment, cfg);
                   }
  -                catch( DBException de )
  -                {
  +                catch (DBException de) {
                       throw de;
                   }
  -                catch( Exception e )
  -                {
  +                catch (Exception e) {
                       throw new DBException(FaultCodes.getFaultCode(e));
                   }
               }
  @@ -194,16 +178,13 @@
        *
        * @param collection The Collection whose meta is required
        */
  -    public void dropCollectionMeta(Collection collection)
  -    throws DBException
  -    {
  +    public void dropCollectionMeta(Collection collection) throws DBException 
{
           Collection mcol = getMetaCollection(collection, false);
  -        if( null != mcol )
  -        {
  +        if (null != mcol) {
               try {
                   mcol.drop();
               }
  -            catch( DBException e ) {
  +            catch (DBException e) {
                   // fail silently
               }
           }
  @@ -217,18 +198,15 @@
        * @param collection The Collection whose meta is required
        * @return The requested MetaData
        */
  -    public MetaData getCollectionMeta(Collection collection)
  -    throws DBException
  -    {
  +    public MetaData getCollectionMeta(Collection collection) throws 
DBException {
           Collection mcol = getMetaCollection(collection, true);
   
  -        if( null != mcol )
  -        {
  -            MetaData meta = (MetaData)mcol.getObject(COLLECTION_META_DATA);
  -            if ( meta == null )
  +        if (null != mcol) {
  +            MetaData meta = (MetaData) mcol.getObject(COLLECTION_META_DATA);
  +            if (meta == null)
                   meta = new MetaData();
   
  -            if( meta.getType() == MetaData.UNKNOWN )
  +            if (meta.getType() == MetaData.UNKNOWN)
                   meta.setType(MetaData.COLLECTION);
               meta.setOwner(collection.getCanonicalName());
               meta.setDirty(false);
  @@ -243,15 +221,12 @@
        * @param collection The Collection that owns the MetaData
        * @param meta The MetaData
        */
  -    public void setCollectionMeta(Collection collection, MetaData meta)
  -    throws DBException
  -    {
  -        if( null == meta )
  +    public void setCollectionMeta(Collection collection, MetaData meta) 
throws DBException {
  +        if (null == meta)
               return;
   
           Collection mcol = getMetaCollection(collection, true);
  -        if( null != mcol )
  -        {
  +        if (null != mcol) {
               mcol.setObject(COLLECTION_META_DATA, meta);
               meta.setDirty(false);
           }
  @@ -264,16 +239,13 @@
        * @param collection The Collection whose meta is required
        * @param id the Document id
        */
  -    public void dropDocumentMeta(Collection collection, String id)
  -    throws DBException
  -    {
  +    public void dropDocumentMeta(Collection collection, String id) throws 
DBException {
           Collection mcol = getMetaCollection(collection, false);
  -        if( null != mcol )
  -        {
  +        if (null != mcol) {
               try {
                   mcol.remove(id);
               }
  -            catch( DBException e ) {
  +            catch (DBException e) {
                   // fail silently
               }
           }
  @@ -287,17 +259,14 @@
        * @param id the ID
        * @return The requested MetaData
        */
  -    public MetaData getDocumentMeta(Collection collection, String id)
  -    throws DBException
  -    {
  +    public MetaData getDocumentMeta(Collection collection, String id) throws 
DBException {
           Collection mcol = getMetaCollection(collection, true);
  -        if( null != mcol )
  -        {
  -            MetaData meta = (MetaData)mcol.getObject(id);
  -            if ( meta == null )
  +        if (null != mcol) {
  +            MetaData meta = (MetaData) mcol.getObject(id);
  +            if (meta == null)
                   meta = new MetaData();
   
  -            if( meta.getType() == MetaData.UNKNOWN )
  +            if (meta.getType() == MetaData.UNKNOWN)
                   meta.setType(MetaData.DOCUMENT);
               meta.setOwner(collection.getCanonicalName() + "/" + id);
               meta.setDirty(false);
  @@ -313,18 +282,14 @@
        * @param id
        * @param meta The MetaData
        */
  -    public void setDocumentMeta(Collection collection, String id, MetaData 
meta)
  -    throws DBException
  -    {
  -        if( null == meta )
  +    public void setDocumentMeta(Collection collection, String id, MetaData 
meta) throws DBException {
  +        if (null == meta)
               return;
   
           Collection mcol = getMetaCollection(collection, true);
  -        if( null != mcol )
  -        {
  +        if (null != mcol) {
               mcol.setObject(id, meta);
               meta.setDirty(false);
           }
       }
   }
  -
  
  
  
  1.4       +38 -63    
xml-xindice/java/src/org/apache/xindice/core/DBObserver.java
  
  Index: DBObserver.java
  ===================================================================
  RCS file: 
/home/cvs/xml-xindice/java/src/org/apache/xindice/core/DBObserver.java,v
  retrieving revision 1.3
  retrieving revision 1.4
  diff -u -r1.3 -r1.4
  --- DBObserver.java   14 Jul 2003 17:23:56 -0000      1.3
  +++ DBObserver.java   14 Jul 2003 19:07:14 -0000      1.4
  @@ -1,114 +1,89 @@
   package org.apache.xindice.core;
   
  +import java.util.Map;
  +
   import org.apache.xindice.core.data.Key;
   import org.apache.xindice.core.data.Record;
   import org.apache.xindice.util.Configuration;
  -
  -import org.w3c.dom.*;
  -
  -import java.util.Map;
  +import org.w3c.dom.Document;
   
   /**
    * Observer for Xindice DB activities
    */
  -public abstract class DBObserver
  -{
  -    private static final DBObserver NOOP = new DBObserver()
  -    {
  -        public void setDatabaseConfig( 
  -        Database db, Map collections, Configuration cfg ) {}
  +public abstract class DBObserver {
  +    
  +    private static final DBObserver NOOP = new DBObserver() {
  +        public void setDatabaseConfig(Database db, Map collections, 
Configuration cfg) {}
   
  -        public void setCollectionConfig( 
  -        Collection col, Configuration cfg ) {}
  +        public void setCollectionConfig(Collection col, Configuration cfg) {}
   
  -        public void flushDatabaseConfig( 
  -        Database db, Configuration cfg ) {}
  -    
  -        public void dropCollection( Collection col ) 
  -        throws DBException {}
  +        public void flushDatabaseConfig(Database db, Configuration cfg) {}
  +
  +        public void dropCollection(Collection col) throws DBException {}
  +
  +        public void createCollection(Collection col) throws DBException {}
   
  -        public void createCollection( Collection col ) 
  -        throws DBException {}
  +        public void putDocument(Collection col, Key key, Document document, 
boolean create) throws DBException {}
   
  -        public void putDocument( 
  -        Collection col, Key key, Document document, boolean create ) 
  -        throws DBException {}
  -
  -        public void loadDocument( 
  -            Collection col, Record record, Document document ) 
  -        throws DBException {}
  -        
  -        public void dropDocument( Collection col, Key key ) 
  -        throws DBException {}
  +        public void loadDocument(Collection col, Record record, Document 
document) throws DBException {}
  +
  +        public void dropDocument(Collection col, Key key) throws DBException 
{}
       };
   
       private static DBObserver instance = NOOP;
   
       /**
        * Sets the default observer instance
  -     */ 
  -    public static void setInstance( DBObserver obs )
  -    { 
  -        instance = (null == obs) ? NOOP : obs; 
  +     */
  +    public static void setInstance(DBObserver obs) {
  +        instance = (null == obs) ? NOOP : obs;
       }
   
       /**
        * Returns the observer instance, must be non-null
  -     */    
  -    public static DBObserver getInstance()
  -    { 
  -        return instance; 
  +     */
  +    public static DBObserver getInstance() {
  +        return instance;
       }
  -    
  +
       /**
        * Called after Database.setConfig()
  -     */    
  -    public abstract void setDatabaseConfig( 
  -        Database db, Map collections, Configuration cfg );
  +     */
  +    public abstract void setDatabaseConfig(Database db, Map collections, 
Configuration cfg);
   
       /**
        * Called after Collection.setConfig()
  -     */    
  -    public abstract void setCollectionConfig( 
  -        Collection col, Configuration cfg );
  +     */
  +    public abstract void setCollectionConfig(Collection col, Configuration 
cfg);
   
       /**
        * Called after Database.flushConfig()
        */
  -    public abstract void flushDatabaseConfig( 
  -        Database db, Configuration cfg );
  -    
  +    public abstract void flushDatabaseConfig(Database db, Configuration cfg);
  +
       /**
        * Called before Collection.drop()
        */
  -    public abstract void dropCollection( Collection col ) 
  -    throws DBException;
  +    public abstract void dropCollection(Collection col) throws DBException;
   
       /**
        * Called after Collection.create()
        */
  -    public abstract void createCollection( Collection col ) 
  -    throws DBException;
  +    public abstract void createCollection(Collection col) throws DBException;
   
       /**
        * Called after Collection.putDocument()
  -     */    
  -    public abstract void putDocument( 
  -        Collection col, Key key, Document document, boolean create ) 
  -    throws DBException;
  +     */
  +    public abstract void putDocument(Collection col, Key key, Document 
document, boolean create) throws DBException;
   
       /**
        * Called after Collection.getDocument()
  -     */    
  -    public abstract void loadDocument( 
  -        Collection col, Record record, Document document ) 
  -    throws DBException;
  +     */
  +    public abstract void loadDocument(Collection col, Record record, 
Document document) throws DBException;
   
       /**
        * Called before Collection.remove(key)
        */
  -    public abstract void dropDocument( Collection col, Key key ) 
  -    throws DBException;
  -    
  -}
  +    public abstract void dropDocument(Collection col, Key key) throws 
DBException;
   
  +}
  
  
  
  1.11      +253 -253  
xml-xindice/java/src/org/apache/xindice/core/FaultCodes.java
  
  Index: FaultCodes.java
  ===================================================================
  RCS file: 
/home/cvs/xml-xindice/java/src/org/apache/xindice/core/FaultCodes.java,v
  retrieving revision 1.10
  retrieving revision 1.11
  diff -u -r1.10 -r1.11
  --- FaultCodes.java   11 Jun 2003 03:56:47 -0000      1.10
  +++ FaultCodes.java   14 Jul 2003 19:07:14 -0000      1.11
  @@ -71,256 +71,256 @@
    */
   
   public abstract class FaultCodes {
  -     private static final Map faultMessages = new HashMap();
  -     public static final int GEN = (int) (0l);
  -     public static final int OBJ = (int) (100l);
  -     public static final int COL = (int) (200l);
  -     public static final int IDX = (int) (300l);
  -     public static final int TRX = (int) (400l);
  -     public static final int DBE = (int) (500l);
  -     public static final int QRY = (int) (600l);
  -     public static final int SEC = (int) (700l);
  -     public static final int URI = (int) (800l);
  -     public static final int JAVA = (int) (2000l);
  -     public static final int GEN_UNKNOWN = (int) (0l);
  -     public static final int GEN_GENERAL_ERROR = (int) (40l);
  -     public static final int GEN_CRITICAL_ERROR = (int) (70l);
  -     public static final int GEN_FATAL_ERROR = (int) (90l);
  -     public static final int COL_COLLECTION_NOT_FOUND = (int) (200l);
  -     public static final int COL_DOCUMENT_NOT_FOUND = (int) (201l);
  -     public static final int COL_DUPLICATE_COLLECTION = (int) (240l);
  -     public static final int COL_NULL_RESULT = (int) (241l);
  -     public static final int COL_NO_FILER = (int) (242l);
  -     public static final int COL_NO_INDEXMANAGER = (int) (242l);
  -     public static final int COL_DOCUMENT_MALFORMED = (int) (243l);
  -     public static final int COL_CANNOT_STORE = (int) (244l);
  -     public static final int COL_CANNOT_RETRIEVE = (int) (245l);
  -     public static final int COL_COLLECTION_READ_ONLY = (int) (246l);
  -     public static final int COL_COLLECTION_CLOSED = (int) (247l);
  -     public static final int COL_CANNOT_CREATE = (int) (270l);
  -     public static final int COL_CANNOT_DROP = (int) (271l);
  -     public static final int COL_INVALID_RESULT = (int) (277l);
  -     public static final int IDX_VALUE_NOT_FOUND = (int) (300l);
  -     public static final int IDX_INDEX_NOT_FOUND = (int) (301l);
  -     public static final int IDX_MATCHES_NOT_FOUND = (int) (340l);
  -     public static final int IDX_DUPLICATE_INDEX = (int) (341l);
  -     public static final int IDX_NOT_SUPPORTED = (int) (370l);
  -     public static final int IDX_STYLE_NOT_FOUND = (int) (371l);
  -     public static final int IDX_CORRUPTED = (int) (372l);
  -     public static final int IDX_CANNOT_CREATE = (int) (373l);
  -     public static final int TRX_DOC_LOCKED = (int) (400l);
  -     public static final int TRX_NO_CONTEXT = (int) (440l);
  -     public static final int TRX_NOT_ACTIVE = (int) (441l);
  -     public static final int TRX_NOT_SUPPORTED = (int) (470l);
  -     public static final int DBE_NO_PARENT = (int) (500l);
  -     public static final int DBE_CANNOT_DROP = (int) (570l);
  -     public static final int DBE_CANNOT_CREATE = (int) (571l);
  -     public static final int QRY_NULL_RESULT = (int) (600l);
  -     public static final int QRY_COMPILATION_ERROR = (int) (640l);
  -     public static final int QRY_PROCESSING_ERROR = (int) (641l);
  -     public static final int QRY_NOT_SUPPORTED = (int) (670l);
  -     public static final int QRY_STYLE_NOT_FOUND = (int) (671l);
  -     public static final int SEC_INVALID_USER = (int) (770l);
  -     public static final int SEC_INVALID_GROUP = (int) (771l);
  -     public static final int SEC_INVALID_ACCESS = (int) (772l);
  -     public static final int SEC_INVALID_CREDENTIALS = (int) (773l);
  -     public static final int URI_EMPTY = (int) (800l);
  -     public static final int URI_NULL = (int) (801l);
  -     public static final int URI_PARSE_ERROR = (int) (820l);
  -     public static final int JAVA_RUNTIME_ERROR = (int) (2070l);
  -
  -     private FaultCodes() {}
  -
  -     static {
  -             // General errors 0 series
  -             putCodeMessage(GEN_UNKNOWN, "Unknown");
  -             putCodeMessage(GEN_GENERAL_ERROR, "General Error");
  -             putCodeMessage(GEN_CRITICAL_ERROR, "Critical Error");
  -             putCodeMessage(GEN_FATAL_ERROR, "Fatal Error");
  -
  -             // Collection-related errors 200 series
  -             putCodeMessage(COL_COLLECTION_NOT_FOUND, "Collection Not 
Found");
  -             putCodeMessage(COL_DOCUMENT_NOT_FOUND, "Collection Document Not 
Found");
  -             putCodeMessage(COL_DUPLICATE_COLLECTION, "Collection 
Duplicated");
  -             putCodeMessage(COL_NULL_RESULT, "Collection Null Result");
  -             putCodeMessage(COL_NO_FILER, "Collection No Filer");
  -             putCodeMessage(COL_NO_INDEXMANAGER, "Collection No 
IndexManager");
  -             putCodeMessage(COL_DOCUMENT_MALFORMED, "Collection Document 
Malformed");
  -             putCodeMessage(COL_CANNOT_STORE, "Collection Cannot Store");
  -             putCodeMessage(COL_CANNOT_RETRIEVE, "Collection Cannot 
Retrieve");
  -             putCodeMessage(COL_COLLECTION_READ_ONLY, "Collection 
Read-only");
  -             putCodeMessage(COL_COLLECTION_CLOSED, "Collection Closed");
  -             putCodeMessage(COL_CANNOT_CREATE, "Collection Cannot Create");
  -             putCodeMessage(COL_CANNOT_DROP, "Collection Cannot Drop");
  -             putCodeMessage(COL_INVALID_RESULT, "Collection Invalid Result");
  -
  -             // Index-related errors 300 series
  -             putCodeMessage(IDX_VALUE_NOT_FOUND, "Index Value Not Found");
  -             putCodeMessage(IDX_INDEX_NOT_FOUND, "Index Not Found");
  -             putCodeMessage(IDX_MATCHES_NOT_FOUND, "Index Matches Not 
Found");
  -             putCodeMessage(IDX_DUPLICATE_INDEX, "Index Duplicate Index");
  -             putCodeMessage(IDX_NOT_SUPPORTED, "Index Not Supported");
  -             putCodeMessage(IDX_STYLE_NOT_FOUND, "Index Style Not Found");
  -             putCodeMessage(IDX_CORRUPTED, "Index Corrupted");
  -             putCodeMessage(IDX_CANNOT_CREATE, "Index Cannot Create");
  -
  -             // Transaction-related errors 400 series
  -             putCodeMessage(TRX_DOC_LOCKED, "Transaction Document Locked");
  -             putCodeMessage(TRX_NO_CONTEXT, "Transaction No Context");
  -             putCodeMessage(TRX_NOT_ACTIVE, "Transaction Not Active");
  -             putCodeMessage(TRX_NOT_SUPPORTED, "Transaction Not Supported");
  -
  -             // Database-related errors 500 series
  -             putCodeMessage(DBE_NO_PARENT, "Database No Parent");
  -             putCodeMessage(DBE_CANNOT_DROP, "Database Cannot Drop");
  -             putCodeMessage(DBE_CANNOT_CREATE, "Database Cannot Create");
  -
  -             // Query-related errors 600 series
  -             putCodeMessage(QRY_NULL_RESULT, "Query Null Result");
  -             putCodeMessage(QRY_COMPILATION_ERROR, "Query Compilation 
Error");
  -             putCodeMessage(QRY_PROCESSING_ERROR, "Query Processing Error");
  -             putCodeMessage(QRY_NOT_SUPPORTED, "Query Not Supported");
  -             putCodeMessage(QRY_STYLE_NOT_FOUND, "Query Style Not Found");
  -
  -             // Security-related errors 700 series
  -             putCodeMessage(SEC_INVALID_USER, "Security Invalid User");
  -             putCodeMessage(SEC_INVALID_GROUP, "Security Invalid Group");
  -             putCodeMessage(SEC_INVALID_ACCESS, "Security Invalid Access");
  -             putCodeMessage(SEC_INVALID_CREDENTIALS, "Security Invalid 
Credentials");
  -
  -             // URI-related errors 800 series
  -             putCodeMessage(URI_EMPTY, "URI Empty");
  -             putCodeMessage(URI_NULL, "URI Null");
  -             putCodeMessage(URI_PARSE_ERROR, "URI Parse Error");
  -
  -             // Java-related errors 2000 series
  -             putCodeMessage(JAVA_RUNTIME_ERROR, "Java Runtime Error");
  -     }
  -
  -     private static void putCodeMessage(int code, String message) {
  -             faultMessages.put(new Integer(code), message);
  -     }
  -
  -     /**
  -      * getMessage returns a textual form for the specified fault code.
  -      *
  -      * @param code The Fault Code
  -      * @return It's textual form
  -      */
  -     public static String getMessage(int code) {
  -             String msg = (String) faultMessages.get(new Integer(code));
  -             return msg != null ? msg : "";
  -     }
  -
  -     /**
  -      * createXMLDBException creates an XMLDBException instance based
  -      * on the specified Exception.  If the Exception is a DBException,
  -      * it will extract any important information from it (like fault
  -      * codes and messages)
  -      *
  -      * @param e The Exception to use
  -      * @return An XMLDBException instance
  -      */
  -     public static XMLDBException createXMLDBException(Exception e) {
  -             if (e instanceof XMLDBException)
  -                     return (XMLDBException) e;
  -
  -             int faultCode = e instanceof RuntimeException ? 
JAVA_RUNTIME_ERROR : GEN_UNKNOWN;
  -             return createXMLDBException(faultCode, null, e);
  -     }
  -
  -     /**
  -      * Creates an XMLDBException instance based
  -      * on the specified fault code, message, and Exception.  If the 
Exception is a DBException,
  -      * it will extract any important information from it (like fault
  -      * codes and messages). If the exception is an instance of 
XindiceException,
  -      * the exception class name and message of any Throwable(s) available
  -      * via XindiceException.getCause will also be incorporated
  -      * into the message. If a chain of wrapped XindiceExceptions is 
available,
  -      * the chain will be followed incorporating the class name and message
  -      * at each level. 
  -      * TODO: This should only be considered a temporary fix
  -      * TODO: until such time as the xmldb API can be refined to allow for 
wrapped
  -      * TODO: throwables in XMLDBException.
  -      *
  -      * @param faultCode the fault code for the created exception
  -      * @param e The Exception to use
  -      * @return An XMLDBException instance
  -      */
  -     public static XMLDBException createXMLDBException(int faultCode, String 
message, Exception e) {
  -             if (e instanceof XMLDBException) {
  -                     return (XMLDBException) e;
  -             }
  -
  -             if (e instanceof DBException) {
  -                     faultCode = ((DBException) e).faultCode;
  -             }
  -
  -             return new XMLDBException(ErrorCodes.VENDOR_ERROR, faultCode, 
message, e);
  -     }
  -
  -     /**
  -      * getFaultCodeType examines the provided exception to determine
  -      * the general fault code that is associated with it.  General
  -      * fault codes are reduced from actual fault codes to be one of
  -      * the GEN_ prefixed fault code values.
  -      *
  -      * @param e The Exception to examine
  -      * @return The General Fault Code
  -      */
  -     public static int getFaultCodeType(Exception e) {
  -             int code = 0;
  -             if (e instanceof DBException)
  -                     code = ((DBException) e).faultCode;
  -
  -             // Strip it to the General series
  -             code = code % 100;
  -             // Narrow to a General value
  -             code = code - (code % 10);
  -             return code;
  -     }
  -
  -     /**
  -      * getFaultCodeSeries examines the provided exception to
  -      * determine the fault code series that is associated with it.
  -      * Series are reduced from actual fault codes to be one of
  -      * the fault code prefixes (ex: COL, DB, SEC).
  -      *
  -      * @param e The Exception to examine
  -      * @return The Fault Code Series
  -      */
  -     public static int getFaultCodeSeries(Exception e) {
  -             int code = 0;
  -             if (e instanceof DBException)
  -                     code = ((DBException) e).faultCode;
  -
  -             // Strip it to the series
  -             code = code - (code % 100);
  -             return code;
  -     }
  -
  -     /**
  -      * getFaultCode examines the provided exception to determine
  -      * the fault code that is associated with it.
  -      *
  -      * @param e The Exception to examine
  -      * @return The Fault Code
  -      */
  -     public static int getFaultCode(Exception e) {
  -             if (e instanceof DBException)
  -                     return ((DBException) e).faultCode;
  -             else
  -                     return 0;
  -     }
  -
  -     /**
  -      * getFaultMessage examines the provided exception to determine
  -      * the fault message that is associated with it.
  -      *
  -      * @param e The Exception to examine
  -      * @return The Fault Message
  -      */
  -     public static String getFaultMessage(Exception e) {
  -             return getMessage(getFaultCode(e));
  -     }
  +    private static final Map faultMessages = new HashMap();
  +    public static final int GEN = (int) (0l);
  +    public static final int OBJ = (int) (100l);
  +    public static final int COL = (int) (200l);
  +    public static final int IDX = (int) (300l);
  +    public static final int TRX = (int) (400l);
  +    public static final int DBE = (int) (500l);
  +    public static final int QRY = (int) (600l);
  +    public static final int SEC = (int) (700l);
  +    public static final int URI = (int) (800l);
  +    public static final int JAVA = (int) (2000l);
  +    public static final int GEN_UNKNOWN = (int) (0l);
  +    public static final int GEN_GENERAL_ERROR = (int) (40l);
  +    public static final int GEN_CRITICAL_ERROR = (int) (70l);
  +    public static final int GEN_FATAL_ERROR = (int) (90l);
  +    public static final int COL_COLLECTION_NOT_FOUND = (int) (200l);
  +    public static final int COL_DOCUMENT_NOT_FOUND = (int) (201l);
  +    public static final int COL_DUPLICATE_COLLECTION = (int) (240l);
  +    public static final int COL_NULL_RESULT = (int) (241l);
  +    public static final int COL_NO_FILER = (int) (242l);
  +    public static final int COL_NO_INDEXMANAGER = (int) (242l);
  +    public static final int COL_DOCUMENT_MALFORMED = (int) (243l);
  +    public static final int COL_CANNOT_STORE = (int) (244l);
  +    public static final int COL_CANNOT_RETRIEVE = (int) (245l);
  +    public static final int COL_COLLECTION_READ_ONLY = (int) (246l);
  +    public static final int COL_COLLECTION_CLOSED = (int) (247l);
  +    public static final int COL_CANNOT_CREATE = (int) (270l);
  +    public static final int COL_CANNOT_DROP = (int) (271l);
  +    public static final int COL_INVALID_RESULT = (int) (277l);
  +    public static final int IDX_VALUE_NOT_FOUND = (int) (300l);
  +    public static final int IDX_INDEX_NOT_FOUND = (int) (301l);
  +    public static final int IDX_MATCHES_NOT_FOUND = (int) (340l);
  +    public static final int IDX_DUPLICATE_INDEX = (int) (341l);
  +    public static final int IDX_NOT_SUPPORTED = (int) (370l);
  +    public static final int IDX_STYLE_NOT_FOUND = (int) (371l);
  +    public static final int IDX_CORRUPTED = (int) (372l);
  +    public static final int IDX_CANNOT_CREATE = (int) (373l);
  +    public static final int TRX_DOC_LOCKED = (int) (400l);
  +    public static final int TRX_NO_CONTEXT = (int) (440l);
  +    public static final int TRX_NOT_ACTIVE = (int) (441l);
  +    public static final int TRX_NOT_SUPPORTED = (int) (470l);
  +    public static final int DBE_NO_PARENT = (int) (500l);
  +    public static final int DBE_CANNOT_DROP = (int) (570l);
  +    public static final int DBE_CANNOT_CREATE = (int) (571l);
  +    public static final int QRY_NULL_RESULT = (int) (600l);
  +    public static final int QRY_COMPILATION_ERROR = (int) (640l);
  +    public static final int QRY_PROCESSING_ERROR = (int) (641l);
  +    public static final int QRY_NOT_SUPPORTED = (int) (670l);
  +    public static final int QRY_STYLE_NOT_FOUND = (int) (671l);
  +    public static final int SEC_INVALID_USER = (int) (770l);
  +    public static final int SEC_INVALID_GROUP = (int) (771l);
  +    public static final int SEC_INVALID_ACCESS = (int) (772l);
  +    public static final int SEC_INVALID_CREDENTIALS = (int) (773l);
  +    public static final int URI_EMPTY = (int) (800l);
  +    public static final int URI_NULL = (int) (801l);
  +    public static final int URI_PARSE_ERROR = (int) (820l);
  +    public static final int JAVA_RUNTIME_ERROR = (int) (2070l);
  +
  +    private FaultCodes() {}
  +
  +    static {
  +        // General errors 0 series
  +        putCodeMessage(GEN_UNKNOWN, "Unknown");
  +        putCodeMessage(GEN_GENERAL_ERROR, "General Error");
  +        putCodeMessage(GEN_CRITICAL_ERROR, "Critical Error");
  +        putCodeMessage(GEN_FATAL_ERROR, "Fatal Error");
  +
  +        // Collection-related errors 200 series
  +        putCodeMessage(COL_COLLECTION_NOT_FOUND, "Collection Not Found");
  +        putCodeMessage(COL_DOCUMENT_NOT_FOUND, "Collection Document Not 
Found");
  +        putCodeMessage(COL_DUPLICATE_COLLECTION, "Collection Duplicated");
  +        putCodeMessage(COL_NULL_RESULT, "Collection Null Result");
  +        putCodeMessage(COL_NO_FILER, "Collection No Filer");
  +        putCodeMessage(COL_NO_INDEXMANAGER, "Collection No IndexManager");
  +        putCodeMessage(COL_DOCUMENT_MALFORMED, "Collection Document 
Malformed");
  +        putCodeMessage(COL_CANNOT_STORE, "Collection Cannot Store");
  +        putCodeMessage(COL_CANNOT_RETRIEVE, "Collection Cannot Retrieve");
  +        putCodeMessage(COL_COLLECTION_READ_ONLY, "Collection Read-only");
  +        putCodeMessage(COL_COLLECTION_CLOSED, "Collection Closed");
  +        putCodeMessage(COL_CANNOT_CREATE, "Collection Cannot Create");
  +        putCodeMessage(COL_CANNOT_DROP, "Collection Cannot Drop");
  +        putCodeMessage(COL_INVALID_RESULT, "Collection Invalid Result");
  +
  +        // Index-related errors 300 series
  +        putCodeMessage(IDX_VALUE_NOT_FOUND, "Index Value Not Found");
  +        putCodeMessage(IDX_INDEX_NOT_FOUND, "Index Not Found");
  +        putCodeMessage(IDX_MATCHES_NOT_FOUND, "Index Matches Not Found");
  +        putCodeMessage(IDX_DUPLICATE_INDEX, "Index Duplicate Index");
  +        putCodeMessage(IDX_NOT_SUPPORTED, "Index Not Supported");
  +        putCodeMessage(IDX_STYLE_NOT_FOUND, "Index Style Not Found");
  +        putCodeMessage(IDX_CORRUPTED, "Index Corrupted");
  +        putCodeMessage(IDX_CANNOT_CREATE, "Index Cannot Create");
  +
  +        // Transaction-related errors 400 series
  +        putCodeMessage(TRX_DOC_LOCKED, "Transaction Document Locked");
  +        putCodeMessage(TRX_NO_CONTEXT, "Transaction No Context");
  +        putCodeMessage(TRX_NOT_ACTIVE, "Transaction Not Active");
  +        putCodeMessage(TRX_NOT_SUPPORTED, "Transaction Not Supported");
  +
  +        // Database-related errors 500 series
  +        putCodeMessage(DBE_NO_PARENT, "Database No Parent");
  +        putCodeMessage(DBE_CANNOT_DROP, "Database Cannot Drop");
  +        putCodeMessage(DBE_CANNOT_CREATE, "Database Cannot Create");
  +
  +        // Query-related errors 600 series
  +        putCodeMessage(QRY_NULL_RESULT, "Query Null Result");
  +        putCodeMessage(QRY_COMPILATION_ERROR, "Query Compilation Error");
  +        putCodeMessage(QRY_PROCESSING_ERROR, "Query Processing Error");
  +        putCodeMessage(QRY_NOT_SUPPORTED, "Query Not Supported");
  +        putCodeMessage(QRY_STYLE_NOT_FOUND, "Query Style Not Found");
  +
  +        // Security-related errors 700 series
  +        putCodeMessage(SEC_INVALID_USER, "Security Invalid User");
  +        putCodeMessage(SEC_INVALID_GROUP, "Security Invalid Group");
  +        putCodeMessage(SEC_INVALID_ACCESS, "Security Invalid Access");
  +        putCodeMessage(SEC_INVALID_CREDENTIALS, "Security Invalid 
Credentials");
  +
  +        // URI-related errors 800 series
  +        putCodeMessage(URI_EMPTY, "URI Empty");
  +        putCodeMessage(URI_NULL, "URI Null");
  +        putCodeMessage(URI_PARSE_ERROR, "URI Parse Error");
  +
  +        // Java-related errors 2000 series
  +        putCodeMessage(JAVA_RUNTIME_ERROR, "Java Runtime Error");
  +    }
  +
  +    private static void putCodeMessage(int code, String message) {
  +        faultMessages.put(new Integer(code), message);
  +    }
  +
  +    /**
  +     * getMessage returns a textual form for the specified fault code.
  +     *
  +     * @param code The Fault Code
  +     * @return It's textual form
  +     */
  +    public static String getMessage(int code) {
  +        String msg = (String) faultMessages.get(new Integer(code));
  +        return msg != null ? msg : "";
  +    }
  +
  +    /**
  +     * createXMLDBException creates an XMLDBException instance based
  +     * on the specified Exception.  If the Exception is a DBException,
  +     * it will extract any important information from it (like fault
  +     * codes and messages)
  +     *
  +     * @param e The Exception to use
  +     * @return An XMLDBException instance
  +     */
  +    public static XMLDBException createXMLDBException(Exception e) {
  +        if (e instanceof XMLDBException)
  +            return (XMLDBException) e;
  +
  +        int faultCode = e instanceof RuntimeException ? JAVA_RUNTIME_ERROR : 
GEN_UNKNOWN;
  +        return createXMLDBException(faultCode, null, e);
  +    }
  +
  +    /**
  +     * Creates an XMLDBException instance based
  +     * on the specified fault code, message, and Exception.  If the 
Exception is a DBException,
  +     * it will extract any important information from it (like fault
  +     * codes and messages). If the exception is an instance of 
XindiceException,
  +     * the exception class name and message of any Throwable(s) available
  +     * via XindiceException.getCause will also be incorporated
  +     * into the message. If a chain of wrapped XindiceExceptions is 
available,
  +     * the chain will be followed incorporating the class name and message
  +     * at each level. 
  +     * TODO: This should only be considered a temporary fix
  +     * TODO: until such time as the xmldb API can be refined to allow for 
wrapped
  +     * TODO: throwables in XMLDBException.
  +     *
  +     * @param faultCode the fault code for the created exception
  +     * @param e The Exception to use
  +     * @return An XMLDBException instance
  +     */
  +    public static XMLDBException createXMLDBException(int faultCode, String 
message, Exception e) {
  +        if (e instanceof XMLDBException) {
  +            return (XMLDBException) e;
  +        }
  +
  +        if (e instanceof DBException) {
  +            faultCode = ((DBException) e).faultCode;
  +        }
  +
  +        return new XMLDBException(ErrorCodes.VENDOR_ERROR, faultCode, 
message, e);
  +    }
  +
  +    /**
  +     * getFaultCodeType examines the provided exception to determine
  +     * the general fault code that is associated with it.  General
  +     * fault codes are reduced from actual fault codes to be one of
  +     * the GEN_ prefixed fault code values.
  +     *
  +     * @param e The Exception to examine
  +     * @return The General Fault Code
  +     */
  +    public static int getFaultCodeType(Exception e) {
  +        int code = 0;
  +        if (e instanceof DBException)
  +            code = ((DBException) e).faultCode;
  +
  +        // Strip it to the General series
  +        code = code % 100;
  +        // Narrow to a General value
  +        code = code - (code % 10);
  +        return code;
  +    }
  +
  +    /**
  +     * getFaultCodeSeries examines the provided exception to
  +     * determine the fault code series that is associated with it.
  +     * Series are reduced from actual fault codes to be one of
  +     * the fault code prefixes (ex: COL, DB, SEC).
  +     *
  +     * @param e The Exception to examine
  +     * @return The Fault Code Series
  +     */
  +    public static int getFaultCodeSeries(Exception e) {
  +        int code = 0;
  +        if (e instanceof DBException)
  +            code = ((DBException) e).faultCode;
  +
  +        // Strip it to the series
  +        code = code - (code % 100);
  +        return code;
  +    }
  +
  +    /**
  +     * getFaultCode examines the provided exception to determine
  +     * the fault code that is associated with it.
  +     *
  +     * @param e The Exception to examine
  +     * @return The Fault Code
  +     */
  +    public static int getFaultCode(Exception e) {
  +        if (e instanceof DBException)
  +            return ((DBException) e).faultCode;
  +        else
  +            return 0;
  +    }
  +
  +    /**
  +     * getFaultMessage examines the provided exception to determine
  +     * the fault message that is associated with it.
  +     *
  +     * @param e The Exception to examine
  +     * @return The Fault Message
  +     */
  +    public static String getFaultMessage(Exception e) {
  +        return getMessage(getFaultCode(e));
  +    }
   }
  
  
  
  1.5       +122 -99   
xml-xindice/java/src/org/apache/xindice/core/DocumentCache.java
  
  Index: DocumentCache.java
  ===================================================================
  RCS file: 
/home/cvs/xml-xindice/java/src/org/apache/xindice/core/DocumentCache.java,v
  retrieving revision 1.4
  retrieving revision 1.5
  diff -u -r1.4 -r1.5
  --- DocumentCache.java        3 Jul 2003 19:23:07 -0000       1.4
  +++ DocumentCache.java        14 Jul 2003 19:07:14 -0000      1.5
  @@ -59,16 +59,17 @@
    * $Id$
    */
   
  +import java.util.Map;
  +import java.util.WeakHashMap;
  +
   import org.apache.xindice.core.data.Key;
   import org.apache.xindice.xml.NodeSource;
   import org.apache.xindice.xml.SymbolTable;
   import org.apache.xindice.xml.dom.DBDocument;
   import org.apache.xindice.xml.dom.DocumentImpl;
  -
  -import org.w3c.dom.*;
  -
  -import java.util.Map;
  -import java.util.WeakHashMap;
  +import org.w3c.dom.Document;
  +import org.w3c.dom.Node;
  +import org.w3c.dom.NodeList;
   
   /**
    * DocumentCache implements a simple Document caching system for
  @@ -76,98 +77,120 @@
    */
   
   public final class DocumentCache {
  -     private Map table = new WeakHashMap();
  +    private Map table = new WeakHashMap();
   
  -     public Document getDocument(Collection col, Key key) {
  -             Object v = table.get(new CacheKey(col, key));
  -             Document doc = null;
  -             if (v instanceof Document)
  -                     doc = (Document) v;
  -             else if (v instanceof byte[]) {
  -                     try {
  -                             SymbolTable s = col.getSymbols();
  -                             NodeSource ns = new NodeSource(col, key);
  -                             doc = new DocumentImpl((byte[]) v, s, ns);
  -                     }
  -                     catch (Exception e) {}
  -             }
  -             return doc;
  -     }
  -
  -     public void putDocument(Collection col, Key key, byte[] bytes) {
  -             CacheKey ckey = new CacheKey(col, key);
  -             table.put(ckey, bytes);
  -     }
  -
  -     public void putDocument(Collection col, Key key, Document doc) {
  -             CacheKey ckey = new CacheKey(col, key);
  -             table.put(ckey, doc);
  -     }
  -
  -     public void removeDocument(Collection col, Key key) {
  -             table.remove(new CacheKey(col, key));
  -     }
  -
  -     public static int getCacheControl(Document doc) {
  -             String cache = DBDocument.CACHE;
  -             NodeList childNodes = doc.getChildNodes();
  -             int size = childNodes.getLength();
  -             for (int i = 0; i < size; i++) {
  -                     Node n = childNodes.item(i);
  -                     if (n.getNodeType() == Node.PROCESSING_INSTRUCTION_NODE 
&& n.getNodeName().equals(DBDocument.CACHE_CONTROL)) {
  -                             cache = n.getNodeValue().trim();
  -                             break;
  -                     }
  -             }
  -
  -             if (cache != null) {
  -                     if (cache.equals(DBDocument.CACHE))
  -                             return -1;
  -                     else if (cache.equals(DBDocument.NOCACHE))
  -                             return 0;
  -                     else
  -                             return Integer.parseInt(cache);
  -             }
  -             else
  -                     return -1;
  -     }
  -
  -     /**
  -      * CacheKey
  -      */
  -
  -     private class CacheKey {
  -             private Collection col;
  -             private String strVal;
  -             private Key key;
  -
  -             public CacheKey(Collection col, Key key) {
  -                     this.col = col;
  -                     this.key = key;
  -             }
  -
  -             public Collection getCollection() {
  -                     return col;
  -             }
  -
  -             public Key getKey() {
  -                     return key;
  -             }
  -
  -             public String toString() {
  -                     if (strVal == null)
  -                             strVal = col.getCanonicalDocumentName(key);
  -                     return strVal;
  -             }
  -
  -             public int hashCode() {
  -                     if (strVal == null)
  -                             strVal = col.getCanonicalDocumentName(key);
  -                     return strVal.hashCode();
  -             }
  -
  -             public boolean equals(Object o) {
  -                     return o instanceof CacheKey && col == ((CacheKey) 
o).col && key.equals(((CacheKey) o).key);
  -             }
  -     }
  +    /**
  +     * @param col
  +     * @param key
  +     * @return
  +     */
  +    public Document getDocument(Collection col, Key key) {
  +        Object v = table.get(new CacheKey(col, key));
  +        Document doc = null;
  +        if (v instanceof Document)
  +            doc = (Document) v;
  +        else if (v instanceof byte[]) {
  +            try {
  +                SymbolTable s = col.getSymbols();
  +                NodeSource ns = new NodeSource(col, key);
  +                doc = new DocumentImpl((byte[]) v, s, ns);
  +            }
  +            catch (Exception e) {}
  +        }
  +        return doc;
  +    }
  +
  +    /**
  +     * @param col
  +     * @param key
  +     * @param bytes
  +     */
  +    public void putDocument(Collection col, Key key, byte[] bytes) {
  +        CacheKey ckey = new CacheKey(col, key);
  +        table.put(ckey, bytes);
  +    }
  +
  +    /**
  +     * @param col
  +     * @param key
  +     * @param doc
  +     */
  +    public void putDocument(Collection col, Key key, Document doc) {
  +        CacheKey ckey = new CacheKey(col, key);
  +        table.put(ckey, doc);
  +    }
  +
  +    /**
  +     * @param col
  +     * @param key
  +     */
  +    public void removeDocument(Collection col, Key key) {
  +        table.remove(new CacheKey(col, key));
  +    }
  +
  +    /**
  +     * @param doc
  +     * @return
  +     */
  +    public static int getCacheControl(Document doc) {
  +        String cache = DBDocument.CACHE;
  +        NodeList childNodes = doc.getChildNodes();
  +        int size = childNodes.getLength();
  +        for (int i = 0; i < size; i++) {
  +            Node n = childNodes.item(i);
  +            if (n.getNodeType() == Node.PROCESSING_INSTRUCTION_NODE && 
n.getNodeName().equals(DBDocument.CACHE_CONTROL)) {
  +                cache = n.getNodeValue().trim();
  +                break;
  +            }
  +        }
  +
  +        if (cache != null) {
  +            if (cache.equals(DBDocument.CACHE))
  +                return -1;
  +            else if (cache.equals(DBDocument.NOCACHE))
  +                return 0;
  +            else
  +                return Integer.parseInt(cache);
  +        }
  +        else
  +            return -1;
  +    }
  +
  +    /**
  +     * CacheKey
  +     */
  +    private class CacheKey {
  +        private Collection col;
  +        private String strVal;
  +        private Key key;
  +
  +        public CacheKey(Collection col, Key key) {
  +            this.col = col;
  +            this.key = key;
  +        }
  +
  +        public Collection getCollection() {
  +            return col;
  +        }
  +
  +        public Key getKey() {
  +            return key;
  +        }
  +
  +        public String toString() {
  +            if (strVal == null)
  +                strVal = col.getCanonicalDocumentName(key);
  +            return strVal;
  +        }
  +
  +        public int hashCode() {
  +            if (strVal == null)
  +                strVal = col.getCanonicalDocumentName(key);
  +            return strVal.hashCode();
  +        }
  +
  +        public boolean equals(Object o) {
  +            return o instanceof CacheKey && col == ((CacheKey) o).col && 
key.equals(((CacheKey) o).key);
  +        }
  +    }
   }
  
  
  
  1.5       +18 -19    
xml-xindice/java/src/org/apache/xindice/core/DBException.java
  
  Index: DBException.java
  ===================================================================
  RCS file: 
/home/cvs/xml-xindice/java/src/org/apache/xindice/core/DBException.java,v
  retrieving revision 1.4
  retrieving revision 1.5
  diff -u -r1.4 -r1.5
  --- DBException.java  31 Oct 2002 06:59:56 -0000      1.4
  +++ DBException.java  14 Jul 2003 19:07:14 -0000      1.5
  @@ -68,23 +68,22 @@
    */
   
   public class DBException extends XindiceException {
  -   public int faultCode;
  +    public int faultCode;
   
  -   public DBException() {
  -      this(FaultCodes.GEN_UNKNOWN,  "", null);
  -   }
  +    public DBException() {
  +        this(FaultCodes.GEN_UNKNOWN, "", null);
  +    }
   
  -   public DBException(int faultCode) {
  -      this(faultCode, "", null);
  -   }
  +    public DBException(int faultCode) {
  +        this(faultCode, "", null);
  +    }
   
  -   public DBException(int faultCode, String message) {
  -      this(faultCode, message, null);
  -   }
  -
  -   public DBException(int faultCode, String message, Throwable cause) {
  -      super(message, cause);
  -      this.faultCode = faultCode;
  -   }
  +    public DBException(int faultCode, String message) {
  +        this(faultCode, message, null);
  +    }
   
  +    public DBException(int faultCode, String message, Throwable cause) {
  +        super(message, cause);
  +        this.faultCode = faultCode;
  +    }
   }
  
  
  
  1.3       +3 -3      
xml-xindice/java/src/org/apache/xindice/core/Container.java
  
  Index: Container.java
  ===================================================================
  RCS file: 
/home/cvs/xml-xindice/java/src/org/apache/xindice/core/Container.java,v
  retrieving revision 1.2
  retrieving revision 1.3
  diff -u -r1.2 -r1.3
  --- Container.java    31 Oct 2002 06:59:56 -0000      1.2
  +++ Container.java    14 Jul 2003 19:07:14 -0000      1.3
  @@ -60,14 +60,14 @@
    */
   
   import org.apache.xindice.core.data.Key;
  -
  -import org.w3c.dom.*;
  +import org.w3c.dom.Document;
   
   /**
    * Container is a generic container for Key and Document pairs.
    */
   
   public interface Container {
  +     
      /**
       * getCollection returns the Collection that the Document contained
       * belongs to.
  
  
  
  1.21      +293 -270  
xml-xindice/java/src/org/apache/xindice/core/Database.java
  
  Index: Database.java
  ===================================================================
  RCS file: 
/home/cvs/xml-xindice/java/src/org/apache/xindice/core/Database.java,v
  retrieving revision 1.20
  retrieving revision 1.21
  diff -u -r1.20 -r1.21
  --- Database.java     14 Jul 2003 18:31:57 -0000      1.20
  +++ Database.java     14 Jul 2003 19:07:14 -0000      1.21
  @@ -80,273 +80,296 @@
    * Database is the primary container for the Xindice Database Engine.
    */
   public final class Database extends Collection implements Named {
  -     public static final String DBROOT = "dbroot";
  -     private static final String QUERYENGINE = "queryengine";
  -     private static final String DATABASE = "database";
  -     private static final String COLKEY = "database.xml";
  -     private static final String METADATA = "use-metadata";
  -     public static final String NAME = "name";
  -
  -     private static Log log = LogFactory.getLog("org.apache.xindice.core");
  -
  -     public static final String PROP_XINDICE_HOME = "xindice.home";
  -
  -     private static final Map databases = new HashMap(); // String to 
Database
  -
  -     private DocumentCache docCache = new DocumentCache();
  -
  -     private SystemCollection systemCollection = null;
  -
  -     private MetaSystemCollection metaSystemCollection = null;
  -
  -     private boolean sysInit = false;
  -     private boolean metaInit = false;
  -     private boolean metaEnabled = false;
  -     // key = canonical name, value = timerecord
  -     private Map timestamps = new HashMap();
  -
  -     private QueryEngine engine = new QueryEngine(this);
  -
  -     /**
  -      * This will merely return an instance of a Database for the given 
  -      *      name if one has already been loaded.
  -      * 
  -      * @param name
  -      * @return Database
  -      */
  -     public static Database getDatabase(String name) {
  -
  -             Database database = (Database) databases.get(name);
  -             if (null == database) {
  -                     // in case it's currently being added (only pay the 
sync hit on a miss)
  -                     synchronized (databases) {
  -                             database = (Database) databases.get(name);
  -                     }
  -             }
  -
  -             return database;
  -     }
  -
  -     /**
  -      * This will return an instance of a Database for the given 
  -      *      name if one has already been loaded, otherwise it will
  -      *      create a new instance.
  -      * 
  -      * @param config
  -      * @return Database
  -      */
  -     public static Database getDatabase(Configuration config) {
  -
  -             String name = config.getAttribute(Database.NAME);
  -
  -             // no name in the config file ... can't the database
  -             if (null == name) {
  -                     throw new ConfigurationException("Database 
configuration didn't contain a database name");
  -             }
  -
  -             Database database = (Database) databases.get(name);
  -             if (null == database) {
  -                     // in case it's currently being added (only pay the 
sync hit on a miss)
  -                     synchronized (databases) {
  -                             // was it created while we waited?
  -                             database = (Database) databases.get(name);
  -                             if (null == database) {
  -                                     database = new Database();
  -                                     database.setConfig(config);
  -
  -                                     databases.put(database.getName(), 
database);
  -                             }
  -                     }
  -             }
  -
  -             return database;
  -     }
  -
  -     public static String[] listDatabases() {
  -             return (String[]) databases.keySet().toArray(new String[0]);
  -     }
  -
  -     public void setConfig(Configuration config) {
  -             this.config = config;
  -
  -             this.name = config.getAttribute(NAME);
  -             setCanonicalName('/' + getName());
  -
  -             String dbroot = config.getAttribute(DBROOT);
  -             File dbrootDir = new File(dbroot);
  -             if (!dbrootDir.isAbsolute()) {
  -                     dbrootDir = new 
File(System.getProperty(PROP_XINDICE_HOME), dbroot);
  -             }
  -             setCollectionRoot(dbrootDir);
  -             log.info("Database points to " + dbrootDir.getAbsolutePath());
  -             log.debug("Database dir exists: " + (dbrootDir == null ? false 
: dbrootDir.exists()));
  -
  -             try {
  -                     Configuration queryCfg = config.getChild(QUERYENGINE);
  -                     if (queryCfg != null)
  -                             this.engine.setConfig(queryCfg);
  -             }
  -             catch (Exception e) {
  -
  -                     log.warn(e);
  -             }
  -
  -             if (!sysInit) {
  -                     this.systemCollection = new SystemCollection(this);
  -
  -                     try {
  -                             this.systemCollection.init();
  -                     }
  -                     catch (XindiceException e) {
  -                             log.warn(e);
  -                     }
  -
  -                     this.collections.put(systemCollection.getName(), 
systemCollection);
  -                     this.sysInit = true;
  -             }
  -
  -             try {
  -                     // Bootstrap from the database itself...  This is 
accomplished
  -                     // by intercepting the setConfig call and using a 
Configuration
  -                     // retrieved from the database instead of the standard 
config
  -                     Document colDoc = 
systemCollection.getCollection(SystemCollection.CONFIGS).getDocument(COLKEY);
  -                     if (colDoc == null) {
  -                             DocumentBuilder db = 
DocumentBuilderFactory.newInstance().newDocumentBuilder();
  -                             colDoc = db.newDocument();
  -                             Element root = colDoc.createElement(DATABASE);
  -                             root.setAttribute(NAME, name);
  -                             colDoc.appendChild(root);
  -                             
systemCollection.getCollection(SystemCollection.CONFIGS).setDocument(COLKEY, 
colDoc);
  -                     }
  -
  -                     super.setConfig(new 
Configuration(colDoc.getDocumentElement(), false));
  -             }
  -             catch (Exception e) {
  -                     log.warn(e);
  -             }
  -
  -             // Register the Database with the VM
  -             // databases.put(getName(), this);
  -
  -             // initialize the meta collection
  -             // but only if it's turned on in the config.
  -             String metaCfg = config.getAttribute(METADATA);
  -             if (metaCfg.equalsIgnoreCase("on")) {
  -                     metaEnabled = true;
  -                     if (!metaInit) {
  -                             this.metaSystemCollection = new 
MetaSystemCollection(this);
  -                             try {
  -                                     this.metaSystemCollection.init();
  -                             }
  -                             catch (XindiceException e) {
  -                                     log.warn("Error initializing the meta 
collection", e);
  -                             }
  -                             // should this attach the meta collection to 
the database?
  -
  -                             collections.put(metaSystemCollection.getName(), 
metaSystemCollection);
  -                             metaInit = true;
  -                             log.info("Meta information initialized");
  -                     }
  -             }
  -
  -             // observer
  -             DBObserver.getInstance().setDatabaseConfig(this, collections, 
config);
  -     }
  -
  -     public SystemCollection getSystemCollection() {
  -             return systemCollection;
  -     }
  -
  -     /**
  -      * Return the MetaSystem collection for this database.
  -      * 
  -      * It will return null if metadata is not enabled on this database.
  -      * @return MetaSystemCollection
  -      */
  -     public MetaSystemCollection getMetaSystemCollection() {
  -             return metaSystemCollection;
  -     }
  -
  -     /**
  -      * Return whether or not metadata is enabled on this database.
  -      * @return boolean
  -      */
  -     public boolean isMetaEnabled() {
  -             return metaEnabled;
  -     }
  -
  -     public Database getDatabase() {
  -             return this;
  -     }
  -
  -     /**
  -      * flushConfig ensures that the Collection configuration has been
  -      * properly flushed to disk after a modification.
  -      */
  -     public void flushConfig() {
  -             
  -             try {
  -                     Document d = config.getElement().getOwnerDocument();
  -                     
systemCollection.getCollection(SystemCollection.CONFIGS).setDocument(COLKEY, d);
  -             }
  -             catch (Exception e) {
  -                     log.error("Error Writing Configuration '" + name + "', 
for database " + getName(), e);
  -             }
  -             
  -             // observer
  -             DBObserver.getInstance().flushDatabaseConfig(this, config);
  -     }
  -
  -     public boolean close() throws DBException {
  -             flushConfig();
  -
  -             synchronized (databases) {
  -                     databases.remove(getName());
  -             }
  -
  -             return true;
  -     }
  -
  -     /**
  -      * getDocumentCache returns the Database-level Document Cache.
  -      *
  -      * @return The DocumentCache
  -      */
  -     public DocumentCache getDocumentCache() {
  -             return docCache;
  -     }
  -
  -     /**
  -      * getQueryEngine returns a reference to the Database's current
  -      * operating QueryEngine implementation.
  -      *
  -      * @return The QueryEngine instance
  -      */
  -     public QueryEngine getQueryEngine() {
  -             return engine;
  -     }
  -
  -     // methods for recording the times when meta data is enabled.
  -     public synchronized void recordTime(String path, long created, long 
modified) {
  -             TimeRecord rec = (TimeRecord) timestamps.get(path);
  -             if (null == rec) {
  -                     rec = new TimeRecord(created, modified);
  -                     timestamps.put(path, rec);
  -             }
  -             else {
  -                     if (created > 0)
  -                             rec.setCreatedTime(created);
  -                     if (modified > 0)
  -                             rec.setModifiedTime(modified);
  -             }
  -     }
  -
  -     public synchronized void removeTime(String path) {
  -             timestamps.remove(path);
  -     }
  -
  -     public synchronized TimeRecord getTime(String path) {
  -             TimeRecord rec = (TimeRecord) timestamps.get(path);
  -             return rec;
  -     }
  +
  +    public static final String DBROOT = "dbroot";
  +    public static final String NAME = "name";
  +    public static final String PROP_XINDICE_HOME = "xindice.home";
  +    private static final String QUERYENGINE = "queryengine";
  +    private static final String COLKEY = "database.xml";
  +    private static final String DATABASE = "database";
  +    private static final String METADATA = "use-metadata";
  +    private static Log log = LogFactory.getLog("org.apache.xindice.core");
  +    private static final Map databases = new HashMap(); // String to Database
  +
  +    /**
  +     * This will return an instance of a Database for the given 
  +     *       name if one has already been loaded, otherwise it will
  +     *       create a new instance.
  +     * 
  +     * @param config
  +     * @return Database
  +     */
  +    public static Database getDatabase(Configuration config) {
  +
  +        String name = config.getAttribute(Database.NAME);
  +
  +        // no name in the config file ... can't the database
  +        if (null == name) {
  +            throw new ConfigurationException("Database configuration didn't 
contain a database name");
  +        }
  +
  +        Database database = (Database) databases.get(name);
  +        if (null == database) {
  +            // in case it's currently being added (only pay the sync hit on 
a miss)
  +            synchronized (databases) {
  +                // was it created while we waited?
  +                database = (Database) databases.get(name);
  +                if (null == database) {
  +                    database = new Database();
  +
  +                    try {
  +                        database.setConfig(config);
  +                    }
  +                    catch (XindiceException x) { // TODO: Configurable 
interface should use ConfigurationException instead of XindiceException.
  +
  +                        throw new ConfigurationException(x);
  +                    }
  +
  +                    databases.put(database.getName(), database);
  +                }
  +            }
  +        }
  +
  +        return database;
  +    }
  +
  +    /**
  +     * This will merely return an instance of a Database for the given 
  +     *       name if one has already been loaded.
  +     * 
  +     * @param name
  +     * @return Database
  +     */
  +    public static Database getDatabase(String name) {
  +
  +        Database database = (Database) databases.get(name);
  +        if (null == database) {
  +            // in case it's currently being added (only pay the sync hit on 
a miss)
  +            synchronized (databases) {
  +                database = (Database) databases.get(name);
  +            }
  +        }
  +
  +        return database;
  +    }
  +
  +    public static String[] listDatabases() {
  +        return (String[]) databases.keySet().toArray(new String[0]);
  +    }
  +
  +    //
  +    // Instance...
  +    //
  +    private DocumentCache docCache = new DocumentCache();
  +    private QueryEngine engine = new QueryEngine(this);
  +    private boolean metaEnabled = false;
  +    private boolean metaInit = false;
  +    private MetaSystemCollection metaSystemCollection = null;
  +    private boolean sysInit = false;
  +    private SystemCollection systemCollection = null;
  +    /** key = canonical name, value = timerecord */
  +    private Map timestamps = new HashMap();
  +
  +    /**
  +     * @see org.apache.xindice.core.DBObject#close()
  +     */
  +    public boolean close() throws DBException {
  +        flushConfig();
  +
  +        synchronized (databases) {
  +            databases.remove(getName());
  +        }
  +
  +        return true;
  +    }
  +
  +    /**
  +     * flushConfig ensures that the Collection configuration has been
  +     * properly flushed to disk after a modification.
  +     */
  +    public void flushConfig() {
  +
  +        try {
  +            Document d = getConfig().getElement().getOwnerDocument();
  +            
systemCollection.getCollection(SystemCollection.CONFIGS).setDocument(COLKEY, d);
  +        }
  +        catch (Exception e) {
  +            log.error("Error Writing Configuration '" + getName() + "', for 
database " + getName(), e);
  +        }
  +
  +        // observer
  +        DBObserver.getInstance().flushDatabaseConfig(this, getConfig());
  +    }
  +
  +    /**
  +     * @see org.apache.xindice.core.Collection#getDatabase()
  +     */
  +    public Database getDatabase() {
  +        return this;
  +    }
  +
  +    /**
  +     * getDocumentCache returns the Database-level Document Cache.
  +     *
  +     * @return The DocumentCache
  +     */
  +    public DocumentCache getDocumentCache() {
  +        return docCache;
  +    }
  +
  +    /**
  +     * Return the MetaSystem collection for this database.
  +     * 
  +     * It will return null if metadata is not enabled on this database.
  +     * @return MetaSystemCollection
  +     */
  +    public MetaSystemCollection getMetaSystemCollection() {
  +        return metaSystemCollection;
  +    }
  +
  +    /**
  +     * getQueryEngine returns a reference to the Database's current
  +     * operating QueryEngine implementation.
  +     *
  +     * @return The QueryEngine instance
  +     */
  +    public QueryEngine getQueryEngine() {
  +        return engine;
  +    }
  +
  +    /**
  +     * @see org.apache.xindice.core.Collection#getSystemCollection()
  +     */
  +    public SystemCollection getSystemCollection() {
  +        return systemCollection;
  +    }
  +
  +    /**
  +     * @param path
  +     * @return
  +     */
  +    public synchronized TimeRecord getTime(String path) {
  +        TimeRecord rec = (TimeRecord) timestamps.get(path);
  +        return rec;
  +    }
  +
  +    /**
  +     * Return whether or not metadata is enabled on this database.
  +     * @return boolean
  +     */
  +    public boolean isMetaEnabled() {
  +        return metaEnabled;
  +    }
  +
  +    // methods for recording the times when meta data is enabled.
  +    public synchronized void recordTime(String path, long created, long 
modified) {
  +        TimeRecord rec = (TimeRecord) timestamps.get(path);
  +        if (null == rec) {
  +            rec = new TimeRecord(created, modified);
  +            timestamps.put(path, rec);
  +        }
  +        else {
  +            if (created > 0)
  +                rec.setCreatedTime(created);
  +            if (modified > 0)
  +                rec.setModifiedTime(modified);
  +        }
  +    }
  +
  +    /**
  +     * @param path
  +     */
  +    public synchronized void removeTime(String path) {
  +        timestamps.remove(path);
  +    }
  +
  +    /**
  +     * @see 
org.apache.xindice.util.Configurable#setConfig(org.apache.xindice.util.Configuration)
  +     */
  +    public void setConfig(Configuration config) throws XindiceException {
  +        super.setConfig(config);
  +
  +        setName(config.getAttribute(NAME));
  +        setCanonicalName('/' + getName());
  +
  +        String dbroot = config.getAttribute(DBROOT);
  +        File dbrootDir = new File(dbroot);
  +        if (!dbrootDir.isAbsolute()) {
  +            dbrootDir = new File(System.getProperty(PROP_XINDICE_HOME), 
dbroot);
  +        }
  +        setCollectionRoot(dbrootDir);
  +        log.info("Database points to " + dbrootDir.getAbsolutePath());
  +        log.debug("Database dir exists: " + (dbrootDir == null ? false : 
dbrootDir.exists()));
  +
  +        try {
  +            Configuration queryCfg = config.getChild(QUERYENGINE);
  +            if (queryCfg != null)
  +                this.engine.setConfig(queryCfg);
  +        }
  +        catch (Exception e) {
  +
  +            log.warn(e);
  +        }
  +
  +        if (!sysInit) {
  +            this.systemCollection = new SystemCollection(this);
  +
  +            try {
  +                this.systemCollection.init();
  +            }
  +            catch (XindiceException e) {
  +                log.warn(e);
  +            }
  +
  +            super.addCollection(systemCollection);
  +            this.sysInit = true;
  +        }
  +
  +        try {
  +            // Bootstrap from the database itself...  This is accomplished
  +            // by intercepting the setConfig call and using a Configuration
  +            // retrieved from the database instead of the standard config
  +            Document colDoc = 
systemCollection.getCollection(SystemCollection.CONFIGS).getDocument(COLKEY);
  +            if (colDoc == null) {
  +                DocumentBuilder db = 
DocumentBuilderFactory.newInstance().newDocumentBuilder();
  +                colDoc = db.newDocument();
  +                Element root = colDoc.createElement(DATABASE);
  +                root.setAttribute(NAME, getName());
  +                colDoc.appendChild(root);
  +                
systemCollection.getCollection(SystemCollection.CONFIGS).setDocument(COLKEY, 
colDoc);
  +            }
  +
  +            super.setConfig(new Configuration(colDoc.getDocumentElement(), 
false));
  +        }
  +        catch (Exception e) {
  +            log.warn(e);
  +        }
  +
  +        // Register the Database with the VM
  +        // databases.put(getName(), this);
  +
  +        // initialize the meta collection
  +        // but only if it's turned on in the config.
  +        String metaCfg = config.getAttribute(METADATA);
  +        if (metaCfg.equalsIgnoreCase("on")) {
  +            metaEnabled = true;
  +            if (!metaInit) {
  +                this.metaSystemCollection = new MetaSystemCollection(this);
  +                try {
  +                    this.metaSystemCollection.init();
  +                }
  +                catch (XindiceException e) {
  +                    log.warn("Error initializing the meta collection", e);
  +                }
  +                // should this attach the meta collection to the database?
  +
  +                super.addCollection(metaSystemCollection);
  +                metaInit = true;
  +                log.info("Meta information initialized");
  +            }
  +        }
  +
  +        // observer
  +        DBObserver.getInstance().setDatabaseConfig(this, getCollections(), 
config);
  +    }
   }
  
  
  
  1.21      +1485 
-1476xml-xindice/java/src/org/apache/xindice/core/Collection.java
  
  Index: Collection.java
  ===================================================================
  RCS file: 
/home/cvs/xml-xindice/java/src/org/apache/xindice/core/Collection.java,v
  retrieving revision 1.20
  retrieving revision 1.21
  diff -u -r1.20 -r1.21
  --- Collection.java   14 Jul 2003 17:23:56 -0000      1.20
  +++ Collection.java   14 Jul 2003 19:07:15 -0000      1.21
  @@ -58,7 +58,13 @@
    *
    * $Id$
    */
  +import java.io.File;
  +import java.io.UnsupportedEncodingException;
  +import java.net.InetAddress;
  +import java.util.ArrayList;
   
  +import org.apache.commons.logging.Log;
  +import org.apache.commons.logging.LogFactory;
   import org.apache.xindice.core.data.DocumentSet;
   import org.apache.xindice.core.data.EmptyDocumentSet;
   import org.apache.xindice.core.data.EmptyNodeSet;
  @@ -70,10 +76,10 @@
   import org.apache.xindice.core.filer.Filer;
   import org.apache.xindice.core.indexer.IndexManager;
   import org.apache.xindice.core.indexer.Indexer;
  +import org.apache.xindice.core.meta.MetaData;
   import org.apache.xindice.core.meta.inline.InlineMetaMap;
   import org.apache.xindice.core.meta.inline.InlineMetaService;
   import org.apache.xindice.core.meta.inline.ResourceTypeReader;
  -import org.apache.xindice.core.meta.MetaData;
   import org.apache.xindice.core.query.QueryEngine;
   import org.apache.xindice.util.Configurable;
   import org.apache.xindice.util.Configuration;
  @@ -94,14 +100,6 @@
   import org.w3c.dom.NodeList;
   import org.w3c.dom.ProcessingInstruction;
   
  -import org.apache.commons.logging.Log;
  -import org.apache.commons.logging.LogFactory;
  -
  -import java.io.File;
  -import java.io.UnsupportedEncodingException;
  -import java.net.InetAddress;
  -import java.util.ArrayList;
  -
   /**
    * Collection represents a collection of Documents maintains links to
    * the Filer storage implementation, and the Indexes associated with
  @@ -109,1470 +107,1481 @@
    **/
   
   public class Collection extends CollectionManager implements Named, 
DBObject, Configurable {
  -     private static final String NAME = "name";
  -     private static final String FILER = "filer";
  -     private static final String CLASS = "class";
  -     private static final String INDEXES = "indexes";
  -     private static final String INLINE_METADATA = "inline-metadata";
  -     private static final String COMPRESSED = "compressed";
  -     private static final String CACHE = "cache";
  -     private static final String SYMBOLS = "symbols";
  -     private static final String CLASSNAME = "xindice-class";
  -
  -     private static final DocumentSet EMPTY_DOCUMENTSET = new 
EmptyDocumentSet();
  -     private static final NodeSet EMPTY_NODESET = new EmptyNodeSet();
  -     private static final String[] EMPTY_STRING_ARRAY = {};
  -
  -     private static Log log = LogFactory.getLog("org.apache.xindice.core");
  -
  -     private static int host_id;
  -     static {
  -             try {
  -                     InetAddress a = InetAddress.getLocalHost();
  -                     byte[] b = a.getAddress();
  -                     host_id = 0;
  -                     host_id += b[0];
  -                     host_id += (b[1] << 8);
  -                     host_id += (b[2] << 16);
  -                     host_id += (b[3] << 24);
  -                     host_id = Math.abs(host_id);
  -             }
  -             catch (Exception e) {}
  -     };
  -
  -     private Collection parent = null;
  -
  -     // Object ID Stuff
  -     private int collection_id = 0;
  -     private long document_id = System.currentTimeMillis();
  -     private Object oidMutex = new Object();
  -     private String oidTemplate = null;
  -
  -     protected String name;
  -     private String canonicalName;
  -     private File collectionRoot;
  -
  -     private Filer filer = null;
  -
  -     private boolean compressed = false;
  -     private SymbolTable symbols = null;
  -     private boolean internalSymbols = false;
  -
  -     private IndexManager indexManager;
  -     private DocumentCache documentCache;
  -
  -     private InlineMetaService inlineMetaService;
  -
  -     protected Collection() {}
  -
  -     public Collection(Collection collection) {
  -             this();
  -             parent = collection;
  -     }
  -
  -     public void setConfig(Configuration config) throws XindiceException {
  -             this.config = config;
  -
  -             name = config.getAttribute(NAME);
  -             compressed = config.getBooleanAttribute(COMPRESSED, true);
  -
  -             /*
  -              * If inline metadata is desired, get an InlineMetaService 
object.
  -              */
  -             if (config.getBooleanAttribute(INLINE_METADATA, false)) {
  -                     inlineMetaService = new InlineMetaService();
  -             }
  -
  -             /*
  -              * Wait to set up the local debug header until everything needed
  -              * by debugHeader() is complete!
  -              */
  -             String localDebugHeader = debugHeader() + "setConfig: ";
  -
  -             if (inlineMetaService == null) {
  -                     log.debug(localDebugHeader + "inline metadata 
DISABLED");
  -             }
  -             else {
  -                     log.debug(localDebugHeader + "inline metadata ENABLED");
  -             }
  -
  -             if (parent != null) {
  -                     setCanonicalName(parent.getCanonicalName() + '/' + 
name);
  -                     log.debug(localDebugHeader + "canonical name=<" + 
getCanonicalName() + ">");
  -                     setCollectionRoot(new File(parent.getCollectionRoot(), 
name));
  -                     log.debug(localDebugHeader + "collection root=<" + 
getCollectionRoot().toString() + ">");
  -             }
  -
  -             if (config.getBooleanAttribute(CACHE, true))
  -                     documentCache = getDatabase().getDocumentCache();
  -
  -             // If no Filer is defined, skip Symbols and Indexes
  -             Configuration filerConfig = config.getChild(FILER);
  -             if (filerConfig != null) {
  -                     log.debug(localDebugHeader + "have filer config...");
  -
  -                     // Symbol Table Setup
  -                     Configuration symConfig = config.getChild(SYMBOLS);
  -                     internalSymbols = (symConfig != null);
  -                     if (internalSymbols) {
  -                             log.debug(localDebugHeader + "have internal 
symbols <" + TextWriter.toString(symConfig.getElement()) + ">");
  -                             try {
  -                                     symbols = new 
SymbolTable(symConfig.getElement());
  -                             }
  -                             catch (Exception e) {
  -                                     if (log.isDebugEnabled()) {
  -                                             log.debug("Error building 
symbol table from internal symbols", e);
  -                                     }
  -                             }
  -                     }
  -                     else {
  -                             log.debug(localDebugHeader + "no internal 
symbols...");
  -                             try {
  -                                     symbols = 
getSystemCollection().loadSymbols(this);
  -                                     log.debug(
  -                                             localDebugHeader
  -                                                     + "loaded symbols from 
system collection <"
  -                                                     + 
TextWriter.toString(symbols.streamToXML(new DocumentImpl()))
  -                                                     + ">");
  -                             }
  -                             catch (Exception e) {
  -                                     if (log.isDebugEnabled()) {
  -                                             log.debug("Error building 
symbol table from system collection...", e);
  -                                     }
  -                             }
  -                     }
  -
  -                     String className = filerConfig.getAttribute(CLASS);
  -                     log.debug(localDebugHeader + "file class=<" + className 
+ ">");
  -                     try {
  -                             filer = (Filer) 
Class.forName(className).newInstance();
  -                             //            filer.setCollection(this);
  -                             filer.setLocation(getCollectionRoot(), 
getName());
  -                             filer.setConfig(filerConfig);
  -                             if (!filer.exists())
  -                                     filer.create();
  -                             filer.open();
  -                     }
  -                     catch (Exception e) {
  -                             if (log.isWarnEnabled()) {
  -                                     log.warn("Filer '" + className + "' not 
available", e);
  -                             }
  -                     }
  -
  -                     // Index Manager
  -                     try {
  -                             indexManager = new IndexManager(this);
  -                             Configuration idxConfig = 
config.getChild(INDEXES, true);
  -                             indexManager.setConfig(idxConfig);
  -                     }
  -                     catch (Exception e) {
  -                             if (log.isDebugEnabled()) {
  -                                     log.debug("No message", e);
  -                             }
  -                     }
  -             }
  -
  -             super.setConfig(config);
  -
  -             // observer
  -             DBObserver.getInstance().setCollectionConfig(this, config);
  -     }
  -
  -     public final String getName() {
  -             return name;
  -     }
  -
  -     public final File getCollectionRoot() {
  -             return collectionRoot;
  -     }
  -
  -     protected final void setCollectionRoot(File collectionRoot) {
  -             this.collectionRoot = collectionRoot;
  -             if (!collectionRoot.exists())
  -                     collectionRoot.mkdirs();
  -     }
  -
  -     /**
  -      * getParentCollection returns the parent Collection of this
  -      * Collection.
  -      *
  -      * @return The parent Collection (or null)
  -      */
  -     public final Collection getParentCollection() throws DBException {
  -             return parent;
  -     }
  -
  -     public final boolean dropCollection(Collection collection) throws 
DBException {
  -             boolean success = super.dropCollection(collection);
  -             getDatabase().flushConfig();
  -             return success;
  -     }
  -
  -     public final Collection createCollection(String path, Configuration 
config) throws DBException {
  -             Collection col = super.createCollection(path, config);
  -             getDatabase().flushConfig();
  -             return col;
  -     }
  -
  -     // Convenience Methods
  -
  -     /**
  -      * getDatabase returns the Database owner for this Collection.
  -      *
  -      * @return The Database
  -      */
  -     public Database getDatabase() {
  -             return parent.getDatabase();
  -     }
  -
  -     /**
  -      * getSystemCollection returns the System Collection.
  -      *
  -      * @return The System Collection
  -      */
  -     public SystemCollection getSystemCollection() throws DBException {
  -             return getDatabase().getSystemCollection();
  -     }
  -
  -     /**
  -      * getQueryEngine returns the Database's Query Engine
  -      *
  -      * @return The Query Engine
  -      */
  -     public QueryEngine getQueryEngine() throws DBException {
  -             return getDatabase().getQueryEngine();
  -     }
  -
  -     private void checkFiler(int faultCode) throws DBException {
  -             if (filer == null)
  -                     throw new DBException(faultCode, "This Collection '" + 
name + "' cannot store Documents");
  -     }
  -
  -     /**
  -      * getIndexer retrieves an Indexer by name.
  -      *
  -      * @param name The Indexer name
  -      * @return The Indexer (or null)
  -      */
  -     public final Indexer getIndexer(String name) throws DBException {
  -             checkFiler(FaultCodes.COL_NO_INDEXMANAGER);
  -             return indexManager.get(name);
  -     }
  -
  -     /**
  -      * listIndexers returns a list of the currently registered Indexers
  -      * as an array of String.
  -      *
  -      * @return The Indexer list
  -      */
  -     public final String[] listIndexers() throws DBException {
  -             checkFiler(FaultCodes.COL_NO_INDEXMANAGER);
  -             return indexManager.list();
  -     }
  -
  -     /**
  -      * dropIndexer physically removes the specified Indexer and any
  -      * associated system resources that the Indexer uses.
  -      *
  -      * @param index The Indexer to drop
  -      * @return Whether or not the Indexer was dropped
  -      */
  -     public final boolean dropIndexer(Indexer index) throws DBException {
  -             checkFiler(FaultCodes.COL_NO_INDEXMANAGER);
  -
  -             if (index == null)
  -                     throw new DBException(FaultCodes.IDX_INDEX_NOT_FOUND, 
"Index Value Null");
  -
  -             boolean success = indexManager.drop(index.getName());
  -             getDatabase().flushConfig();
  -             return success;
  -     }
  -
  -     /**
  -      * createIndexer creates a new Indexer object and any associated
  -      * system resources that the Indexer will need.
  -      *
  -      * @param config The Indexer's configuration
  -      * @return The newly created Indexer
  -      */
  -     public final Indexer createIndexer(Configuration config) throws 
DBException {
  -             checkFiler(FaultCodes.COL_NO_INDEXMANAGER);
  -             Indexer idx = indexManager.create(config);
  -             getDatabase().flushConfig();
  -             return idx;
  -     }
  -
  -     /**
  -      * getFiler returns the low-level Filer instances underlying the
  -      * Collection instance.
  -      *
  -      * @return The requested Filer
  -      */
  -     public final Filer getFiler() {
  -             return filer;
  -     }
  -
  -     /**
  -      * return the IndexManager being used by this Collection.
  -      *
  -      * @return The IndexManager
  -      */
  -     public final IndexManager getIndexManager() throws DBException {
  -             checkFiler(FaultCodes.COL_NO_INDEXMANAGER);
  -             return indexManager;
  -     }
  -
  -     /**
  -      * getSymbols returns the SymbolTable in use by this
  -      * Collection.
  -      *
  -      * @return The Symbol Table
  -      */
  -     public final SymbolTable getSymbols() throws DBException {
  -             return symbols;
  -     }
  -
  -     /**
  -      * Turns an XML string into a parsed document and caches it.
  -      *
  -      * @param key The key to use when caching
  -      * @param xml The string to parse
  -      * @return A parsed DOM document or null if failure
  -      */
  -     private Document parseDocument(Key key, String xml) throws DBException {
  -             Document doc = null;
  -             try {
  -                     doc = DOMParser.toDocument(xml);
  -
  -                     // Have to move it to Xindice DOM for XMLObject 
AutoLinking
  -                     byte[] b = DOMCompressor.Compress(doc, symbols);
  -                     doc = new DocumentImpl(b, symbols, new NodeSource(this, 
key));
  -
  -                     if (documentCache != null)
  -                             documentCache.putDocument(this, key, b);
  -             }
  -             catch (Exception e) {
  -                     throw new 
DBException(FaultCodes.COL_DOCUMENT_MALFORMED, "Unable to parse Document", e);
  -             }
  -             return doc;
  -     }
  -
  -     /**
  -      * getCanonicalName returns the canonical name for this Object.
  -      * <br>
  -      * ex: /local/test/ocs
  -      *
  -      * @return The canonical name
  -      */
  -     public final String getCanonicalName() {
  -             return canonicalName;
  -     }
  -
  -     protected final void setCanonicalName(String canonicalName) {
  -             this.canonicalName = canonicalName;
  -
  -             // Calculate The OID Template
  -             collection_id = Math.abs(canonicalName.hashCode());
  -             StringBuffer sb = new 
StringBuffer("00000000000000000000000000000000");
  -             String host = Integer.toString(host_id, 16);
  -             String collection = Integer.toString(collection_id, 16);
  -             sb.insert(8 - host.length(), host);
  -             sb.insert(16 - collection.length(), collection);
  -             sb.setLength(32);
  -             oidTemplate = sb.toString();
  -     }
  -
  -     /**
  -      * getCanonicalDocumentName returns the canonical name for the specified
  -      * Key in relation to this Collection.
  -      * <br>
  -      * ex: /local/test/ocs/ytd
  -      *
  -      * @param key The Key
  -      * @return The canonical name
  -      */
  -     public final String getCanonicalDocumentName(Key key) {
  -             return getCanonicalDocumentName(key.toString());
  -     }
  -
  -     public final String getCanonicalDocumentName(String key) {
  -             StringBuffer sb = new StringBuffer();
  -             sb.append(canonicalName);
  -             sb.append('/');
  -             sb.append(key);
  -             return sb.toString();
  -     }
  -
  -     public final boolean open() throws DBException {
  -             return true;
  -     }
  -
  -     public boolean isOpened() throws DBException {
  -             return true;
  -     }
  -
  -     public boolean exists() throws DBException {
  -             return true;
  -     }
  -
  -     public boolean close() throws DBException {
  -             return true;
  -     }
  -
  -     public boolean create() throws DBException {
  -             // update the meta information if necessary
  -             updateCollectionMeta();
  -             
  -             DBObserver.getInstance().createCollection(this);
  -             return true;
  -     }
  -
  -     public boolean drop() throws DBException {
  -             if (this == getDatabase())
  -                     throw new DBException(FaultCodes.DBE_CANNOT_DROP, "You 
Cannot Drop The Database");
  -
  -             DBObserver.getInstance().dropCollection(this);
  -
  -             // drop the meta if necessary
  -             if (isMetaEnabled()) {
  -                     MetaSystemCollection metacol = 
getMetaSystemCollection();
  -                     metacol.dropCollectionMeta(this);
  -             }
  -
  -             // Drop Child Collections
  -             String[] cols = listCollections();
  -             for (int i = 0; i < cols.length; i++)
  -                     dropCollection(getCollection(cols[i]));
  -
  -             if (filer != null) {
  -                     // Drop Indexers
  -                     String[] idx = indexManager.list();
  -                     for (int i = 0; i < idx.length; i++)
  -                             dropIndexer(getIndexer(idx[i]));
  -
  -                     // Now Drop The Filer
  -                     filer.drop();
  -             }
  -
  -             getCollectionRoot().delete();
  -             getDatabase().flushConfig();
  -
  -             return true;
  -     }
  -
  -     // All Document Handling Code Follows
  -
  -     /**
  -      * createNewOID allocates a new Object ID to be used as a Key in the
  -      * Collection.
  -      *
  -      * @return The newly generated Key
  -      */
  -     public final Key createNewOID() {
  -             long ct = System.currentTimeMillis();
  -
  -             synchronized (oidMutex) {
  -                     if (ct <= document_id)
  -                             ct = document_id + 1;
  -                     document_id = ct;
  -             }
  -
  -             StringBuffer sb = new StringBuffer(oidTemplate);
  -             String document = Long.toString(document_id, 16);
  -             sb.insert(32 - document.length(), document);
  -             sb.setLength(32);
  -
  -             return new Key(sb.toString());
  -     }
  -
  -     /**
  -      * createNewKey allocates a new Key to be used as a Key in the
  -      * Collection.
  -      *
  -      * @param key The Key hint
  -      * @return The newly generated Key
  -      */
  -     protected final Key createNewKey(Object key) {
  -             if (key == null)
  -                     return createNewOID();
  -             if (key instanceof Key)
  -                     return (Key) key;
  -             else
  -                     return new Key(key.toString());
  -     }
  -
  -     public final void flushSymbolTable() throws DBException {
  -             if (symbols.isDirty() && !internalSymbols)
  -                     getSystemCollection().saveSymbols(this, symbols);
  -     }
  -
  -     /*
  -      * Lowest-level method for saving a binary entry into the database.
  -      * Does not update non-inline metadata.
  -      */
  -     private void putBinary(Key key, byte[] bytes, boolean create) throws 
DBException {
  -
  -             if (inlineMetaService == null) {
  -                     throw new DBException(
  -                             FaultCodes.COL_CANNOT_STORE,
  -                             "Cannot store a binary resource in collection " 
+ name + ": inline-metadata is not enabled");
  -             }
  -
  -             if (!create) {
  -                     byte[] storedBytes = getBinary(key);
  -                     if (storedBytes == null) {
  -                             /*
  -                              * XXX TODO
  -                              * Do we need a COL_KEY_ALREADY_PRESENT fault
  -                              * so that the caller can interpret this 
exception?
  -                              */
  -                             throw new DBException(
  -                                     FaultCodes.COL_CANNOT_STORE,
  -                                     "Error storing binary object with key 
'" + key + "': the 'create' flag is false and" + " the key is not in the 
database");
  -                     }
  -             }
  -
  -             InlineMetaMap map = inlineMetaService.getEmptyMap();
  -             map.put("type", ResourceTypeReader.BINARY);
  -             Value value = inlineMetaService.createValue(map, bytes, 0, 
bytes.length);
  -             filer.writeRecord(key, value);
  -     }
  -
  -     /**
  -      * This is the lowest-level method for storing a record into the 
backing store.
  -      * It does not update non-inline metadata.
  -      */
  -     private void putDocument(Key key, Document document /* TODO used this 
variable , boolean create*/
  -     ) throws DBException {
  -
  -             String localDebugHeader = debugHeader() + "putDocument: 
docKey=<" + key.toString() + ">: ";
  -
  -             log.debug(localDebugHeader + "document=<" + 
TextWriter.toString(document).toString() + ">");
  -
  -             checkFiler(FaultCodes.COL_NO_FILER);
  -
  -             if (document instanceof DBDocument) {
  -                     // This is a shitty shitty hack... Kill immediately
  -                     DBDocument dbDoc = (DBDocument) document;
  -                     if (dbDoc.getSource() == null)
  -                             dbDoc.setSource(new NodeSource(this, key));
  -             }
  -
  -             /*
  -              * The possibilities are restricted because only XML
  -              * is handled by this method.  There are only a few
  -              * pieces of information that need to be constructed:
  -              * 1) the xindice DOM document is needed for all XML objects, as
  -              *         it is handed to the IndexManager and the DBObserver.
  -              * 2) the packed document, if this is a compressed XML object,
  -              *        is needed for the cache and the BTree (via the Value 
object).
  -              * 3) the string-converted-to-utf-8 bytes, if this is a 
non-compressed
  -              *        XML object, is needed for the BTree (via the Value 
object).
  -              * 4) A Value object, with a header if headers are enabled, and
  -              *        otherwise without headers, for the BTree.
  -              */
  -
  -             byte[] packedDocument = null;
  -             byte[] utf8Document = null;
  -
  -             if (compressed) {
  -                     try {
  -
  -                             packedDocument = 
DOMCompressor.Compress(document, symbols);
  -                             log.debug(localDebugHeader + "length=" + 
packedDocument.length);
  -
  -                             // Why must it be re-created?
  -                             document = new DocumentImpl(packedDocument, 
symbols, new NodeSource(this, key));
  -
  -                             log.debug(localDebugHeader + "packedDocument: 
length=" + packedDocument.length + " document=<" + 
TextWriter.toString(document) + ">");
  -                     }
  -                     catch (Exception e) {
  -                             throw new 
DBException(FaultCodes.COL_CANNOT_STORE, localDebugHeader + "Error compressing 
Document '" + key + "'", e);
  -                     }
  -             }
  -             else {
  -                     try {
  -                             utf8Document = 
TextWriter.toString(document).getBytes("utf-8");
  -                             log.debug(localDebugHeader + "utf8Document: 
length=" + utf8Document.length + " document=<" + new String(utf8Document, 
"utf-8") + ">");
  -                     }
  -                     catch (UnsupportedEncodingException e) {
  -                             throw new 
DBException(FaultCodes.GEN_FATAL_ERROR, "utf-8 encoding not supported", e);
  -                     }
  -             }
  -
  -             /*
  -              * XXX TODO
  -              * Can this be moved into the if(compressed) block?
  -              */
  -             flushSymbolTable();
  -
  -             // Temporary until insert and update are separate
  -             Document oldDoc = getDocument(key);
  -             if (oldDoc != null) {
  -                     indexManager.removeDocument(key, oldDoc);
  -             }
  -             indexManager.addDocument(key, document);
  -
  -             /*
  -              * Construct the Value object that is stored in the BTree.
  -              */
  -             Value value;
  -             if (inlineMetaService == null) {
  -                     if (compressed) {
  -                             value = new Value(packedDocument);
  -                     }
  -                     else {
  -                             value = new Value(utf8Document);
  -                     }
  -             }
  -             else {
  -                     InlineMetaMap map = inlineMetaService.getEmptyMap();
  -                     map.put("type", ResourceTypeReader.XML);
  -                     if (compressed) {
  -                             value = inlineMetaService.createValue(map, 
packedDocument, 0, packedDocument.length);
  -                     }
  -                     else {
  -                             value = inlineMetaService.createValue(map, 
utf8Document, 0, utf8Document.length);
  -                     }
  -             }
  -             filer.writeRecord(key, value);
  -
  -             // Cache Stuff
  -             if (documentCache != null) {
  -                     if (compressed)
  -                             documentCache.putDocument(this, key, 
packedDocument);
  -                     else
  -                             documentCache.putDocument(this, key, document);
  -             }
  -
  -             DBObserver.getInstance().putDocument(this, key, document, 
oldDoc == null);
  -     }
  -
  -     /**
  -      * update the modified time of this collection when appropriate
  -      */
  -     protected void updateCollectionMeta() {
  -             // update the meta data if necessary
  -             if (isMetaEnabled()) {
  -                     MetaSystemCollection metacol = 
getMetaSystemCollection();
  -                     MetaData meta = null;
  -                     try {
  -                             meta = metacol.getCollectionMeta(this);
  -                     }
  -                     catch (DBException e) {
  -                             // something strange has happened.. can't get 
the
  -                             // meta data for this collection
  -                             if (log.isWarnEnabled())
  -                                     log.warn("Error fetching collection 
meta. " + e);
  -                             return;
  -                     }
  -
  -                     if (log.isInfoEnabled())
  -                             log.info("Updating modified time for this 
collection's meta");
  -                     long now = System.currentTimeMillis();
  -                     if (null == meta) {
  -                             meta = new MetaData(MetaData.COLLECTION, 
getCanonicalName(), now, now);
  -                     }
  -                     else {
  -                             // this collection already has a meta.  so 
update its modified time.
  -                             meta.setContext(0, now);
  -                     }
  -                     try {
  -                             metacol.setCollectionMeta(this, meta);
  -                     }
  -                     catch (DBException e) {
  -                             if (log.isWarnEnabled())
  -                                     log.warn("Error setting the collection 
meta. " + e);
  -                             return;
  -                     }
  -             }
  -     }
  -
  -     /**
  -      * update the modified time of this document when appropriate
  -      */
  -     protected void updateDocumentMeta(String id) throws DBException {
  -             // update the meta data if necessary
  -             if (!isMetaEnabled())
  -                     return;
  -
  -             Document doc = getDocument(id);
  -             if (null == doc)
  -                     throw new 
DBException(FaultCodes.COL_DOCUMENT_NOT_FOUND, "Document " + id + " does not 
exist");
  -
  -             MetaSystemCollection metacol = getMetaSystemCollection();
  -             MetaData meta = metacol.getDocumentMeta(this, id);
  -
  -             String path = getCanonicalDocumentName(id);
  -
  -             /*
  -             TimeRecord rec = null;
  -             if( null == meta || !meta.hasContext() )
  -                rec = getDatabase().getTime(path);
  -             
  -             long created = (null != rec) ? rec.getCreatedTime() : 
System.currentTimeMillis();
  -             long modified = (null != rec) ? rec.getModifiedTime() : 
System.currentTimeMillis();
  -             */
  -
  -             // this is wrong.. but it should work for now...
  -             long created = System.currentTimeMillis();
  -             long modified = System.currentTimeMillis();
  -
  -             if (null == meta) {
  -                     meta = new MetaData(MetaData.DOCUMENT, path, created, 
modified);
  -             }
  -             else if (!meta.hasContext()) {
  -                     meta.setContext(created, modified);
  -             }
  -             else {
  -                     meta.setContext(0, modified);
  -             }
  -             metacol.setDocumentMeta(this, id, meta);
  -     }
  -
  -     /**
  -      * insertBinary inserts a new binary object into a Xindice Collection.
  -      *
  -      * @param docKey The document Key
  -      * @param document The document to insert
  -      * @throws DBException if inline-metadata is not enabled, the key is
  -      *         already in the database, or an error occurs while saving.
  -      */
  -     public void insertBinary(Object docKey, byte[] bytes) throws 
DBException {
  -
  -             if (inlineMetaService == null) {
  -                     throw new DBException(
  -                             FaultCodes.COL_CANNOT_STORE,
  -                             "Cannot insert a binary resource in collection 
" + name + ": inline-metadata is not enabled.");
  -             }
  -
  -             putBinary(createNewKey(docKey), bytes, true);
  -
  -             // update the meta information if necessary
  -             updateCollectionMeta();
  -     }
  -
  -     /**
  -      * Insert a binary object into a Xindice Collection.  A unique key
  -      * is automatically generated. by which the binary object can be
  -      * retrieved in the future.  Note: because the key is automatically
  -      * unique, this insert method will never cause a collision with an
  -      * object already in the database.
  -      *
  -      * @param bytes The bytes making up the binary object to insert
  -      * @return Key automatically generated for the binary object
  -      * @throws DBException if inline-metadata is not enabled, or an
  -      *         error occurs while saving.
  -      */
  -     public Key insertBinary(byte[] bytes) throws DBException {
  -
  -             if (inlineMetaService == null) {
  -                     throw new DBException(
  -                             FaultCodes.COL_CANNOT_STORE,
  -                             "Cannot insert a binary resource in collection 
" + name + ": inline-metadata is not enabled.");
  -             }
  -
  -             Key key = createNewOID();
  -             putBinary(key, bytes, true);
  -
  -             // update the meta information if necessary
  -             updateCollectionMeta();
  -
  -             return key;
  -     }
  -
  -     /**
  -      * insertDocument inserts a new Document into a Xindice Collection.
  -      *
  -      * @param document The Document
  -      * @return The new Object Identifier
  -      */
  -     public final Key insertDocument(Document document) throws DBException {
  -             Key key = createNewOID();
  -             putDocument(key, document /*, true */
  -             );
  -             // update the meta information if necessary
  -             updateCollectionMeta();
  -             return key;
  -     }
  -
  -     /**
  -      * insertDocument inserts a new Document into a Xindice Collection.
  -      *
  -      * @param docKey The document Key
  -      * @param document The document to insert
  -      */
  -     public final void insertDocument(Object docKey, Document document) 
throws DBException {
  -             putDocument(createNewKey(docKey), document /*, true */
  -             );
  -             // update the meta information if necessary
  -             updateCollectionMeta();
  -     }
  -
  -     /**
  -      * setDocument overwrites/updates an existing Document in a
  -      * Xindice Collection.
  -      *
  -      * @param docKey The Document Key
  -      * @param document The Document
  -      */
  -     public final void setDocument(Object docKey, Document document) throws 
DBException {
  -             putDocument(createNewKey(docKey), document /*, false */
  -             );
  -             // update the meta for this document
  -             updateDocumentMeta(docKey.toString());
  -     }
  -
  -     /**
  -      * remove removes an object from the Collection based on its Key,
  -      * regardless of it's type.
  -      *
  -      * @param key The Object's Key
  -      */
  -     public final void remove(Object key) throws DBException {
  -             checkFiler(FaultCodes.COL_NO_FILER);
  -
  -             Key objKey = createNewKey(key);
  -
  -             Document oldDoc = getDocument(objKey);
  -             if (oldDoc != null)
  -                     indexManager.removeDocument(objKey, oldDoc);
  -
  -             if (documentCache != null)
  -                     documentCache.removeDocument(this, objKey);
  -
  -             if (!filer.deleteRecord(objKey))
  -                     throw new 
DBException(FaultCodes.COL_DOCUMENT_NOT_FOUND, "Document Does Not Exist");
  -
  -             // update the meta for this collection if necessary
  -             updateCollectionMeta();
  -             // remove the document meta
  -             if (isMetaEnabled()) {
  -                     getMetaSystemCollection().dropDocumentMeta(this, 
objKey.toString());
  -             }
  -             DBObserver.getInstance().dropDocument(this, objKey);
  -     }
  -
  -     /**
  -      * Retrieve a binary database entry by key.
  -      * This low-level method will not update non-inline metadata.
  -      *
  -      * @param docKey identifying the desired database entry
  -      * @return byte[] containing the binary database entry
  -      * @throws DBException if inline-metadata is not enabled
  -      *         (binary resource cannot be stored in a collection
  -      *             which does not have inline-metadata enabled),
  -      *         in case of backing store error, and in case of
  -      *         header corruption
  -      */
  -     public final byte[] getBinary(Object docKey) throws DBException {
  -
  -             log.debug(debugHeader() + "getBinary: docKey=<" + 
docKey.toString() + ">");
  -
  -             if (inlineMetaService != null) {
  -                     throw new DBException(
  -                             FaultCodes.COL_DOCUMENT_NOT_FOUND,
  -                             "There are no binary resources in collection" + 
name + ": inline-metadata is not enabled.");
  -             }
  -
  -             Object entry = getEntry(docKey);
  -             if (entry == null) {
  -                     return null;
  -             }
  -
  -             if (!(entry instanceof byte[])) {
  -                     throw new DBException(
  -                             FaultCodes.COL_INVALID_RESULT,
  -                             "The resource associated with key '" + 
docKey.toString() + "' in collection '" + name + "'is not binary");
  -             }
  -
  -             return (byte[]) entry;
  -     }
  -
  -     /**
  -      * getDocument retrieves a Document by Key.
  -      *
  -      * @param docKey The Document Key
  -      * @return The Document
  -      */
  -     public final Document getDocument(Object docKey) throws DBException {
  -
  -             log.debug(debugHeader() + "getDocument: docKey=<" + 
docKey.toString() + ">");
  -
  -             Object entry = getEntry(docKey);
  -             if (entry == null) {
  -                     return null;
  -             }
  -
  -             if (!(entry instanceof Document)) {
  -                     throw new DBException(
  -                             FaultCodes.COL_INVALID_RESULT,
  -                             "The resource associated with key '" + 
docKey.toString() + "' in collection '" + name + "'is not XML");
  -             }
  -
  -             return (Document) entry;
  -     }
  -
  -     /**
  -      * Retrieve a database entry by key.
  -      * If no matching entry is found, null is returned; if
  -      * an XML entry is found, a Document is returned; if a
  -      * binary entryis found, byte[] is returned.
  -      * This low-level method will not update non-inline metadata.
  -      *
  -      * @param docKey identifying the desired database entry
  -      * @return Object containing the database entry, or null if no
  -      *         matching entry is found
  -      * @throws DBException in case of backing store error,
  -      *         and in case of header corruption
  -      */
  -     public final Object getEntry(Object docKey) throws DBException {
  -
  -             /*
  -              * I would prefer to throw an exception (NPE) in this case,
  -              * but we have a test indicating a null return...
  -              */
  -             if (docKey == null) {
  -                     return null;
  -             }
  -
  -             String localDebugHeader = debugHeader() + "getEntry: docKey=<" 
+ docKey.toString() + ">: ";
  -
  -             log.debug(localDebugHeader);
  -
  -             checkFiler(FaultCodes.COL_NO_FILER);
  -
  -             Key key = createNewKey(docKey);
  -
  -             /*
  -              * If the key has a corresponding value in the cache, return it
  -              * and save a disk access.
  -              * 
  -              * At some point the current document-centric cache 
implementation
  -              * needs to be converted to an entry cache which can hold both
  -              * Document and byte[].
  -              */
  -             if (documentCache != null) {
  -                     Document document = documentCache.getDocument(this, 
key);
  -                     log.debug(localDebugHeader + "cache search returned: " 
+ document);
  -                     if (document != null) {
  -                             return document;
  -                     }
  -             }
  -
  -             Record record = filer.readRecord(key);
  -             if (record == null) {
  -                     return null;
  -             }
  -
  -             log.debug(localDebugHeader + "record value: length=" + 
record.getValue().getLength());
  -
  -             Value value;
  -             InlineMetaMap metaMap = null;
  -             if (inlineMetaService == null) {
  -                     log.debug(localDebugHeader + "type not available");
  -                     value = record.getValue();
  -             }
  -             else {
  -                     log.debug(localDebugHeader + "decomposing header...");
  -                     InlineMetaService.DatabaseEntry databaseEntry = 
inlineMetaService.readDatabaseEntry(record.getValue());
  -                     metaMap = databaseEntry.map;
  -                     value = databaseEntry.value;
  -
  -                     log.debug(localDebugHeader + "type=" + 
metaMap.get("type") + " length=" + value.getLength());
  -             }
  -
  -             if (inlineMetaService == null || 
metaMap.get("type").equals(ResourceTypeReader.XML)) {
  -
  -                     log.debug(localDebugHeader + "XML document");
  -
  -                     Document document;
  -                     if (compressed) {
  -
  -                             document = new DocumentImpl(value.getData(), 
symbols, new NodeSource(this, key));
  -
  -                             flushSymbolTable();
  -
  -                             log.debug(localDebugHeader + "compressed XML 
document: document=<" + TextWriter.toString(document) + ">");
  -
  -                             if (documentCache != null) {
  -                                     documentCache.putDocument(this, key, 
value.getData());
  -                             }
  -                     }
  -                     else {
  -                             log.debug(localDebugHeader + "pre 
parseDocument(): value=<" + value.toString() + ">");
  -                             document = parseDocument(key, value.toString());
  -                     }
  -
  -                     DBObserver.getInstance().loadDocument(this, record, 
document);
  -                     return document;
  -             }
  -             else {
  -                     return value.getData();
  -             }
  -     }
  -
  -     /**
  -      * getContainer retrieves a Container from the Collection.  The 
Container
  -      * encapsulates all information needed in dealing with a Document 
outside
  -      * of the context of a Collection (ex: DocumentContext).
  -      *
  -      * @param docKey The Document Key
  -      * @return The Container
  -      */
  -     public final Container getContainer(Object docKey) throws DBException {
  -             Key key = createNewKey(docKey);
  -             Document doc = getDocument(key);
  -             return doc != null ? new ColContainer(key, doc) : null;
  -     }
  -
  -     /**
  -      * getObject instantiates and returns an XMLSerializable object based 
on the
  -      * provided Key.  Xindice takes care of instantiating the correct 
class, but
  -      * only if a class was registered with the Document in the first place.
  -      *
  -      * @param key The Document Key
  -      * @return an Castable XMLSerializable Instance
  -      */
  -     public final XMLSerializable getObject(Object key) throws DBException {
  -             String className = null;
  -
  -             Document doc = getDocument(key);
  -
  -             if (doc != null) {
  -                     NodeList childNodes = doc.getChildNodes();
  -                     int size = childNodes.getLength();
  -                     for (int i = 0; i < size; i++) {
  -                             Node n = childNodes.item(i);
  -                             if (n.getNodeType() == 
Node.PROCESSING_INSTRUCTION_NODE && n.getNodeName().equals(CLASSNAME)) {
  -                                     className = n.getNodeValue().trim();
  -                                     break;
  -                             }
  -                     }
  -
  -                     if (className != null) {
  -                             try {
  -                                     XMLSerializable obj = (XMLSerializable) 
Class.forName(className).newInstance();
  -                                     
obj.streamFromXML(doc.getDocumentElement());
  -                                     return obj;
  -                             }
  -                             catch (Exception e) {
  -                                     if (log.isDebugEnabled()) {
  -                                             log.debug("No message", e);
  -                                     }
  -                             }
  -                     }
  -             }
  -
  -             return null;
  -     }
  -
  -     private void putObject(Key key, XMLSerializable obj /*, boolean create 
*/
  -     ) throws DBException {
  -
  -             String localDebugHeader = debugHeader() + "putObject: key=<" + 
key.toString() + ">: ";
  -
  -             Document doc = new DocumentImpl();
  -             ProcessingInstruction pi = 
doc.createProcessingInstruction(CLASSNAME, obj.getClass().getName());
  -             doc.appendChild(pi);
  -             Element elem = obj.streamToXML(doc);
  -             log.debug(localDebugHeader + "elem=<" + 
TextWriter.toString(elem) + ">");
  -             doc.appendChild(elem);
  -             putDocument(key, doc /*, create */
  -             );
  -     }
  -
  -     /**
  -      * setObject sets an XMLSerializable object in the Collection based on 
the
  -      * provided Key.  Xindice takes care of associating the implementation 
class
  -      * with the XMLSerializable object.
  -      *
  -      * @param key The Key to use
  -      * @param obj The Object to set
  -      */
  -     public final void setObject(Object key, XMLSerializable obj) throws 
DBException {
  -             putObject(createNewKey(key), obj /*, false */
  -             );
  -     }
  -
  -     /**
  -      * insertObject inserts an XMLSerializable object into the Collection 
and
  -      * returns a newly generated Key.  Xindice takes care of associating the
  -      * implementation class with the XMLSerializable object.
  -      *
  -      * @param obj The Object to insert
  -      * @return The newly generated Key
  -      */
  -     public final Key insertObject(XMLSerializable obj) throws DBException {
  -             Key key = createNewOID();
  -             putObject(key, obj /*, true */
  -             );
  -             return key;
  -     }
  -
  -     /**
  -      * insertObject inserts an XMLSerializable object into the Collection 
based
  -      * on the specified Key.  Xindice takes care of associating the
  -      * implementation class with the XMLSerializable object.
  -      *
  -      * @param key The Key to use
  -      * @param obj The Object to insert
  -      */
  -     public final void insertObject(String key, XMLSerializable obj) throws 
DBException {
  -             putObject(createNewKey(key), obj /*, true */
  -             );
  -     }
  -
  -     /**
  -      * queryCollection performs a query against the current collection
  -      * using the specified style and query String.
  -      *
  -      * @param style The query style to use (ex: XPath)
  -      * @param query The query to execute
  -      * @param nsMap The namespace Map (if any)
  -      * @return The resulting NodeSet
  -      */
  -     public final NodeSet queryCollection(String style, String query, 
NamespaceMap nsMap) throws DBException {
  -             // a collection in which you are unable to file documents will 
have no filer 
  -             // (for example the root collection). Rather than throwing an 
exception return 
  -             // a constant result (nothing)
  -             return null == filer ? EMPTY_NODESET : 
getQueryEngine().query(this, style, query, nsMap, null);
  -     }
  -
  -     /**
  -      * queryDocument performs a query against a single Document using
  -      * the specified style, query string, and Document ID.
  -      *
  -      * @param style The query style to use (ex: XPath)
  -      * @param query The query to execute
  -      * @param nsMap The namespace Map (if any)
  -      * @param key The Document to query
  -      * @return The resulting NodeSet
  -      */
  -     public final NodeSet queryDocument(String style, String query, 
NamespaceMap nsMap, Object key) throws DBException {
  -             checkFiler(FaultCodes.QRY_STYLE_NOT_FOUND);
  -             Key[] k = null;
  -             if (key instanceof Key[])
  -                     k = (Key[]) key;
  -             else
  -                     k = new Key[] { createNewKey(key)};
  -             return getQueryEngine().query(this, style, query, nsMap, k);
  -     }
  -
  -     /**
  -      * getDocumentSet returns the set of Documents being maintained
  -      * by this Collection.
  -      *
  -      * @return The DocumentSet
  -      */
  -     public final DocumentSet getDocumentSet() throws DBException {
  -             // a collection in which you are unable to file documents will 
have no filer 
  -             // (for example the root collection). Rather than throwing an 
exception return 
  -             // a constant result (nothing)
  -             return null == filer ? EMPTY_DOCUMENTSET : new 
ColDocumentSet(filer.getRecordSet());
  -     }
  -
  -     /**
  -      * listDocuments returns a list of all document keys stored by this
  -      * collection.
  -      *
  -      * @return the list of document keys
  -      */
  -     public final String[] listDocuments() throws DBException {
  -             // a collection in which you are unable to file documents will 
have no filer 
  -             // (for example the root collection). Rather than throwing an 
exception return 
  -             // a constant result (nothing)          
  -             if (null == filer)
  -             {
  -                     return EMPTY_STRING_ARRAY;                              
                
  -             }
  -             else
  -             {
  -                     RecordSet set = filer.getRecordSet();
  -
  -                     // todo: what happens if the size if > than the size of 
an int.
  -                     // I'm pretty sure some sort of runtime exception will 
occur 
  -                     // in the ArrayList.add method.                         
  -
  -                     // give a hint to the size of the record set, saves on 
arraylist array copies.
  -                     ArrayList temp = new 
ArrayList((int)filer.getRecordCount());
  -     
  -                     while (set.hasMoreRecords()) {
  -                             Key key = set.getNextKey();
  -                             temp.add(key.toString());
  -                     }
  -     
  -                     return (String[]) temp.toArray(new String[0]);
  -             }
  -     }
  -
  -     /**
  -      * getDocumentCount returns the count of Documents being maintained
  -      * by this Collection.
  -      *
  -      * @return The Document count
  -      */
  -     public final long getDocumentCount() throws DBException {
  -             // a collection in which you are unable to file documents will 
have no filer 
  -             // (for example the root collection). Rather than throwing an 
exception return 
  -             // a constant result (nothing)
  -             return null == filer ? 0 : filer.getRecordCount();
  -     }
  -
  -     public void dispose() {
  -             try {
  -                     ((Collection) this).close();
  -             }
  -             catch (Exception e) {
  -                     if (log.isDebugEnabled()) {
  -                             log.debug("No message", e);
  -                     }
  -             }
  -     }
  -
  -     private String debugHeader() {
  -             return "["
  -                     + Thread.currentThread().getName()
  -                     + "] Collection:"
  -                     + " name="
  -                     + name
  -                     + " compressed="
  -                     + compressed
  -                     + " inline-metadata="
  -                     + (inlineMetaService != null)
  -                     + " ";
  -     }
  -
  -     // META DATA RELATED DOCS
  -     /**
  -      * Returns whether or not meta data is enabled.
  -      * @return boolean whether or not meta data is enabled.
  -      */
  -     public boolean isMetaEnabled() {
  -             return getDatabase().isMetaEnabled();
  -     }
  -
  -     /**
  -      * Return the MetaData for this collection.
  -      * 
  -      * If metadata is not enabled in the configuration, the MetaData object
  -      * returned will be null.
  -      * @return MetaData this collection's metadata.
  -      */
  -     public MetaData getCollectionMeta() throws DBException {
  -             MetaData meta = null;
  -             if (!isMetaEnabled()) {
  -                     if (log.isWarnEnabled()) {
  -                             log.warn("Meta information requested but not 
enabled in config!");
  -                     }
  -                     return meta;
  -             }
  -             MetaSystemCollection metacol = getMetaSystemCollection();
  -             meta = metacol.getCollectionMeta(this);
  -             long now = System.currentTimeMillis();
  -             if (null == meta) {
  -                     meta = new MetaData(MetaData.COLLECTION, 
getCanonicalName(), now, now);
  -                     metacol.setCollectionMeta(this, meta);
  -             }
  -             return meta;
  -     }
  -
  -     /**
  -      * Reset the metadata object for this collection.
  -      * @param meta the Metadata to use
  -      */
  -     public void setCollectionMeta(MetaData meta) throws DBException {
  -             if (!isMetaEnabled()) {
  -                     if (log.isWarnEnabled()) {
  -                             log.warn("Meta information requested but not 
enabled in config!");
  -                     }
  -                     return;
  -             }
  -             if (null != meta) {
  -                     if (meta.getType() != MetaData.COLLECTION)
  -                             throw new DBException(FaultCodes.GEN_UNKNOWN, 
"Mismatch type of meta data for collection " + getCanonicalName());
  -
  -                     MetaSystemCollection metacol = 
getMetaSystemCollection();
  -                     metacol.setCollectionMeta(this, meta);
  -             }
  -     }
  -
  -     /**
  -      * Return the MetaData object for a document within this collection.
  -      * 
  -      * If metadata is not enabled, the MetaData object returned will be 
null.
  -      * @param id the document whose metadata you want
  -      */
  -     public MetaData getDocumentMeta(String id) throws DBException {
  -             MetaData meta = null;
  -             if (!isMetaEnabled()) {
  -                     if (log.isWarnEnabled()) {
  -                             log.warn("Meta information requested but not 
enabled in config!");
  -                     }
  -                     return meta;
  -             }
  -             Document doc = getDocument(id);
  -             if (null == doc)
  -                     throw new 
DBException(FaultCodes.COL_DOCUMENT_NOT_FOUND, "Document " + id + " does not 
exist");
  -
  -             MetaSystemCollection metacol = getMetaSystemCollection();
  -             meta = metacol.getDocumentMeta(this, id);
  -
  -             String path = getCanonicalDocumentName(id);
  -
  -             /*
  -             TimeRecord rec = null;
  -             if( null == meta || !meta.hasContext() )
  -                rec = getDatabase().getTime(path);
  -             
  -             long created = (null != rec) ? rec.getCreatedTime() : 
System.currentTimeMillis();
  -             long modified = (null != rec) ? rec.getModifiedTime() : 
System.currentTimeMillis();
  -             */
  -
  -             // this is wrong.. but it should work for now...
  -             long created = System.currentTimeMillis();
  -             long modified = System.currentTimeMillis();
  -
  -             if (null == meta) {
  -                     meta = new MetaData(MetaData.DOCUMENT, path, created, 
modified);
  -                     metacol.setDocumentMeta(this, id, meta);
  -             }
  -             else if (!meta.hasContext()) {
  -                     meta.setContext(created, modified);
  -             }
  -
  -             return meta;
  -     }
  -
  -     /**
  -      * Set the metadata associated with a document within this collection.
  -      * 
  -      * @param id the document name
  -      * @param meta the metadata object to be used.
  -      */
  -     public void setDocumentMeta(String id, MetaData meta) throws 
DBException {
  -             if (!isMetaEnabled()) {
  -                     if (log.isWarnEnabled()) {
  -                             log.warn("Meta information requested but not 
enabled in config!");
  -                     }
  -                     return;
  -             }
  -             Document doc = getDocument(id);
  -             if (null == doc)
  -                     throw new 
DBException(FaultCodes.COL_DOCUMENT_NOT_FOUND, "Document " + id + " does not 
exist");
  -
  -             if (null != meta) {
  -                     if (meta.getType() == MetaData.UNKNOWN || 
meta.getType() == MetaData.COLLECTION)
  -                             throw new DBException(FaultCodes.GEN_UNKNOWN, 
"Mismatch type of meta data for document " + getCanonicalDocumentName(id));
  -
  -                     MetaSystemCollection metacol = 
getMetaSystemCollection();
  -                     metacol.setDocumentMeta(this, id, meta);
  -             }
  -     }
  -
  -     /**
  -      * Return the MetaSystemCollection for the database containing this
  -      * collection.
  -      * 
  -      * @return MetaSystemCollection
  -      */
  -     private MetaSystemCollection getMetaSystemCollection() //throws 
DBException
  -     {
  -             return getDatabase().getMetaSystemCollection();
  -     }
  -
  -     /**
  -      * ColDocumentSet
  -      */
  -     private class ColDocumentSet implements DocumentSet {
  -             private RecordSet set;
  -
  -             public ColDocumentSet(RecordSet set) {
  -                     this.set = set;
  -             }
  -
  -             public boolean hasMoreDocuments() throws DBException {
  -                     return set.hasMoreRecords();
  -             }
  -
  -             public Container getNextContainer() throws DBException {
  -                     if (set.hasMoreRecords()) {
  -                             Record rec = set.getNextRecord();
  -                             Key key = rec.getKey();
  -                             Value val = rec.getValue();
  -                             if (val.getData() != null) {
  -                                     try {
  -                                             if (compressed) {
  -                                                     Document doc = new 
DocumentImpl(val.getData(), symbols, new NodeSource(Collection.this, key));
  -                                                     return new 
ColContainer(key, doc);
  -                                             }
  -                                             else
  -                                                     return new 
ColContainer(key, DOMParser.toDocument(val));
  -                                     }
  -                                     catch (Exception e) {
  -                                             if (log.isDebugEnabled()) {
  -                                                     log.debug("No message", 
e);
  -                                             }
  -                                     }
  -                             }
  -                     }
  -                     return null;
  -             }
  -
  -             public Document getNextDocument() throws DBException {
  -                     Container c = getNextContainer();
  -                     if (c != null)
  -                             return c.getDocument();
  -                     else
  -                             return null;
  -             }
  -     }
  -
  -     /**
  -      * ColContainer
  -      */
  -     private class ColContainer implements Container {
  -             private Key key;
  -             private Document document;
  -
  -             public ColContainer(Key key, Document document) {
  -                     this.key = key;
  -                     this.document = document;
  -             }
  -
  -             public Collection getCollection() {
  -                     return Collection.this;
  -             }
  -
  -             public Key getKey() {
  -                     return key;
  -             }
  -
  -             public String getCanonicalName() throws DBException {
  -                     return getCanonicalDocumentName(key);
  -             }
  -
  -             public Document getDocument() {
  -                     return document;
  -             }
  -
  -             public Document rollback() throws DBException {
  -                     document = Collection.this.getDocument(key);
  -                     return document;
  -             }
  -
  -             public void commit(Document doc) throws DBException {
  -                     document = doc;
  -                     commit();
  -             }
  -
  -             public void commit() throws DBException {
  -                     putDocument(key, document /*, false */
  -                     );
  -             }
  -
  -             public void remove() throws DBException {
  -                     Collection.this.remove(key);
  -             }
  -     }
  +
  +    /**
  +     * ColContainer
  +     */
  +    private class ColContainer implements Container {
  +        private Document document;
  +        private Key key;
  +
  +        public ColContainer(Key key, Document document) {
  +            this.key = key;
  +            this.document = document;
  +        }
  +
  +        public void commit() throws DBException {
  +            putDocument(key, document /*, false */
  +            );
  +        }
  +
  +        public void commit(Document doc) throws DBException {
  +            document = doc;
  +            commit();
  +        }
  +
  +        public String getCanonicalName() throws DBException {
  +            return getCanonicalDocumentName(key);
  +        }
  +
  +        public Collection getCollection() {
  +            return Collection.this;
  +        }
  +
  +        public Document getDocument() {
  +            return document;
  +        }
  +
  +        public Key getKey() {
  +            return key;
  +        }
  +
  +        public void remove() throws DBException {
  +            Collection.this.remove(key);
  +        }
  +
  +        public Document rollback() throws DBException {
  +            document = Collection.this.getDocument(key);
  +            return document;
  +        }
  +    }
  +
  +    /**
  +     * ColDocumentSet
  +     */
  +    private class ColDocumentSet implements DocumentSet {
  +        private RecordSet set;
  +
  +        public ColDocumentSet(RecordSet set) {
  +            this.set = set;
  +        }
  +
  +        public Container getNextContainer() throws DBException {
  +            if (set.hasMoreRecords()) {
  +                Record rec = set.getNextRecord();
  +                Key key = rec.getKey();
  +                Value val = rec.getValue();
  +                if (val.getData() != null) {
  +                    try {
  +                        if (compressed) {
  +                            Document doc = new DocumentImpl(val.getData(), 
symbols, new NodeSource(Collection.this, key));
  +                            return new ColContainer(key, doc);
  +                        }
  +                        else
  +                            return new ColContainer(key, 
DOMParser.toDocument(val));
  +                    }
  +                    catch (Exception e) {
  +                        if (log.isDebugEnabled()) {
  +                            log.debug("No message", e);
  +                        }
  +                    }
  +                }
  +            }
  +            return null;
  +        }
  +
  +        public Document getNextDocument() throws DBException {
  +            Container c = getNextContainer();
  +            if (c != null)
  +                return c.getDocument();
  +            else
  +                return null;
  +        }
  +
  +        public boolean hasMoreDocuments() throws DBException {
  +            return set.hasMoreRecords();
  +        }
  +    }
  +
  +    private static final String CACHE = "cache";
  +    private static final String CLASS = "class";
  +    private static final String CLASSNAME = "xindice-class";
  +    private static final String COMPRESSED = "compressed";
  +    private static final DocumentSet EMPTY_DOCUMENTSET = new 
EmptyDocumentSet();
  +    private static final NodeSet EMPTY_NODESET = new EmptyNodeSet();
  +    private static final String[] EMPTY_STRING_ARRAY = {};
  +    private static final String FILER = "filer";
  +    private static int host_id;
  +    private static final String INDEXES = "indexes";
  +    private static final String INLINE_METADATA = "inline-metadata";
  +    private static Log log = LogFactory.getLog("org.apache.xindice.core");
  +    private static final String NAME = "name";
  +    private static final String SYMBOLS = "symbols";
  +
  +    static {
  +        try {
  +            InetAddress a = InetAddress.getLocalHost();
  +            byte[] b = a.getAddress();
  +            host_id = 0;
  +            host_id += b[0];
  +            host_id += (b[1] << 8);
  +            host_id += (b[2] << 16);
  +            host_id += (b[3] << 24);
  +            host_id = Math.abs(host_id);
  +        }
  +        catch (Exception e) {
  +
  +            log.warn(e);
  +        }
  +    }
  +
  +    private String canonicalName;
  +    // Object ID Stuff
  +    private int collection_id = 0;
  +    private File collectionRoot;
  +    private boolean compressed = false;
  +    private long document_id = System.currentTimeMillis();
  +    private DocumentCache documentCache;
  +    private Filer filer = null;
  +    private IndexManager indexManager;
  +    private InlineMetaService inlineMetaService;
  +    private boolean internalSymbols = false;
  +    private String name;
  +    private Object oidMutex = new Object();
  +    private String oidTemplate = null;
  +    private Collection parent = null;
  +    private SymbolTable symbols = null;
  +
  +    protected Collection() {}
  +
  +    /**
  +     * 
  +     * @param parentCollection
  +     */
  +    public Collection(Collection parentCollection) {
  +        this();
  +        this.parent = parentCollection;
  +    }
  +
  +    private void checkFiler(int faultCode) throws DBException {
  +        if (filer == null)
  +            throw new DBException(faultCode, "This Collection '" + name + "' 
cannot store Documents");
  +    }
  +
  +    /**
  +     * @see org.apache.xindice.core.DBObject#close()
  +     */
  +    public boolean close() throws DBException {
  +        return true;
  +    }
  +
  +    /**
  +     * @see org.apache.xindice.core.DBObject#create()
  +     */
  +    public boolean create() throws DBException {
  +        // update the meta information if necessary
  +        updateCollectionMeta();
  +
  +        DBObserver.getInstance().createCollection(this);
  +        return true;
  +    }
  +
  +    /**
  +     * @see 
org.apache.xindice.core.CollectionManager#createCollection(java.lang.String, 
org.apache.xindice.util.Configuration)
  +     */
  +    public final Collection createCollection(String path, Configuration 
config) throws DBException {
  +        Collection col = super.createCollection(path, config);
  +        getDatabase().flushConfig();
  +        return col;
  +    }
  +
  +    /**
  +     * createIndexer creates a new Indexer object and any associated
  +     * system resources that the Indexer will need.
  +     *
  +     * @param config The Indexer's configuration
  +     * @return The newly created Indexer
  +     */
  +    public final Indexer createIndexer(Configuration config) throws 
DBException {
  +        checkFiler(FaultCodes.COL_NO_INDEXMANAGER);
  +        Indexer idx = indexManager.create(config);
  +        getDatabase().flushConfig();
  +        return idx;
  +    }
  +
  +    /**
  +     * createNewKey allocates a new Key to be used as a Key in the
  +     * Collection.
  +     *
  +     * @param key The Key hint
  +     * @return The newly generated Key
  +     */
  +    protected final Key createNewKey(Object key) {
  +        if (key == null)
  +            return createNewOID();
  +        if (key instanceof Key)
  +            return (Key) key;
  +        else
  +            return new Key(key.toString());
  +    }
  +
  +    /**
  +     * createNewOID allocates a new Object ID to be used as a Key in the
  +     * Collection.
  +     *
  +     * @return The newly generated Key
  +     */
  +    public final Key createNewOID() {
  +        long ct = System.currentTimeMillis();
  +
  +        synchronized (oidMutex) {
  +            if (ct <= document_id)
  +                ct = document_id + 1;
  +            document_id = ct;
  +        }
  +
  +        StringBuffer sb = new StringBuffer(oidTemplate);
  +        String document = Long.toString(document_id, 16);
  +        sb.insert(32 - document.length(), document);
  +        sb.setLength(32);
  +
  +        return new Key(sb.toString());
  +    }
  +
  +    private String debugHeader() {
  +        return "["
  +            + Thread.currentThread().getName()
  +            + "] Collection:"
  +            + " name="
  +            + name
  +            + " compressed="
  +            + compressed
  +            + " inline-metadata="
  +            + (inlineMetaService != null)
  +            + " ";
  +    }
  +
  +    /**
  +     * @see org.apache.xindice.util.Disposable#dispose()
  +     */
  +    public void dispose() {
  +        try {
  +            ((Collection) this).close();
  +        }
  +        catch (Exception e) {
  +            if (log.isDebugEnabled()) {
  +                log.debug("No message", e);
  +            }
  +        }
  +    }
  +
  +    /**
  +     * @see org.apache.xindice.core.DBObject#drop()
  +     */
  +    public boolean drop() throws DBException {
  +        if (this == getDatabase())
  +            throw new DBException(FaultCodes.DBE_CANNOT_DROP, "You Cannot 
Drop The Database");
  +
  +        DBObserver.getInstance().dropCollection(this);
  +
  +        // drop the meta if necessary
  +        if (isMetaEnabled()) {
  +            MetaSystemCollection metacol = getMetaSystemCollection();
  +            metacol.dropCollectionMeta(this);
  +        }
  +
  +        // Drop Child Collections
  +        String[] cols = listCollections();
  +        for (int i = 0; i < cols.length; i++)
  +            dropCollection(getCollection(cols[i]));
  +
  +        if (filer != null) {
  +            // Drop Indexers
  +            String[] idx = indexManager.list();
  +            for (int i = 0; i < idx.length; i++)
  +                dropIndexer(getIndexer(idx[i]));
  +
  +            // Now Drop The Filer
  +            filer.drop();
  +        }
  +
  +        getCollectionRoot().delete();
  +        getDatabase().flushConfig();
  +
  +        return true;
  +    }
  +
  +    /**
  +     * @see 
org.apache.xindice.core.CollectionManager#dropCollection(org.apache.xindice.core.Collection)
  +     */
  +    public final boolean dropCollection(Collection collection) throws 
DBException {
  +        boolean success = super.dropCollection(collection);
  +        getDatabase().flushConfig();
  +        return success;
  +    }
  +
  +    /**
  +     * dropIndexer physically removes the specified Indexer and any
  +     * associated system resources that the Indexer uses.
  +     *
  +     * @param index The Indexer to drop
  +     * @return Whether or not the Indexer was dropped
  +     */
  +    public final boolean dropIndexer(Indexer index) throws DBException {
  +        checkFiler(FaultCodes.COL_NO_INDEXMANAGER);
  +
  +        if (index == null)
  +            throw new DBException(FaultCodes.IDX_INDEX_NOT_FOUND, "Index 
Value Null");
  +
  +        boolean success = indexManager.drop(index.getName());
  +        getDatabase().flushConfig();
  +        return success;
  +    }
  +
  +    /**
  +     * @see org.apache.xindice.core.DBObject#exists()
  +     */
  +    public boolean exists() throws DBException {
  +        return true;
  +    }
  +
  +    /**
  +     * @throws DBException
  +     */
  +    public final void flushSymbolTable() throws DBException {
  +        if (symbols.isDirty() && !internalSymbols)
  +            getSystemCollection().saveSymbols(this, symbols);
  +    }
  +
  +    /**
  +     * Retrieve a binary database entry by key.
  +     * This low-level method will not update non-inline metadata.
  +     *
  +     * @param docKey identifying the desired database entry
  +     * @return byte[] containing the binary database entry
  +     * @throws DBException if inline-metadata is not enabled
  +     *         (binary resource cannot be stored in a collection
  +     *             which does not have inline-metadata enabled),
  +     *         in case of backing store error, and in case of
  +     *         header corruption
  +     */
  +    public final byte[] getBinary(Object docKey) throws DBException {
  +
  +        log.debug(debugHeader() + "getBinary: docKey=<" + docKey.toString() 
+ ">");
  +
  +        if (inlineMetaService != null) {
  +            throw new DBException(FaultCodes.COL_DOCUMENT_NOT_FOUND, "There 
are no binary resources in collection" + name + ": inline-metadata is not 
enabled.");
  +        }
  +
  +        Object entry = getEntry(docKey);
  +        if (entry == null) {
  +            return null;
  +        }
  +
  +        if (!(entry instanceof byte[])) {
  +            throw new DBException(FaultCodes.COL_INVALID_RESULT, "The 
resource associated with key '" + docKey.toString() + "' in collection '" + 
name + "'is not binary");
  +        }
  +
  +        return (byte[]) entry;
  +    }
  +
  +    /**
  +     * getCanonicalDocumentName returns the canonical name for the specified
  +     * Key in relation to this Collection.
  +     * <br>
  +     * ex: /local/test/ocs/ytd
  +     *
  +     * @param key The Key
  +     * @return The canonical name
  +     */
  +    public final String getCanonicalDocumentName(Key key) {
  +        return getCanonicalDocumentName(key.toString());
  +    }
  +
  +    /**
  +     * @param key
  +     * @return
  +     */
  +    public final String getCanonicalDocumentName(String key) {
  +        StringBuffer sb = new StringBuffer();
  +        sb.append(canonicalName);
  +        sb.append('/');
  +        sb.append(key);
  +        return sb.toString();
  +    }
  +
  +    /**
  +     * getCanonicalName returns the canonical name for this Object.
  +     * <br>
  +     * ex: /local/test/ocs
  +     *
  +     * @return The canonical name
  +     */
  +    public final String getCanonicalName() {
  +        return canonicalName;
  +    }
  +
  +    /**
  +     * Return the MetaData for this collection.
  +     * 
  +     * If metadata is not enabled in the configuration, the MetaData object
  +     * returned will be null.
  +     * @return MetaData this collection's metadata.
  +     */
  +    public MetaData getCollectionMeta() throws DBException {
  +        MetaData meta = null;
  +        if (!isMetaEnabled()) {
  +            if (log.isWarnEnabled()) {
  +                log.warn("Meta information requested but not enabled in 
config!");
  +            }
  +            return meta;
  +        }
  +        MetaSystemCollection metacol = getMetaSystemCollection();
  +        meta = metacol.getCollectionMeta(this);
  +        long now = System.currentTimeMillis();
  +        if (null == meta) {
  +            meta = new MetaData(MetaData.COLLECTION, getCanonicalName(), 
now, now);
  +            metacol.setCollectionMeta(this, meta);
  +        }
  +        return meta;
  +    }
  +
  +    /**
  +     * @return
  +     */
  +    public final File getCollectionRoot() {
  +        return collectionRoot;
  +    }
  +
  +    /**
  +     * getContainer retrieves a Container from the Collection.  The Container
  +     * encapsulates all information needed in dealing with a Document outside
  +     * of the context of a Collection (ex: DocumentContext).
  +     *
  +     * @param docKey The Document Key
  +     * @return The Container
  +     */
  +    public final Container getContainer(Object docKey) throws DBException {
  +        Key key = createNewKey(docKey);
  +        Document doc = getDocument(key);
  +        return doc != null ? new ColContainer(key, doc) : null;
  +    }
  +
  +    /**
  +     * getDatabase returns the Database owner for this Collection.
  +     *
  +     * @return The Database
  +     */
  +    public Database getDatabase() {
  +        return parent.getDatabase();
  +    }
  +
  +    /**
  +     * getDocument retrieves a Document by Key.
  +     *
  +     * @param docKey The Document Key
  +     * @return The Document
  +     */
  +    public final Document getDocument(Object docKey) throws DBException {
  +
  +        log.debug(debugHeader() + "getDocument: docKey=<" + 
docKey.toString() + ">");
  +
  +        Object entry = getEntry(docKey);
  +        if (entry == null) {
  +            return null;
  +        }
  +
  +        if (!(entry instanceof Document)) {
  +            throw new DBException(FaultCodes.COL_INVALID_RESULT, "The 
resource associated with key '" + docKey.toString() + "' in collection '" + 
name + "'is not XML");
  +        }
  +
  +        return (Document) entry;
  +    }
  +
  +    /**
  +     * getDocumentCount returns the count of Documents being maintained
  +     * by this Collection.
  +     *
  +     * @return The Document count
  +     */
  +    public final long getDocumentCount() throws DBException {
  +        // a collection in which you are unable to file documents will have 
no filer 
  +        // (for example the root collection). Rather than throwing an 
exception return 
  +        // a constant result (nothing)
  +        return null == filer ? 0 : filer.getRecordCount();
  +    }
  +
  +    /**
  +     * Return the MetaData object for a document within this collection.
  +     * 
  +     * If metadata is not enabled, the MetaData object returned will be null.
  +     * @param id the document whose metadata you want
  +     */
  +    public MetaData getDocumentMeta(String id) throws DBException {
  +        MetaData meta = null;
  +        if (!isMetaEnabled()) {
  +            if (log.isWarnEnabled()) {
  +                log.warn("Meta information requested but not enabled in 
config!");
  +            }
  +            return meta;
  +        }
  +        Document doc = getDocument(id);
  +        if (null == doc)
  +            throw new DBException(FaultCodes.COL_DOCUMENT_NOT_FOUND, 
"Document " + id + " does not exist");
  +
  +        MetaSystemCollection metacol = getMetaSystemCollection();
  +        meta = metacol.getDocumentMeta(this, id);
  +
  +        String path = getCanonicalDocumentName(id);
  +
  +        /*
  +        TimeRecord rec = null;
  +        if( null == meta || !meta.hasContext() )
  +           rec = getDatabase().getTime(path);
  +        
  +        long created = (null != rec) ? rec.getCreatedTime() : 
System.currentTimeMillis();
  +        long modified = (null != rec) ? rec.getModifiedTime() : 
System.currentTimeMillis();
  +        */
  +
  +        // this is wrong.. but it should work for now...
  +        long created = System.currentTimeMillis();
  +        long modified = System.currentTimeMillis();
  +
  +        if (null == meta) {
  +            meta = new MetaData(MetaData.DOCUMENT, path, created, modified);
  +            metacol.setDocumentMeta(this, id, meta);
  +        }
  +        else if (!meta.hasContext()) {
  +            meta.setContext(created, modified);
  +        }
  +
  +        return meta;
  +    }
  +
  +    /**
  +     * getDocumentSet returns the set of Documents being maintained
  +     * by this Collection.
  +     *
  +     * @return The DocumentSet
  +     */
  +    public final DocumentSet getDocumentSet() throws DBException {
  +        // a collection in which you are unable to file documents will have 
no filer 
  +        // (for example the root collection). Rather than throwing an 
exception return 
  +        // a constant result (nothing)
  +        return null == filer ? EMPTY_DOCUMENTSET : new 
ColDocumentSet(filer.getRecordSet());
  +    }
  +
  +    /**
  +     * Retrieve a database entry by key.
  +     * If no matching entry is found, null is returned; if
  +     * an XML entry is found, a Document is returned; if a
  +     * binary entryis found, byte[] is returned.
  +     * This low-level method will not update non-inline metadata.
  +     *
  +     * @param docKey identifying the desired database entry
  +     * @return Object containing the database entry, or null if no
  +     *         matching entry is found
  +     * @throws DBException in case of backing store error,
  +     *         and in case of header corruption
  +     */
  +    public final Object getEntry(Object docKey) throws DBException {
  +
  +        /*
  +         * I would prefer to throw an exception (NPE) in this case,
  +         * but we have a test indicating a null return...
  +         */
  +        if (docKey == null) {
  +            return null;
  +        }
  +
  +        String localDebugHeader = debugHeader() + "getEntry: docKey=<" + 
docKey.toString() + ">: ";
  +
  +        log.debug(localDebugHeader);
  +
  +        checkFiler(FaultCodes.COL_NO_FILER);
  +
  +        Key key = createNewKey(docKey);
  +
  +        /*
  +         * If the key has a corresponding value in the cache, return it
  +         * and save a disk access.
  +         * 
  +         * At some point the current document-centric cache implementation
  +         * needs to be converted to an entry cache which can hold both
  +         * Document and byte[].
  +         */
  +        if (documentCache != null) {
  +            Document document = documentCache.getDocument(this, key);
  +            log.debug(localDebugHeader + "cache search returned: " + 
document);
  +            if (document != null) {
  +                return document;
  +            }
  +        }
  +
  +        Record record = filer.readRecord(key);
  +        if (record == null) {
  +            return null;
  +        }
  +
  +        log.debug(localDebugHeader + "record value: length=" + 
record.getValue().getLength());
  +
  +        Value value;
  +        InlineMetaMap metaMap = null;
  +        if (inlineMetaService == null) {
  +            log.debug(localDebugHeader + "type not available");
  +            value = record.getValue();
  +        }
  +        else {
  +            log.debug(localDebugHeader + "decomposing header...");
  +            InlineMetaService.DatabaseEntry databaseEntry = 
inlineMetaService.readDatabaseEntry(record.getValue());
  +            metaMap = databaseEntry.map;
  +            value = databaseEntry.value;
  +
  +            log.debug(localDebugHeader + "type=" + metaMap.get("type") + " 
length=" + value.getLength());
  +        }
  +
  +        if (inlineMetaService == null || 
metaMap.get("type").equals(ResourceTypeReader.XML)) {
  +
  +            log.debug(localDebugHeader + "XML document");
  +
  +            Document document;
  +            if (compressed) {
  +
  +                document = new DocumentImpl(value.getData(), symbols, new 
NodeSource(this, key));
  +
  +                flushSymbolTable();
  +
  +                log.debug(localDebugHeader + "compressed XML document: 
document=<" + TextWriter.toString(document) + ">");
  +
  +                if (documentCache != null) {
  +                    documentCache.putDocument(this, key, value.getData());
  +                }
  +            }
  +            else {
  +                log.debug(localDebugHeader + "pre parseDocument(): value=<" 
+ value.toString() + ">");
  +                document = parseDocument(key, value.toString());
  +            }
  +
  +            DBObserver.getInstance().loadDocument(this, record, document);
  +            return document;
  +        }
  +        else {
  +            return value.getData();
  +        }
  +    }
  +
  +    /**
  +     * getFiler returns the low-level Filer instances underlying the
  +     * Collection instance.
  +     *
  +     * @return The requested Filer
  +     */
  +    public final Filer getFiler() {
  +        return filer;
  +    }
  +
  +    /**
  +     * getIndexer retrieves an Indexer by name.
  +     *
  +     * @param name The Indexer name
  +     * @return The Indexer (or null)
  +     */
  +    public final Indexer getIndexer(String name) throws DBException {
  +        checkFiler(FaultCodes.COL_NO_INDEXMANAGER);
  +        return indexManager.get(name);
  +    }
  +
  +    /**
  +     * return the IndexManager being used by this Collection.
  +     *
  +     * @return The IndexManager
  +     */
  +    public final IndexManager getIndexManager() throws DBException {
  +        checkFiler(FaultCodes.COL_NO_INDEXMANAGER);
  +        return indexManager;
  +    }
  +
  +    /**
  +     * Return the MetaSystemCollection for the database containing this
  +     * collection.
  +     * 
  +     * @return MetaSystemCollection
  +     */
  +    private MetaSystemCollection getMetaSystemCollection() //throws 
DBException
  +    {
  +        return getDatabase().getMetaSystemCollection();
  +    }
  +
  +    public final String getName() {
  +        return name;
  +    }
  +
  +    /**
  +     * getObject instantiates and returns an XMLSerializable object based on 
the
  +     * provided Key.  Xindice takes care of instantiating the correct class, 
but
  +     * only if a class was registered with the Document in the first place.
  +     *
  +     * @param key The Document Key
  +     * @return an Castable XMLSerializable Instance
  +     */
  +    public final XMLSerializable getObject(Object key) throws DBException {
  +        String className = null;
  +
  +        Document doc = getDocument(key);
  +
  +        if (doc != null) {
  +            NodeList childNodes = doc.getChildNodes();
  +            int size = childNodes.getLength();
  +            for (int i = 0; i < size; i++) {
  +                Node n = childNodes.item(i);
  +                if (n.getNodeType() == Node.PROCESSING_INSTRUCTION_NODE && 
n.getNodeName().equals(CLASSNAME)) {
  +                    className = n.getNodeValue().trim();
  +                    break;
  +                }
  +            }
  +
  +            if (className != null) {
  +                try {
  +                    XMLSerializable obj = (XMLSerializable) 
Class.forName(className).newInstance();
  +                    obj.streamFromXML(doc.getDocumentElement());
  +                    return obj;
  +                }
  +                catch (Exception e) {
  +                    if (log.isDebugEnabled()) {
  +                        log.debug("No message", e);
  +                    }
  +                }
  +            }
  +        }
  +
  +        return null;
  +    }
  +
  +    /**
  +     * getParentCollection returns the parent Collection of this
  +     * Collection.
  +     *
  +     * @return The parent Collection (or null)
  +     */
  +    public final Collection getParentCollection() throws DBException {
  +        return parent;
  +    }
  +
  +    /**
  +     * getQueryEngine returns the Database's Query Engine
  +     *
  +     * @return The Query Engine
  +     */
  +    public QueryEngine getQueryEngine() throws DBException {
  +        return getDatabase().getQueryEngine();
  +    }
  +
  +    /**
  +     * getSymbols returns the SymbolTable in use by this
  +     * Collection.
  +     *
  +     * @return The Symbol Table
  +     */
  +    public final SymbolTable getSymbols() throws DBException {
  +        return symbols;
  +    }
  +
  +    /**
  +     * getSystemCollection returns the System Collection.
  +     *
  +     * @return The System Collection
  +     */
  +    public SystemCollection getSystemCollection() throws DBException {
  +        return getDatabase().getSystemCollection();
  +    }
  +
  +    /**
  +     * Insert a binary object into a Xindice Collection.  A unique key
  +     * is automatically generated. by which the binary object can be
  +     * retrieved in the future.  Note: because the key is automatically
  +     * unique, this insert method will never cause a collision with an
  +     * object already in the database.
  +     *
  +     * @param bytes The bytes making up the binary object to insert
  +     * @return Key automatically generated for the binary object
  +     * @throws DBException if inline-metadata is not enabled, or an
  +     *         error occurs while saving.
  +     */
  +    public Key insertBinary(byte[] bytes) throws DBException {
  +
  +        if (inlineMetaService == null) {
  +            throw new DBException(FaultCodes.COL_CANNOT_STORE, "Cannot 
insert a binary resource in collection " + name + ": inline-metadata is not 
enabled.");
  +        }
  +
  +        Key key = createNewOID();
  +        putBinary(key, bytes, true);
  +
  +        // update the meta information if necessary
  +        updateCollectionMeta();
  +
  +        return key;
  +    }
  +
  +    /**
  +     * insertBinary inserts a new binary object into a Xindice Collection.
  +     *
  +     * @param docKey The document Key
  +     * @param document The document to insert
  +     * @throws DBException if inline-metadata is not enabled, the key is
  +     *         already in the database, or an error occurs while saving.
  +     */
  +    public void insertBinary(Object docKey, byte[] bytes) throws DBException 
{
  +
  +        if (inlineMetaService == null) {
  +            throw new DBException(FaultCodes.COL_CANNOT_STORE, "Cannot 
insert a binary resource in collection " + name + ": inline-metadata is not 
enabled.");
  +        }
  +
  +        putBinary(createNewKey(docKey), bytes, true);
  +
  +        // update the meta information if necessary
  +        updateCollectionMeta();
  +    }
  +
  +    /**
  +     * insertDocument inserts a new Document into a Xindice Collection.
  +     *
  +     * @param document The Document
  +     * @return The new Object Identifier
  +     */
  +    public final Key insertDocument(Document document) throws DBException {
  +        Key key = createNewOID();
  +        putDocument(key, document /*, true */
  +        );
  +        // update the meta information if necessary
  +        updateCollectionMeta();
  +        return key;
  +    }
  +
  +    /**
  +     * insertDocument inserts a new Document into a Xindice Collection.
  +     *
  +     * @param docKey The document Key
  +     * @param document The document to insert
  +     */
  +    public final void insertDocument(Object docKey, Document document) 
throws DBException {
  +        putDocument(createNewKey(docKey), document /*, true */
  +        );
  +        // update the meta information if necessary
  +        updateCollectionMeta();
  +    }
  +
  +    /**
  +     * insertObject inserts an XMLSerializable object into the Collection 
based
  +     * on the specified Key.  Xindice takes care of associating the
  +     * implementation class with the XMLSerializable object.
  +     *
  +     * @param key The Key to use
  +     * @param obj The Object to insert
  +     */
  +    public final void insertObject(String key, XMLSerializable obj) throws 
DBException {
  +        putObject(createNewKey(key), obj /*, true */
  +        );
  +    }
  +
  +    /**
  +     * insertObject inserts an XMLSerializable object into the Collection and
  +     * returns a newly generated Key.  Xindice takes care of associating the
  +     * implementation class with the XMLSerializable object.
  +     *
  +     * @param obj The Object to insert
  +     * @return The newly generated Key
  +     */
  +    public final Key insertObject(XMLSerializable obj) throws DBException {
  +        Key key = createNewOID();
  +        putObject(key, obj /*, true */
  +        );
  +        return key;
  +    }
  +
  +    // META DATA RELATED DOCS
  +    /**
  +     * Returns whether or not meta data is enabled.
  +     * @return boolean whether or not meta data is enabled.
  +     */
  +    public boolean isMetaEnabled() {
  +        return getDatabase().isMetaEnabled();
  +    }
  +
  +    public boolean isOpened() throws DBException {
  +        return true;
  +    }
  +
  +    /**
  +     * listDocuments returns a list of all document keys stored by this
  +     * collection.
  +     *
  +     * @return the list of document keys
  +     */
  +    public final String[] listDocuments() throws DBException {
  +        // a collection in which you are unable to file documents will have 
no filer 
  +        // (for example the root collection). Rather than throwing an 
exception return 
  +        // a constant result (nothing)               
  +        if (null == filer) {
  +            return EMPTY_STRING_ARRAY;
  +        }
  +        else {
  +            RecordSet set = filer.getRecordSet();
  +
  +            // todo: what happens if the size if > than the size of an int.
  +            // I'm pretty sure some sort of runtime exception will occur 
  +            // in the ArrayList.add method.                  
  +
  +            // give a hint to the size of the record set, saves on arraylist 
array copies.
  +            ArrayList temp = new ArrayList((int) filer.getRecordCount());
  +
  +            while (set.hasMoreRecords()) {
  +                Key key = set.getNextKey();
  +                temp.add(key.toString());
  +            }
  +
  +            return (String[]) temp.toArray(new String[0]);
  +        }
  +    }
  +
  +    /**
  +     * listIndexers returns a list of the currently registered Indexers
  +     * as an array of String.
  +     *
  +     * @return The Indexer list
  +     */
  +    public final String[] listIndexers() throws DBException {
  +        checkFiler(FaultCodes.COL_NO_INDEXMANAGER);
  +        return indexManager.list();
  +    }
  +
  +    public final boolean open() throws DBException {
  +        return true;
  +    }
  +
  +    /**
  +     * Turns an XML string into a parsed document and caches it.
  +     *
  +     * @param key The key to use when caching
  +     * @param xml The string to parse
  +     * @return A parsed DOM document or null if failure
  +     */
  +    private Document parseDocument(Key key, String xml) throws DBException {
  +        Document doc = null;
  +        try {
  +            doc = DOMParser.toDocument(xml);
  +
  +            // Have to move it to Xindice DOM for XMLObject AutoLinking
  +            byte[] b = DOMCompressor.Compress(doc, symbols);
  +            doc = new DocumentImpl(b, symbols, new NodeSource(this, key));
  +
  +            if (documentCache != null)
  +                documentCache.putDocument(this, key, b);
  +        }
  +        catch (Exception e) {
  +            throw new DBException(FaultCodes.COL_DOCUMENT_MALFORMED, "Unable 
to parse Document", e);
  +        }
  +        return doc;
  +    }
  +
  +    /*
  +     * Lowest-level method for saving a binary entry into the database.
  +     * Does not update non-inline metadata.
  +     */
  +    private void putBinary(Key key, byte[] bytes, boolean create) throws 
DBException {
  +
  +        if (inlineMetaService == null) {
  +            throw new DBException(FaultCodes.COL_CANNOT_STORE, "Cannot store 
a binary resource in collection " + name + ": inline-metadata is not enabled");
  +        }
  +
  +        if (!create) {
  +            byte[] storedBytes = getBinary(key);
  +            if (storedBytes == null) {
  +                /*
  +                 * TODO: Do we need a COL_KEY_ALREADY_PRESENT fault so that 
the caller can interpret this exception?
  +                 */
  +                throw new DBException(
  +                    FaultCodes.COL_CANNOT_STORE,
  +                    "Error storing binary object with key '" + key + "': the 
'create' flag is false and" + " the key is not in the database");
  +            }
  +        }
  +
  +        InlineMetaMap map = inlineMetaService.getEmptyMap();
  +        map.put("type", ResourceTypeReader.BINARY);
  +        Value value = inlineMetaService.createValue(map, bytes, 0, 
bytes.length);
  +        filer.writeRecord(key, value);
  +    }
  +
  +    /**
  +     * This is the lowest-level method for storing a record into the backing 
store.
  +     * It does not update non-inline metadata.
  +     */
  +    private void putDocument(Key key, Document document) throws DBException {
  +
  +        String localDebugHeader = debugHeader() + "putDocument: docKey=<" + 
key.toString() + ">: ";
  +
  +        log.debug(localDebugHeader + "document=<" + 
TextWriter.toString(document).toString() + ">");
  +
  +        checkFiler(FaultCodes.COL_NO_FILER);
  +
  +        if (document instanceof DBDocument) {
  +            // This is a shitty shitty hack... Kill immediately
  +            DBDocument dbDoc = (DBDocument) document;
  +            if (dbDoc.getSource() == null)
  +                dbDoc.setSource(new NodeSource(this, key));
  +        }
  +
  +        /*
  +         * The possibilities are restricted because only XML
  +         * is handled by this method.  There are only a few
  +         * pieces of information that need to be constructed:
  +         * 1) the xindice DOM document is needed for all XML objects, as
  +         *         it is handed to the IndexManager and the DBObserver.
  +         * 2) the packed document, if this is a compressed XML object,
  +         *        is needed for the cache and the BTree (via the Value 
object).
  +         * 3) the string-converted-to-utf-8 bytes, if this is a 
non-compressed
  +         *        XML object, is needed for the BTree (via the Value object).
  +         * 4) A Value object, with a header if headers are enabled, and
  +         *        otherwise without headers, for the BTree.
  +         */
  +
  +        byte[] packedDocument = null;
  +        byte[] utf8Document = null;
  +
  +        if (compressed) {
  +            try {
  +
  +                packedDocument = DOMCompressor.Compress(document, symbols);
  +                log.debug(localDebugHeader + "length=" + 
packedDocument.length);
  +
  +                // Why must it be re-created?
  +                document = new DocumentImpl(packedDocument, symbols, new 
NodeSource(this, key));
  +
  +                log.debug(localDebugHeader + "packedDocument: length=" + 
packedDocument.length + " document=<" + TextWriter.toString(document) + ">");
  +            }
  +            catch (Exception e) {
  +                throw new DBException(FaultCodes.COL_CANNOT_STORE, 
localDebugHeader + "Error compressing Document '" + key + "'", e);
  +            }
  +        }
  +        else {
  +            try {
  +                utf8Document = 
TextWriter.toString(document).getBytes("utf-8");
  +                log.debug(localDebugHeader + "utf8Document: length=" + 
utf8Document.length + " document=<" + new String(utf8Document, "utf-8") + ">");
  +            }
  +            catch (UnsupportedEncodingException e) {
  +                throw new DBException(FaultCodes.GEN_FATAL_ERROR, "utf-8 
encoding not supported", e);
  +            }
  +        }
  +
  +        /*
  +         * TODO: Can this be moved into the if(compressed) block?
  +         */
  +        flushSymbolTable();
  +
  +        // Temporary until insert and update are separate
  +        Document oldDoc = getDocument(key);
  +        if (oldDoc != null) {
  +            indexManager.removeDocument(key, oldDoc);
  +        }
  +        indexManager.addDocument(key, document);
  +
  +        /*
  +         * Construct the Value object that is stored in the BTree.
  +         */
  +        Value value;
  +        if (inlineMetaService == null) {
  +            if (compressed) {
  +                value = new Value(packedDocument);
  +            }
  +            else {
  +                value = new Value(utf8Document);
  +            }
  +        }
  +        else {
  +            InlineMetaMap map = inlineMetaService.getEmptyMap();
  +            map.put("type", ResourceTypeReader.XML);
  +            if (compressed) {
  +                value = inlineMetaService.createValue(map, packedDocument, 
0, packedDocument.length);
  +            }
  +            else {
  +                value = inlineMetaService.createValue(map, utf8Document, 0, 
utf8Document.length);
  +            }
  +        }
  +        filer.writeRecord(key, value);
  +
  +        // Cache Stuff
  +        if (documentCache != null) {
  +            if (compressed)
  +                documentCache.putDocument(this, key, packedDocument);
  +            else
  +                documentCache.putDocument(this, key, document);
  +        }
  +
  +        DBObserver.getInstance().putDocument(this, key, document, oldDoc == 
null);
  +    }
  +
  +    private void putObject(Key key, XMLSerializable obj) throws DBException {
  +
  +        String localDebugHeader = debugHeader() + "putObject: key=<" + 
key.toString() + ">: ";
  +
  +        Document doc = new DocumentImpl();
  +        ProcessingInstruction pi = 
doc.createProcessingInstruction(CLASSNAME, obj.getClass().getName());
  +        doc.appendChild(pi);
  +        Element elem = obj.streamToXML(doc);
  +        log.debug(localDebugHeader + "elem=<" + TextWriter.toString(elem) + 
">");
  +        doc.appendChild(elem);
  +        putDocument(key, doc /*, create */
  +        );
  +    }
  +
  +    /**
  +     * queryCollection performs a query against the current collection
  +     * using the specified style and query String.
  +     *
  +     * @param style The query style to use (ex: XPath)
  +     * @param query The query to execute
  +     * @param nsMap The namespace Map (if any)
  +     * @return The resulting NodeSet
  +     */
  +    public final NodeSet queryCollection(String style, String query, 
NamespaceMap nsMap) throws DBException {
  +        // a collection in which you are unable to file documents will have 
no filer 
  +        // (for example the root collection). Rather than throwing an 
exception return 
  +        // a constant result (nothing)
  +        return null == filer ? EMPTY_NODESET : getQueryEngine().query(this, 
style, query, nsMap, null);
  +    }
  +
  +    /**
  +     * queryDocument performs a query against a single Document using
  +     * the specified style, query string, and Document ID.
  +     *
  +     * @param style The query style to use (ex: XPath)
  +     * @param query The query to execute
  +     * @param nsMap The namespace Map (if any)
  +     * @param key The Document to query
  +     * @return The resulting NodeSet
  +     */
  +    public final NodeSet queryDocument(String style, String query, 
NamespaceMap nsMap, Object key) throws DBException {
  +        checkFiler(FaultCodes.QRY_STYLE_NOT_FOUND);
  +        Key[] k = null;
  +        if (key instanceof Key[])
  +            k = (Key[]) key;
  +        else
  +            k = new Key[] { createNewKey(key)};
  +        return getQueryEngine().query(this, style, query, nsMap, k);
  +    }
  +
  +    /**
  +     * remove removes an object from the Collection based on its Key,
  +     * regardless of it's type.
  +     *
  +     * @param key The Object's Key
  +     */
  +    public final void remove(Object key) throws DBException {
  +        checkFiler(FaultCodes.COL_NO_FILER);
  +
  +        Key objKey = createNewKey(key);
  +
  +        Document oldDoc = getDocument(objKey);
  +        if (oldDoc != null)
  +            indexManager.removeDocument(objKey, oldDoc);
  +
  +        if (documentCache != null)
  +            documentCache.removeDocument(this, objKey);
  +
  +        if (!filer.deleteRecord(objKey))
  +            throw new DBException(FaultCodes.COL_DOCUMENT_NOT_FOUND, 
"Document Does Not Exist");
  +
  +        // update the meta for this collection if necessary
  +        updateCollectionMeta();
  +        // remove the document meta
  +        if (isMetaEnabled()) {
  +            getMetaSystemCollection().dropDocumentMeta(this, 
objKey.toString());
  +        }
  +        DBObserver.getInstance().dropDocument(this, objKey);
  +    }
  +
  +    protected final void setCanonicalName(String canonicalName) {
  +        this.canonicalName = canonicalName;
  +
  +        // Calculate The OID Template
  +        collection_id = Math.abs(canonicalName.hashCode());
  +        StringBuffer sb = new 
StringBuffer("00000000000000000000000000000000");
  +        String host = Integer.toString(host_id, 16);
  +        String collection = Integer.toString(collection_id, 16);
  +        sb.insert(8 - host.length(), host);
  +        sb.insert(16 - collection.length(), collection);
  +        sb.setLength(32);
  +        oidTemplate = sb.toString();
  +    }
  +
  +    /**
  +     * Reset the metadata object for this collection.
  +     * @param meta the Metadata to use
  +     */
  +    public void setCollectionMeta(MetaData meta) throws DBException {
  +        if (!isMetaEnabled()) {
  +            if (log.isWarnEnabled()) {
  +                log.warn("Meta information requested but not enabled in 
config!");
  +            }
  +            return;
  +        }
  +        if (null != meta) {
  +            if (meta.getType() != MetaData.COLLECTION)
  +                throw new DBException(FaultCodes.GEN_UNKNOWN, "Mismatch type 
of meta data for collection " + getCanonicalName());
  +
  +            MetaSystemCollection metacol = getMetaSystemCollection();
  +            metacol.setCollectionMeta(this, meta);
  +        }
  +    }
  +
  +    protected final void setCollectionRoot(File collectionRoot) {
  +        this.collectionRoot = collectionRoot;
  +        if (!collectionRoot.exists())
  +            collectionRoot.mkdirs();
  +    }
  +
  +    public void setConfig(Configuration config) throws XindiceException {
  +        super.setConfig(config);
  +
  +        name = config.getAttribute(NAME);
  +        compressed = config.getBooleanAttribute(COMPRESSED, true);
  +
  +        /*
  +         * If inline metadata is desired, get an InlineMetaService object.
  +         */
  +        if (config.getBooleanAttribute(INLINE_METADATA, false)) {
  +            inlineMetaService = new InlineMetaService();
  +        }
  +
  +        /*
  +         * Wait to set up the local debug header until everything needed
  +         * by debugHeader() is complete!
  +         */
  +        String localDebugHeader = debugHeader() + "setConfig: ";
  +
  +        if (inlineMetaService == null) {
  +            log.debug(localDebugHeader + "inline metadata DISABLED");
  +        }
  +        else {
  +            log.debug(localDebugHeader + "inline metadata ENABLED");
  +        }
  +
  +        if (parent != null) {
  +            setCanonicalName(parent.getCanonicalName() + '/' + name);
  +            log.debug(localDebugHeader + "canonical name=<" + 
getCanonicalName() + ">");
  +            setCollectionRoot(new File(parent.getCollectionRoot(), name));
  +            log.debug(localDebugHeader + "collection root=<" + 
getCollectionRoot().toString() + ">");
  +        }
  +
  +        if (config.getBooleanAttribute(CACHE, true))
  +            documentCache = getDatabase().getDocumentCache();
  +
  +        // If no Filer is defined, skip Symbols and Indexes
  +        Configuration filerConfig = config.getChild(FILER);
  +        if (filerConfig != null) {
  +            log.debug(localDebugHeader + "have filer config...");
  +
  +            // Symbol Table Setup
  +            Configuration symConfig = config.getChild(SYMBOLS);
  +            internalSymbols = (symConfig != null);
  +            if (internalSymbols) {
  +                log.debug(localDebugHeader + "have internal symbols <" + 
TextWriter.toString(symConfig.getElement()) + ">");
  +                try {
  +                    symbols = new SymbolTable(symConfig.getElement());
  +                }
  +                catch (Exception e) {
  +                    if (log.isDebugEnabled()) {
  +                        log.debug("Error building symbol table from internal 
symbols", e);
  +                    }
  +                }
  +            }
  +            else {
  +                log.debug(localDebugHeader + "no internal symbols...");
  +                try {
  +                    symbols = getSystemCollection().loadSymbols(this);
  +                    log.debug(localDebugHeader + "loaded symbols from system 
collection <" + TextWriter.toString(symbols.streamToXML(new DocumentImpl())) + 
">");
  +                }
  +                catch (Exception e) {
  +                    if (log.isDebugEnabled()) {
  +                        log.debug("Error building symbol table from system 
collection...", e);
  +                    }
  +                }
  +            }
  +
  +            String className = filerConfig.getAttribute(CLASS);
  +            log.debug(localDebugHeader + "file class=<" + className + ">");
  +            try {
  +                filer = (Filer) Class.forName(className).newInstance();
  +                //            filer.setCollection(this);
  +                filer.setLocation(getCollectionRoot(), getName());
  +                filer.setConfig(filerConfig);
  +                if (!filer.exists())
  +                    filer.create();
  +                filer.open();
  +            }
  +            catch (Exception e) {
  +                if (log.isWarnEnabled()) {
  +                    log.warn("Filer '" + className + "' not available", e);
  +                }
  +            }
  +
  +            // Index Manager
  +            try {
  +                indexManager = new IndexManager(this);
  +                Configuration idxConfig = config.getChild(INDEXES, true);
  +                indexManager.setConfig(idxConfig);
  +            }
  +            catch (Exception e) {
  +                if (log.isDebugEnabled()) {
  +                    log.debug("No message", e);
  +                }
  +            }
  +        }
  +
  +        super.setConfig(config);
  +
  +        // observer
  +        DBObserver.getInstance().setCollectionConfig(this, config);
  +    }
  +
  +    /**
  +     * setDocument overwrites/updates an existing Document in a
  +     * Xindice Collection.
  +     *
  +     * @param docKey The Document Key
  +     * @param document The Document
  +     */
  +    public final void setDocument(Object docKey, Document document) throws 
DBException {
  +        putDocument(createNewKey(docKey), document /*, false */
  +        );
  +        // update the meta for this document
  +        updateDocumentMeta(docKey.toString());
  +    }
  +
  +    /**
  +     * Set the metadata associated with a document within this collection.
  +     * 
  +     * @param id the document name
  +     * @param meta the metadata object to be used.
  +     */
  +    public void setDocumentMeta(String id, MetaData meta) throws DBException 
{
  +        if (!isMetaEnabled()) {
  +            if (log.isWarnEnabled()) {
  +                log.warn("Meta information requested but not enabled in 
config!");
  +            }
  +            return;
  +        }
  +        Document doc = getDocument(id);
  +        if (null == doc)
  +            throw new DBException(FaultCodes.COL_DOCUMENT_NOT_FOUND, 
"Document " + id + " does not exist");
  +
  +        if (null != meta) {
  +            if (meta.getType() == MetaData.UNKNOWN || meta.getType() == 
MetaData.COLLECTION)
  +                throw new DBException(FaultCodes.GEN_UNKNOWN, "Mismatch type 
of meta data for document " + getCanonicalDocumentName(id));
  +
  +            MetaSystemCollection metacol = getMetaSystemCollection();
  +            metacol.setDocumentMeta(this, id, meta);
  +        }
  +    }
  +
  +    /**
  +     * @param string
  +     */
  +    protected void setName(String string) {
  +        name = string;
  +    }
  +
  +    /**
  +     * setObject sets an XMLSerializable object in the Collection based on 
the
  +     * provided Key.  Xindice takes care of associating the implementation 
class
  +     * with the XMLSerializable object.
  +     *
  +     * @param key The Key to use
  +     * @param obj The Object to set
  +     */
  +    public final void setObject(Object key, XMLSerializable obj) throws 
DBException {
  +        putObject(createNewKey(key), obj /*, false */
  +        );
  +    }
  +
  +    /**
  +     * update the modified time of this collection when appropriate
  +     */
  +    protected void updateCollectionMeta() {
  +        // update the meta data if necessary
  +        if (isMetaEnabled()) {
  +            MetaSystemCollection metacol = getMetaSystemCollection();
  +            MetaData meta = null;
  +            try {
  +                meta = metacol.getCollectionMeta(this);
  +            }
  +            catch (DBException e) {
  +                // something strange has happened.. can't get the
  +                // meta data for this collection
  +                if (log.isWarnEnabled())
  +                    log.warn("Error fetching collection meta. " + e);
  +                return;
  +            }
  +
  +            if (log.isInfoEnabled())
  +                log.info("Updating modified time for this collection's 
meta");
  +            long now = System.currentTimeMillis();
  +            if (null == meta) {
  +                meta = new MetaData(MetaData.COLLECTION, getCanonicalName(), 
now, now);
  +            }
  +            else {
  +                // this collection already has a meta.  so update its 
modified time.
  +                meta.setContext(0, now);
  +            }
  +            try {
  +                metacol.setCollectionMeta(this, meta);
  +            }
  +            catch (DBException e) {
  +                if (log.isWarnEnabled())
  +                    log.warn("Error setting the collection meta. " + e);
  +                return;
  +            }
  +        }
  +    }
  +
  +    /**
  +     * update the modified time of this document when appropriate
  +     */
  +    protected void updateDocumentMeta(String id) throws DBException {
  +        // update the meta data if necessary
  +        if (!isMetaEnabled())
  +            return;
  +
  +        Document doc = getDocument(id);
  +        if (null == doc)
  +            throw new DBException(FaultCodes.COL_DOCUMENT_NOT_FOUND, 
"Document " + id + " does not exist");
  +
  +        MetaSystemCollection metacol = getMetaSystemCollection();
  +        MetaData meta = metacol.getDocumentMeta(this, id);
  +
  +        String path = getCanonicalDocumentName(id);
  +
  +        /*
  +        TimeRecord rec = null;
  +        if( null == meta || !meta.hasContext() )
  +           rec = getDatabase().getTime(path);
  +        
  +        long created = (null != rec) ? rec.getCreatedTime() : 
System.currentTimeMillis();
  +        long modified = (null != rec) ? rec.getModifiedTime() : 
System.currentTimeMillis();
  +        */
  +
  +        // this is wrong.. but it should work for now...
  +        long created = System.currentTimeMillis();
  +        long modified = System.currentTimeMillis();
  +
  +        if (null == meta) {
  +            meta = new MetaData(MetaData.DOCUMENT, path, created, modified);
  +        }
  +        else if (!meta.hasContext()) {
  +            meta.setContext(created, modified);
  +        }
  +        else {
  +            meta.setContext(0, modified);
  +        }
  +        metacol.setDocumentMeta(this, id, meta);
  +    }
   }
  
  
  
  1.13      +94 -100   
xml-xindice/java/src/org/apache/xindice/core/SystemCollection.java
  
  Index: SystemCollection.java
  ===================================================================
  RCS file: 
/home/cvs/xml-xindice/java/src/org/apache/xindice/core/SystemCollection.java,v
  retrieving revision 1.12
  retrieving revision 1.13
  diff -u -r1.12 -r1.13
  --- SystemCollection.java     11 Dec 2002 00:22:56 -0000      1.12
  +++ SystemCollection.java     14 Jul 2003 19:07:15 -0000      1.13
  @@ -59,15 +59,13 @@
    * $Id$
    */
   
  +import org.apache.commons.logging.Log;
  +import org.apache.commons.logging.LogFactory;
   import org.apache.xindice.util.Configuration;
   import org.apache.xindice.xml.SymbolTable;
   import org.apache.xindice.xml.SymbolTableSymbols;
   import org.apache.xindice.xml.dom.DOMParser;
  -
  -import org.apache.commons.logging.Log;
  -import org.apache.commons.logging.LogFactory;
  -
  -import org.w3c.dom.*;
  +import org.w3c.dom.Document;
   
   /**
    * SystemCollection represents the System Collection.  Beyond
  @@ -77,98 +75,94 @@
   
   public final class SystemCollection extends Collection {
   
  -   public static final String SYSCOL = "system";
  -
  -   public static final String SYMBOLS = "SysSymbols";
  -   public static final String OBJECTS = "SysObjects";
  -   public static final String CONFIGS = "SysConfig";
  -   public static final String USERS = "SysUsers";
  -   public static final String GROUPS = "SysGroups";
  -   public static final String ACCESS = "SysAccess";
  -
  -   private static Log log = LogFactory.getLog("org.apache.xindice.core");
  -
  -   public SystemCollection(Database db) {
  -      super(db);
  -   }
  -
  -   void init() throws DBException {
  -      // Bootstrap the System Collection
  -
  -      String SysCol =
  -         "<collection name=\""+SYSCOL+"\">"
  -         
  -         // System Collections
  -       + "   <collections>"
  -         
  -         // Symbol Tables Collection
  -       + "      <collection name=\""+SYMBOLS+"\" compressed=\"true\">"
  -       + "         <filer class=\"org.apache.xindice.core.filer.BTreeFiler\" 
/>"
  -         // Textual Representation of Hard-coded Symbol Table
  -       + SymbolTableSymbols.getDefinition()
  -       + "      </collection>"
  -
  -         // System Configuration Collection
  -       + "      <collection name=\""+CONFIGS+"\" compressed=\"false\">"
  -       + "         <filer class=\"org.apache.xindice.core.filer.BTreeFiler\" 
/>"
  -       + "      </collection>"
  -         
  -       + "   </collections>"
  -       + "</collection>";
  -
  -      try {
  -         Document sysDoc = DOMParser.toDocument(SysCol);
  -         Configuration sysCfg = new Configuration(sysDoc, false);
  -         setConfig(sysCfg);
  -      }
  -      catch ( Exception e ) {
  -         if (log.isFatalEnabled()) {
  -            log.fatal("FATAL ERROR: Generating System Collection 
'"+SYSCOL+"'", e);
  -         }
  -         System.exit(1);
  -      }
  -   }
  -
  -   private String getSymbolTableName(Collection col) {
  -      String name = col.getCanonicalName();
  -      int idx = name.indexOf('/', 1);
  -      name = name.substring(idx+1);
  -      return name.replace('/', '_');
  -   }
  -
  -   /**
  -    * loadSymbols retrieves the SymbolTable for the specified Collection.
  -    *
  -    * @param collection The Collection whose SymbolTable is required
  -    * @return The requested SymbolTable
  -    */
  -   public SymbolTable loadSymbols(Collection collection) throws DBException  
{
  -      String name = getSymbolTableName(collection);
  -
  -      Collection symCol = getCollection(SYMBOLS);
  -
  -      SymbolTable symbols = (SymbolTable)symCol.getObject(name);
  -      if ( symbols == null ) {
  -         symbols = new SymbolTable();
  -         saveSymbols(collection, symbols);
  -      }
  -      return symbols;
  -   }
  -
  -   /**
  -    * saveSymbols save the SymbolTable for the specified Collection.
  -    *
  -    * @param collection The Collection that owns the SymbolTable
  -    * @param symbols The SymbolTable
  -    */
  -   public void saveSymbols(Collection collection, SymbolTable symbols) 
throws DBException  {
  -      String name = getSymbolTableName(collection);
  -
  -      Collection symCol = getCollection(SYMBOLS);
  -
  -      if ( symbols != null ) {
  -         symCol.setObject(name, symbols);
  -         symbols.setDirty(false);
  -      }
  -   }
  +    public static final String SYSCOL = "system";
  +    public static final String SYMBOLS = "SysSymbols";
  +    public static final String OBJECTS = "SysObjects";
  +    public static final String CONFIGS = "SysConfig";
  +    public static final String USERS = "SysUsers";
  +    public static final String GROUPS = "SysGroups";
  +    public static final String ACCESS = "SysAccess";
  +    private static Log log = LogFactory.getLog("org.apache.xindice.core");
  +
  +    /**
  +     * @param db
  +     */
  +    public SystemCollection(Database db) {
  +        super(db);
  +    }
  +
  +    void init() throws DBException {
  +        // Bootstrap the System Collection
  +
  +        String SysCol = "<collection name=\"" + SYSCOL + "\">"
  +            // System Collections
  +             +"   <collections>"
  +            // Symbol Tables Collection
  +             +"      <collection name=\"" + SYMBOLS + "\" 
compressed=\"true\">" + "         <filer 
class=\"org.apache.xindice.core.filer.BTreeFiler\" />"
  +            // Textual Representation of Hard-coded Symbol Table
  +             +SymbolTableSymbols.getDefinition() + "      </collection>"
  +            // System Configuration Collection
  +             +"      <collection name=\""
  +             + CONFIGS
  +             + "\" compressed=\"false\">"
  +             + "         <filer 
class=\"org.apache.xindice.core.filer.BTreeFiler\" />"
  +             + "      </collection>"
  +             + "   </collections>"
  +             + "</collection>";
  +
  +        try {
  +            Document sysDoc = DOMParser.toDocument(SysCol);
  +            Configuration sysCfg = new Configuration(sysDoc, false);
  +            setConfig(sysCfg);
  +        }
  +        catch (Exception e) {
  +            if (log.isFatalEnabled()) {
  +                log.fatal("FATAL ERROR: Generating System Collection '" + 
SYSCOL + "'", e);
  +            }
  +            System.exit(1);
  +        }
  +    }
  +
  +    private String getSymbolTableName(Collection col) {
  +        String name = col.getCanonicalName();
  +        int idx = name.indexOf('/', 1);
  +        name = name.substring(idx + 1);
  +        return name.replace('/', '_');
  +    }
  +
  +    /**
  +     * loadSymbols retrieves the SymbolTable for the specified Collection.
  +     *
  +     * @param collection The Collection whose SymbolTable is required
  +     * @return The requested SymbolTable
  +     */
  +    public SymbolTable loadSymbols(Collection collection) throws DBException 
{
  +        String name = getSymbolTableName(collection);
  +
  +        Collection symCol = getCollection(SYMBOLS);
  +
  +        SymbolTable symbols = (SymbolTable) symCol.getObject(name);
  +        if (symbols == null) {
  +            symbols = new SymbolTable();
  +            saveSymbols(collection, symbols);
  +        }
  +        return symbols;
  +    }
  +
  +    /**
  +     * saveSymbols save the SymbolTable for the specified Collection.
  +     *
  +     * @param collection The Collection that owns the SymbolTable
  +     * @param symbols The SymbolTable
  +     */
  +    public void saveSymbols(Collection collection, SymbolTable symbols) 
throws DBException {
  +        String name = getSymbolTableName(collection);
  +
  +        Collection symCol = getCollection(SYMBOLS);
  +
  +        if (symbols != null) {
  +            symCol.setObject(name, symbols);
  +            symbols.setDirty(false);
  +        }
  +    }
   }
  
  
  
  1.11      +208 -193  
xml-xindice/java/src/org/apache/xindice/core/CollectionManager.java
  
  Index: CollectionManager.java
  ===================================================================
  RCS file: 
/home/cvs/xml-xindice/java/src/org/apache/xindice/core/CollectionManager.java,v
  retrieving revision 1.10
  retrieving revision 1.11
  diff -u -r1.10 -r1.11
  --- CollectionManager.java    26 Nov 2002 02:17:18 -0000      1.10
  +++ CollectionManager.java    14 Jul 2003 19:07:15 -0000      1.11
  @@ -77,196 +77,211 @@
    */
   
   public class CollectionManager implements Configurable, Disposable {
  -   private static final String COLLECTIONS = "collections";
  -   private static final String COLLECTION = "collection";
  -   private static final String NAME = "name";
  -   
  -   private static Log log = LogFactory.getLog("org.apache.xindice.core");
  -
  -   private static final String[] EmptyStrings = new String[0];
  -   
  -   protected Map collections = new HashMap(); // Collection
  -
  -   protected Configuration config = null;
  -
  -   protected CollectionManager() {
  -   }
  -   
  -   public void setConfig(Configuration config) throws XindiceException {
  -      this.config = config;
  -
  -      Configuration colConfig = config.getChild(COLLECTIONS);
  -      if ( colConfig != null ) {
  -         colConfig.processChildren(COLLECTION,
  -            new ConfigurationCallback() {
  -               public void process(Configuration cfg) throws 
XindiceException {
  -                  // check for an existing Collection by name and, if found, 
skip creating a new Collection
  -                  // else, create a new child Collection, configure it an 
add it
  -                  // if the Collection already exists in our collections 
list,
  -                  // creating a new one will cause the old one to be 
discarded
  -                  // while holding open file handles, etc.
  -                  Collection col = 
(Collection)collections.get(cfg.getAttribute(NAME));
  -                  if(col == null)
  -                  {
  -                      col = new 
Collection((Collection)CollectionManager.this);
  -                  col.setConfig(cfg);
  -                  collections.put(col.getName(), col);
  -               }
  -                  // else, assume col is configured elsewhere...
  -                  // I'm not sure this should be happening, but it does
  -                  // it is not safe to call col.setConfig again since it 
does a bunch
  -                  // of stuff (like creating a new Filer and overwriting the 
existing one, etc.)
  -               }
  -         });
  -      }
  -   }
  -
  -   public Configuration getConfig() {
  -      return config;
  -   }
  -
  -   /**
  -    * getCollection retrieves a Collection by name.
  -    *
  -    * @param path The Collection path
  -    * @return The Collection (or null)
  -    */
  -   public Collection getCollection(String path) throws DBException {     
  -      if ( path.indexOf("/") != -1 ) {
  -         CollectionManager cm = this;
  -         StringTokenizer st = new StringTokenizer(path, "/");
  -         while ( cm != null && st.hasMoreTokens()) {
  -            path = st.nextToken();
  -            cm = (CollectionManager)cm.collections.get(path);
  -         }
  -         return (Collection)cm;
  -      }
  -      else
  -         return (Collection)collections.get(path);
  -   }
  -
  -   /**
  -    * listCollections retrieves a list of Collections as an array of
  -    * Strings.
  -    *
  -    * @return The Collection list
  -    */
  -   public final String[] listCollections() throws DBException {
  -      return (String[]) collections.keySet().toArray(EmptyStrings);
  -   }
  -
  -   /**
  -    * Returns number of child collections
  -    *
  -    * @return number of collections
  -    */
  -   public final long countCollections() throws DBException {
  -      return (long) collections.size();
  -   }
  -
  -   /**
  -    * dropCollection physically removes the specified Collection and any
  -    * associated system resources that the Collection uses.
  -    *
  -    * @param collection The Collection to drop
  -    * @return Whether or not the Collection was dropped
  -    */
  -   public boolean dropCollection(Collection collection) throws DBException  {
  -      if ( collection == null )
  -         throw new DBException(FaultCodes.COL_COLLECTION_NOT_FOUND, 
"Collection Value Null");
  -            
  -      Collection cm = collection.getParentCollection();
  -
  -      if ( cm == null )
  -         throw new DBException(FaultCodes.DBE_CANNOT_DROP, "You Cannot Drop 
The Database");
  -      
  -      if ( cm != this )
  -         return cm.dropCollection(collection);
  -      else {
  -         final String name = collection.getName();
  -         boolean dropped = collection.drop();
  -         if ( dropped ) {
  -            collections.remove(name);
  -            Configuration colConfig = config.getChild(COLLECTIONS);
  -            colConfig.processChildren(COLLECTION,
  -               new ConfigurationCallback() {
  -                  public void process(Configuration cfg) {
  -                     try {
  -                        if ( cfg.getAttribute(NAME).equals(name) )
  -                           cfg.delete();
  -                     }
  -                     catch ( Exception e ) {
  -                        if (log.isDebugEnabled()) {
  -                           log.debug("No message", e);
  -                        }
  -                     }
  -                  }
  -            });
  -         }
  -         return dropped;
  -      }
  -   }
  -
  -   /**
  -    * createCollection creates a new Collection object and any associated
  -    * system resources that the Collection will need.
  -    *
  -    * @param path The relative path of the Collection
  -    * @param cfg The Collection's configuration
  -    * @return The newly created Collection
  -    */
  -   public Collection createCollection(String path, Configuration cfg)
  -         throws DBException {
  -      if ( path.indexOf("/") != -1 ) {
  -         CollectionManager cm = this;
  -         StringTokenizer st = new StringTokenizer(path, "/");
  -         while ( cm != null && st.hasMoreTokens()) {
  -            path = st.nextToken().trim();
  -            if ( path.length() == 0 )
  -               continue;
  -            if ( st.hasMoreTokens() )
  -               cm = (CollectionManager)cm.collections.get(path);
  -            else
  -               return cm.createCollection(path, cfg);
  -         }
  -         throw new DBException(FaultCodes.COL_COLLECTION_NOT_FOUND, "Parent 
Collection '"+path+"' doesn't exist");
  -      }
  -
  -      Collection collection = null;
  -
  -      if ( CollectionManager.this instanceof Database )
  -         collection = new Collection((Database)CollectionManager.this);
  -      else
  -         collection = new Collection((Collection)CollectionManager.this);
  -      
  -      try {
  -         // Do a name check to see if all is well
  -         String n = cfg.getAttribute(NAME);
  -         if ( n == null || n.trim().equals("") )
  -            throw new DBException(FaultCodes.COL_CANNOT_CREATE, "No name 
specified");
  -         
  -         if ( getCollection(n) != null )
  -            throw new DBException(FaultCodes.COL_DUPLICATE_COLLECTION, 
"Duplicate Collection '"+n+"'");
  -
  -         Configuration colConfig = this.config.getChild(COLLECTIONS, true);
  -         colConfig.add(cfg);
  -         
  -         collection.setConfig(cfg);
  -         collection.create();
  -         collections.put(n, collection);
  -         if (log.isInfoEnabled()) {
  -            log.info("Created a new collection named '"+n+"'");
  -         }
  -      }
  -      catch ( DBException e ) {
  -         throw e;
  -      }
  -      catch ( Exception e ) {
  -         throw new DBException(FaultCodes.COL_CANNOT_CREATE, "Error Creating 
Collection '"+path+"'", e);
  -      }
  -      return collection;
  -   }
  -   
  -   public void dispose() {
  -   }
  +     private static final String COLLECTION = "collection";
  +     private static final String COLLECTIONS = "collections";
  +     private static final String[] EmptyStrings = new String[0];
  +     private static Log log = LogFactory.getLog("org.apache.xindice.core");
  +     private static final String NAME = "name";
  +     private Map collections = new HashMap(); // Collection
  +     private Configuration config = null;
  +     
  +     protected CollectionManager() {}
  +     
  +     /**
  +      * 
  +      * @param collection
  +      */
  +     protected void addCollection(Collection collection){
  +
  +             this.collections.put(collection.getName(), collection);         
  +     }
  +
  +     /**
  +      * Returns number of child collections
  +      *
  +      * @return number of collections
  +      */
  +     public final long countCollections() throws DBException {
  +             return (long) collections.size();
  +     }
  +
  +     /**
  +      * createCollection creates a new Collection object and any associated
  +      * system resources that the Collection will need.
  +      *
  +      * @param path The relative path of the Collection
  +      * @param cfg The Collection's configuration
  +      * @return The newly created Collection
  +      */
  +     public Collection createCollection(String path, Configuration cfg) 
throws DBException {
  +             if (path.indexOf("/") != -1) {
  +                     CollectionManager cm = this;
  +                     StringTokenizer st = new StringTokenizer(path, "/");
  +                     while (cm != null && st.hasMoreTokens()) {
  +                             path = st.nextToken().trim();
  +                             if (path.length() == 0)
  +                                     continue;
  +                             if (st.hasMoreTokens())
  +                                     cm = (CollectionManager) 
cm.collections.get(path);
  +                             else
  +                                     return cm.createCollection(path, cfg);
  +                     }
  +                     throw new 
DBException(FaultCodes.COL_COLLECTION_NOT_FOUND, "Parent Collection '" + path + 
"' doesn't exist");
  +             }
  +
  +             Collection collection = null;
  +
  +             if (CollectionManager.this instanceof Database)
  +                     collection = new Collection((Database) 
CollectionManager.this);
  +             else
  +                     collection = new Collection((Collection) 
CollectionManager.this);
  +
  +             try {
  +                     // Do a name check to see if all is well
  +                     String n = cfg.getAttribute(NAME);
  +                     if (n == null || n.trim().equals(""))
  +                             throw new 
DBException(FaultCodes.COL_CANNOT_CREATE, "No name specified");
  +
  +                     if (getCollection(n) != null)
  +                             throw new 
DBException(FaultCodes.COL_DUPLICATE_COLLECTION, "Duplicate Collection '" + n + 
"'");
  +
  +                     Configuration colConfig = 
this.config.getChild(COLLECTIONS, true);
  +                     colConfig.add(cfg);
  +
  +                     collection.setConfig(cfg);
  +                     collection.create();
  +                     collections.put(n, collection);
  +                     if (log.isInfoEnabled()) {
  +                             log.info("Created a new collection named '" + n 
+ "'");
  +                     }
  +             }
  +             catch (DBException e) {
  +                     throw e;
  +             }
  +             catch (Exception e) {
  +                     throw new DBException(FaultCodes.COL_CANNOT_CREATE, 
"Error Creating Collection '" + path + "'", e);
  +             }
  +             return collection;
  +     }
  +
  +     /**
  +     * @see org.apache.xindice.util.Disposable#dispose()
  +     */
  +    public void dispose() {}
  +
  +     /**
  +      * dropCollection physically removes the specified Collection and any
  +      * associated system resources that the Collection uses.
  +      *
  +      * @param collection The Collection to drop
  +      * @return Whether or not the Collection was dropped
  +      */
  +     public boolean dropCollection(Collection collection) throws DBException 
{
  +             if (collection == null)
  +                     throw new 
DBException(FaultCodes.COL_COLLECTION_NOT_FOUND, "Collection Value Null");
  +
  +             Collection cm = collection.getParentCollection();
  +
  +             if (cm == null)
  +                     throw new DBException(FaultCodes.DBE_CANNOT_DROP, "You 
Cannot Drop The Database");
  +
  +             if (cm != this)
  +                     return cm.dropCollection(collection);
  +             else {
  +                     final String name = collection.getName();
  +                     boolean dropped = collection.drop();
  +                     if (dropped) {
  +                             collections.remove(name);
  +                             Configuration colConfig = 
config.getChild(COLLECTIONS);
  +                             colConfig.processChildren(COLLECTION, new 
ConfigurationCallback() {
  +                                     public void process(Configuration cfg) {
  +                                             try {
  +                                                     if 
(cfg.getAttribute(NAME).equals(name))
  +                                                             cfg.delete();
  +                                             }
  +                                             catch (Exception e) {
  +                                                     if 
(log.isDebugEnabled()) {
  +                                                             log.debug("No 
message", e);
  +                                                     }
  +                                             }
  +                                     }
  +                             });
  +                     }
  +                     return dropped;
  +             }
  +     }
  +
  +     /**
  +      * getCollection retrieves a Collection by name.
  +      *
  +      * @param path The Collection path
  +      * @return The Collection (or null)
  +      */
  +     public Collection getCollection(String path) throws DBException {
  +             if (path.indexOf("/") != -1) {
  +                     CollectionManager cm = this;
  +                     StringTokenizer st = new StringTokenizer(path, "/");
  +                     while (cm != null && st.hasMoreTokens()) {
  +                             path = st.nextToken();
  +                             cm = (CollectionManager) 
cm.collections.get(path);
  +                     }
  +                     return (Collection) cm;
  +             }
  +             else
  +                     return (Collection) collections.get(path);
  +     }
  +     
  +     /**
  +      * @return
  +      */
  +     protected Map getCollections() {
  +             return this.collections;
  +     }       
  +
  +     /**
  +     * @see org.apache.xindice.util.Configurable#getConfig()
  +     */
  +    public Configuration getConfig() {
  +             return config;
  +     }
  +
  +     /**
  +      * listCollections retrieves a list of Collections as an array of
  +      * Strings.
  +      *
  +      * @return The Collection list
  +      */
  +     public final String[] listCollections() throws DBException {
  +             return (String[]) collections.keySet().toArray(EmptyStrings);
  +     }
  +
  +     /**
  +     * @see 
org.apache.xindice.util.Configurable#setConfig(org.apache.xindice.util.Configuration)
  +     */
  +    public void setConfig(Configuration config) throws XindiceException {
  +             this.config = config;
  +
  +             Configuration colConfig = config.getChild(COLLECTIONS);
  +             if (colConfig != null) {
  +                     colConfig.processChildren(COLLECTION, new 
ConfigurationCallback() {
  +                             public void process(Configuration cfg) throws 
XindiceException {
  +                                     // check for an existing Collection by 
name and, if found, skip creating a new Collection
  +                                     // else, create a new child Collection, 
configure it an add it
  +                                     // if the Collection already exists in 
our collections list,
  +                                     // creating a new one will cause the 
old one to be discarded
  +                                     // while holding open file handles, etc.
  +                                     Collection col = (Collection) 
collections.get(cfg.getAttribute(NAME));
  +                                     if (col == null) {
  +                                             col = new 
Collection((Collection) CollectionManager.this);
  +                                             col.setConfig(cfg);
  +                                             collections.put(col.getName(), 
col);
  +                                     }
  +                                     // else, assume col is configured 
elsewhere...
  +                                     // I'm not sure this should be 
happening, but it does
  +                                     // it is not safe to call col.setConfig 
again since it does a bunch
  +                                     // of stuff (like creating a new Filer 
and overwriting the existing one, etc.)
  +                             }
  +                     });
  +             }
  +     }
   }
  
  
  
  1.11      +177 -179  
xml-xindice/java/src/org/apache/xindice/client/xmldb/embed/DatabaseImpl.java
  
  Index: DatabaseImpl.java
  ===================================================================
  RCS file: 
/home/cvs/xml-xindice/java/src/org/apache/xindice/client/xmldb/embed/DatabaseImpl.java,v
  retrieving revision 1.10
  retrieving revision 1.11
  diff -u -r1.10 -r1.11
  --- DatabaseImpl.java 10 Jul 2003 21:42:48 -0000      1.10
  +++ DatabaseImpl.java 14 Jul 2003 19:07:16 -0000      1.11
  @@ -56,7 +56,6 @@
    *
    * $Id$
    */
  -
   package org.apache.xindice.client.xmldb.embed;
   
   import org.apache.xindice.client.xmldb.CommonConfigurable;
  @@ -88,184 +87,183 @@
    */
   public class DatabaseImpl extends CommonConfigurable implements 
org.xmldb.api.base.Database {
   
  -     private static Log log = 
LogFactory.getLog("org.apache.xindice.client.embed");
  -
  -     /* prefix used to denote XML:DB URI's that should use this driver */
  -     static String DRIVER_NAME = "xindice-embed";
  +    private static Log log = 
LogFactory.getLog("org.apache.xindice.client.embed");
   
  -     /* XML:DB conformance level of this driver */
  -     private String CONFORMANCE_LEVEL = "0";
  +    /** prefix used to denote XML:DB URI's that should use this driver */
  +    public static final String DRIVER_NAME = "xindice-embed";
   
  -     protected Database db;
  -
  -     /**
  -      * Creates new <code>DatabaseImpl</code> instance. The configuration is
  -      * loaded from the file defined in the PROP_XINDICE_CONFIGURATION system
  -      * variable.
  -      *
  -      * This is only a temporarly solution since the question of a new init
  -      * method is raised in the xmldb:api group. Another solution could be to
  -      * use the Configurable interface and only create the database when the
  -      * getCollection method is called.
  -      */
  -     public DatabaseImpl() throws FileNotFoundException, XindiceException {
  -             
  -             Configuration config = loadConfiguration();
  -             this.db = Database.getDatabase(config);
  -
  -             if (null == this.db) {
  -                     log.fatal("Unable to configure database");
  -
  -                     throw new XindiceException("Unable to configure 
database");
  -             }
  -             else if (log.isInfoEnabled()) {
  -                     log.info("Database name: '" + this.db.getName() + "'");
  -             }
  -     }
  -
  -     protected Configuration loadConfiguration() throws 
FileNotFoundException, XindiceException, ReadOnlyException {
  -             Configuration config;
  -             String configFile = 
System.getProperty(Xindice.PROP_XINDICE_CONFIGURATION);
  -             if (configFile != null && !configFile.equals("")) {
  -                     if (log.isInfoEnabled()) {
  -                             log.info("Specified configuration file: '" + 
configFile + "'");
  -                     }
  -                     FileInputStream configXMLFile = new FileInputStream(new 
File(configFile));
  -
  -                     config = new 
Configuration(DOMParser.toDocument(configXMLFile), false);
  -             }
  -             else {
  -                     if (log.isInfoEnabled()) {
  -                             log.info("No configuration file specified, 
going with the default configuration");
  -                     }
  -                     config = new 
Configuration(DOMParser.toDocument(Xindice.DEFAULT_CONFIGURATION), false);
  -             }
  -
  -             config = config.getChild("root-collection", false);
  -             return config;
  -     }
  -
  -     /**
  -      * Determines whether this <code>Database</code> implementation  can 
handle
  -      * the URI. It should return true if the Database instance knows how to
  -      * handle the URI and false otherwise.
  -      *
  -      * @param uri the URI to check for.
  -      * @return true if the URI can be handled, false otherwise.
  -      * @exception XMLDBException with expected error codes.<br />
  -      *  <code>ErrorCodes.VENDOR_ERROR</code> for any vendor
  -      *  specific errors that occur.<br />
  -      *  <code>ErrroCodes.INVALID_URI</code> If the URI is not in a valid 
format. <br />
  -      */
  -     public boolean acceptsURI(String uri) throws XMLDBException {
  -
  -             return ((uri != null) && uri.startsWith(getName() + "://"));
  -     }
  -
  -     /**
  -      * Retrieves a <code>Collection</code> instance based on the URI 
provided
  -      * in the <code>uri</code> parameter. The format of the URI is defined 
in the
  -      * documentation for DatabaseManager.getCollection().<p/>
  -      *
  -      * Authentication is handled via username and password however it is not
  -      * required that the database support authentication. Databases that do 
not
  -      * support authentication MUST ignore the
  -      * <code>username</code> and <code>password</code> if those provided 
are not
  -      * null.
  -      *
  -      * @param uri the URI to use to locate the collection.
  -      * @param password The password to use for authentication to the 
database or
  -      *    null if the database does not support authentication.
  -      * @return A <code>Collection</code> instance for the requested 
collection or
  -      *  null if the collection could not be found.
  -      * @return The <code>Collection</code> instance
  -      * @exception XMLDBException with expected error codes.<br />
  -      *  <code>ErrorCodes.VENDOR_ERROR</code> for any vendor
  -      *  specific errors that occur.<br />
  -      *  <code>ErrroCodes.INVALID_URI</code> If the URI is not in a valid 
format. <br />
  -      *  <code>ErrroCodes.PERMISSION_DENIED</code> If the 
<code>username</code>
  -      *    and <code>password</code> were not accepted by the database.
  -      */
  -     public Collection getCollection(String uri, String userName, String 
password) throws XMLDBException {
  -             /* TODO: introduce authentication some day */
  -
  -             if (!acceptsURI(uri)) {
  -                     throw new XMLDBException(ErrorCodes.INVALID_URI, 
"Invalid URL: " + uri);
  -             }
  -
  -             /* Chop off driver prefix, and '://' */
  -             uri = uri.substring(getName().length() + 3);
  -
  -             /* Extract host name & port, if present */
  -             int firstSlash = uri.indexOf('/');
  -             if (firstSlash == -1) {
  -                     throw new XMLDBException(ErrorCodes.INVALID_URI);
  -             }
  -
  -             String collPath = uri.substring(firstSlash);
  -
  -             // The path must start with a /
  -             if (collPath.startsWith("/")) {
  -                     // find the database name. We just skip the first slash
  -                     int colIndex = collPath.indexOf('/', 1);
  -
  -                     // We assume there's no collection specified
  -                     String dbName = collPath.substring(1);
  -                     String colName = "/";
  -
  -                     // if colIndex isn't -1 then we need to pick out the db 
and collection
  -                     if (colIndex != -1) {
  -                             dbName = collPath.substring(1, colIndex);
  -
  -                             // The rest of the name locates the collection
  -                             colName = collPath.substring(colIndex);
  -                     }
  -
  -                     if (colName.equals("")) {
  -                             colName = "/";
  -                     }
  -
  -                     try {
  -                             return new CollectionImpl(db, colName);
  -                     }
  -                     catch (XMLDBException e) {
  -                             if (e.errorCode == 
ErrorCodes.NO_SUCH_COLLECTION) {
  -                                     // per getCollection contract, return 
null if not found
  -                                     return null;
  -                             }
  -                             throw e;
  -                     }
  -             }
  -             else {
  -                     throw new XMLDBException(ErrorCodes.INVALID_URI, 
"Collection name must begin with a '/'");
  -             }
  -     }
  -
  -     /**
  -      * Returns the prefix used in XML:DB to denote URI's that this driver 
can
  -      * handle.
  -      *
  -      * @return the prefix driver name
  -      * @exception XMLDBException with expected error codes.<br />
  -      *  <code>ErrorCodes.VENDOR_ERROR</code> for any vendor
  -      *  specific errors that occur.<br />
  -      */
  -     public String getName() throws XMLDBException {
  -             return DRIVER_NAME;
  -     }
  -
  -     /**
  -      * Returns the XML:DB API Conformance level for the implementation. 
This can
  -      * be used by client programs to determine what functionality is 
available to
  -      * them.
  -      *
  -      * @return the XML:DB API conformance level for this implementation.
  -      * @exception XMLDBException with expected error codes.<br />
  -      *  <code>ErrorCodes.VENDOR_ERROR</code> for any vendor
  -      *  specific errors that occur.<br />
  -      */
  -     public String getConformanceLevel() throws XMLDBException {
  -             return CONFORMANCE_LEVEL;
  -     }
  +    /** XML:DB conformance level of this driver */
  +    private String CONFORMANCE_LEVEL = "0";
  +    private Database database;
  +
  +    /**
  +     * Creates new <code>DatabaseImpl</code> instance. The configuration is
  +     * loaded from the file defined in the PROP_XINDICE_CONFIGURATION system
  +     * variable.
  +     *
  +     * This is only a temporarly solution since the question of a new init
  +     * method is raised in the xmldb:api group. Another solution could be to
  +     * use the Configurable interface and only create the database when the
  +     * getCollection method is called.
  +     */
  +    public DatabaseImpl() throws FileNotFoundException, XindiceException {
  +
  +        Configuration config = loadConfiguration();
  +        this.database = Database.getDatabase(config);
  +
  +        if (null == this.database) {
  +            log.fatal("Unable to configure database");
  +
  +            throw new XindiceException("Unable to configure database");
  +        }
  +        else if (log.isInfoEnabled()) {
  +            log.info("Database name: '" + this.database.getName() + "'");
  +        }
  +    }
  +
  +    protected Configuration loadConfiguration() throws 
FileNotFoundException, XindiceException, ReadOnlyException {
  +        Configuration config;
  +        String configFile = 
System.getProperty(Xindice.PROP_XINDICE_CONFIGURATION);
  +        if (configFile != null && !configFile.equals("")) {
  +            if (log.isInfoEnabled()) {
  +                log.info("Specified configuration file: '" + configFile + 
"'");
  +            }
  +            FileInputStream configXMLFile = new FileInputStream(new 
File(configFile));
  +
  +            config = new Configuration(DOMParser.toDocument(configXMLFile), 
false);
  +        }
  +        else {
  +            if (log.isInfoEnabled()) {
  +                log.info("No configuration file specified, going with the 
default configuration");
  +            }
  +            config = new 
Configuration(DOMParser.toDocument(Xindice.DEFAULT_CONFIGURATION), false);
  +        }
  +
  +        config = config.getChild("root-collection", false);
  +        return config;
  +    }
  +
  +    /**
  +     * Determines whether this <code>Database</code> implementation  can 
handle
  +     * the URI. It should return true if the Database instance knows how to
  +     * handle the URI and false otherwise.
  +     *
  +     * @param uri the URI to check for.
  +     * @return true if the URI can be handled, false otherwise.
  +     * @exception XMLDBException with expected error codes.<br />
  +     *  <code>ErrorCodes.VENDOR_ERROR</code> for any vendor
  +     *  specific errors that occur.<br />
  +     *  <code>ErrroCodes.INVALID_URI</code> If the URI is not in a valid 
format. <br />
  +     */
  +    public boolean acceptsURI(String uri) throws XMLDBException {
  +
  +        return ((uri != null) && uri.startsWith(getName() + "://"));
  +    }
  +
  +    /**
  +     * Retrieves a <code>Collection</code> instance based on the URI provided
  +     * in the <code>uri</code> parameter. The format of the URI is defined 
in the
  +     * documentation for DatabaseManager.getCollection().<p/>
  +     *
  +     * Authentication is handled via username and password however it is not
  +     * required that the database support authentication. Databases that do 
not
  +     * support authentication MUST ignore the
  +     * <code>username</code> and <code>password</code> if those provided are 
not
  +     * null.
  +     *
  +     * @param uri the URI to use to locate the collection.
  +     * @param password The password to use for authentication to the 
database or
  +     *    null if the database does not support authentication.
  +     * @return A <code>Collection</code> instance for the requested 
collection or
  +     *  null if the collection could not be found.
  +     * @return The <code>Collection</code> instance
  +     * @exception XMLDBException with expected error codes.<br />
  +     *  <code>ErrorCodes.VENDOR_ERROR</code> for any vendor
  +     *  specific errors that occur.<br />
  +     *  <code>ErrroCodes.INVALID_URI</code> If the URI is not in a valid 
format. <br />
  +     *  <code>ErrroCodes.PERMISSION_DENIED</code> If the 
<code>username</code>
  +     *    and <code>password</code> were not accepted by the database.
  +     */
  +    public Collection getCollection(String uri, String userName, String 
password) throws XMLDBException {
  +        /* TODO: introduce authentication some day */
  +
  +        if (!acceptsURI(uri)) {
  +            throw new XMLDBException(ErrorCodes.INVALID_URI, "Invalid URL: " 
+ uri);
  +        }
  +
  +        /* Chop off driver prefix, and '://' */
  +        uri = uri.substring(getName().length() + 3);
  +
  +        /* Extract host name & port, if present */
  +        int firstSlash = uri.indexOf('/');
  +        if (firstSlash == -1) {
  +            throw new XMLDBException(ErrorCodes.INVALID_URI);
  +        }
  +
  +        String collPath = uri.substring(firstSlash);
  +
  +        // The path must start with a /
  +        if (collPath.startsWith("/")) {
  +            // find the database name. We just skip the first slash
  +            int colIndex = collPath.indexOf('/', 1);
  +
  +            // We assume there's no collection specified
  +            String dbName = collPath.substring(1);
  +            String colName = "/";
  +
  +            // if colIndex isn't -1 then we need to pick out the db and 
collection
  +            if (colIndex != -1) {
  +                dbName = collPath.substring(1, colIndex);
  +
  +                // The rest of the name locates the collection
  +                colName = collPath.substring(colIndex);
  +            }
  +
  +            if (colName.equals("")) {
  +                colName = "/";
  +            }
  +
  +            try {
  +                return new CollectionImpl(database, colName);
  +            }
  +            catch (XMLDBException e) {
  +                if (e.errorCode == ErrorCodes.NO_SUCH_COLLECTION) {
  +                    // per getCollection contract, return null if not found
  +                    return null;
  +                }
  +                throw e;
  +            }
  +        }
  +        else {
  +            throw new XMLDBException(ErrorCodes.INVALID_URI, "Collection 
name must begin with a '/'");
  +        }
  +    }
  +
  +    /**
  +     * Returns the prefix used in XML:DB to denote URI's that this driver can
  +     * handle.
  +     *
  +     * @return the prefix driver name
  +     * @exception XMLDBException with expected error codes.<br />
  +     *  <code>ErrorCodes.VENDOR_ERROR</code> for any vendor
  +     *  specific errors that occur.<br />
  +     */
  +    public String getName() throws XMLDBException {
  +        return DRIVER_NAME;
  +    }
  +
  +    /**
  +     * Returns the XML:DB API Conformance level for the implementation. This 
can
  +     * be used by client programs to determine what functionality is 
available to
  +     * them.
  +     *
  +     * @return the XML:DB API conformance level for this implementation.
  +     * @exception XMLDBException with expected error codes.<br />
  +     *  <code>ErrorCodes.VENDOR_ERROR</code> for any vendor
  +     *  specific errors that occur.<br />
  +     */
  +    public String getConformanceLevel() throws XMLDBException {
  +        return CONFORMANCE_LEVEL;
  +    }
   
   }
  
  
  

Reply via email to