You are viewing a plain text version of this content. The canonical link for it is here.
Posted to xindice-dev@xml.apache.org by br...@apache.org on 2001/12/06 22:00:15 UTC

cvs commit: xml-xindice/Xindice/java/src/org/apache/xindice/core/xupdate XObjectImpl.java XPathQueryFactoryImpl.java XPathQueryImpl.java XUpdateImpl.java XUpdateQueryResolver.java package.html

bradford    01/12/06 13:00:15

  Added:       Xindice/java/src/org/apache/xindice/core Collection.java
                        CollectionManager.java Container.java
                        DBException.java DBObject.java Database.java
                        DocumentCache.java FaultCodes.java
                        SystemCollection.java package.html
               Xindice/java/src/org/apache/xindice/core/data
                        DocumentSet.java EmptyDocumentSet.java
                        EmptyNodeSet.java EmptyRecordSet.java Key.java
                        NodeSet.java Record.java RecordSet.java Value.java
                        package.html
               Xindice/java/src/org/apache/xindice/core/filer BTree.java
                        BTreeCallback.java BTreeCorruptException.java
                        BTreeException.java BTreeFiler.java
                        BTreeNotFoundException.java FSFiler.java Filer.java
                        FilerException.java HashFiler.java MemFiler.java
                        Paged.java Streamable.java package.html
               Xindice/java/src/org/apache/xindice/core/indexer
                        CannotCreateException.java
                        DuplicateIndexException.java IndexManager.java
                        IndexMatch.java IndexPattern.java IndexQuery.java
                        Indexer.java IndexerException.java NameIndexer.java
                        ValueIndexer.java package.html
               Xindice/java/src/org/apache/xindice/core/indexer/helpers
                        IndexQueryANY.java IndexQueryBW.java
                        IndexQueryBWX.java IndexQueryEQ.java
                        IndexQueryGEQ.java IndexQueryGT.java
                        IndexQueryIN.java IndexQueryLEQ.java
                        IndexQueryLT.java IndexQueryNBW.java
                        IndexQueryNBWX.java IndexQueryNEQ.java
                        IndexQueryNIN.java IndexQueryNSW.java
                        IndexQuerySW.java package.html
               Xindice/java/src/org/apache/xindice/core/objects Args.java
                        CannotCreateException.java
                        ClassFormatException.java
                        DuplicateObjectException.java ElementArgs.java
                        InvalidContextException.java MapArgs.java
                        MethodNotFoundException.java Reflectable.java
                        Reflector.java SimpleReflectable.java
                        SimpleXMLObject.java ThreadPolicy.java Types.java
                        Variant.java XMLObject.java XMLObjectException.java
                        XMLObjectManager.java
                        XMLObjectRuntimeException.java package.html
               Xindice/java/src/org/apache/xindice/core/query
                        CompilationException.java NodeListSet.java
                        ProcessingException.java Query.java
                        QueryEngine.java QueryException.java
                        QueryResolver.java StyleNotFoundException.java
                        XPathQueryResolver.java package.html
               Xindice/java/src/org/apache/xindice/core/request
                        URIMapper.java XindiceStreamHandler.java
                        XindiceStreamHandlerFactory.java package.html
               Xindice/java/src/org/apache/xindice/core/security
                        AccessDeniedException.java Credentials.java
                        DBSecurityManager.java
                        InvalidCredentialsException.java
                        InvalidPasswordException.java
                        LocalSecurityManager.java PasswordCredentials.java
                        Permission.java ResourcePermissions.java
                        SecurityException.java UnknownUserException.java
                        package.html
               Xindice/java/src/org/apache/xindice/core/system
                        Sequencer.java package.html
               Xindice/java/src/org/apache/xindice/core/xupdate
                        XObjectImpl.java XPathQueryFactoryImpl.java
                        XPathQueryImpl.java XUpdateImpl.java
                        XUpdateQueryResolver.java package.html
  Log:
  Added the files from the core package that CVS kindly ignored on import
  
  Revision  Changes    Path
  1.1                  xml-xindice/Xindice/java/src/org/apache/xindice/core/Collection.java
  
  Index: Collection.java
  ===================================================================
  package org.apache.xindice.core;
  
  /*
   * The Apache Software License, Version 1.1
   *
   *
   * Copyright (c) 1999 The Apache Software Foundation.  All rights
   * reserved.
   *
   * Redistribution and use in source and binary forms, with or without
   * modification, are permitted provided that the following conditions
   * are met:
   *
   * 1. Redistributions of source code must retain the above copyright
   *    notice, this list of conditions and the following disclaimer.
   *
   * 2. Redistributions in binary form must reproduce the above copyright
   *    notice, this list of conditions and the following disclaimer in
   *    the documentation and/or other materials provided with the
   *    distribution.
   *
   * 3. The end-user documentation included with the redistribution,
   *    if any, must include the following acknowledgment:
   *       "This product includes software developed by the
   *        Apache Software Foundation (http://www.apache.org/)."
   *    Alternately, this acknowledgment may appear in the software itself,
   *    if and wherever such third-party acknowledgments normally appear.
   *
   * 4. The names "Xindice" and "Apache Software Foundation" must
   *    not be used to endorse or promote products derived from this
   *    software without prior written permission. For written
   *    permission, please contact apache@apache.org.
   *
   * 5. Products derived from this software may not be called "Apache",
   *    nor may "Apache" appear in their name, without prior written
   *    permission of the Apache Software Foundation.
   *
   * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
   * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
   * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
   * DISCLAIMED.  IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
   * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
   * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
   * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
   * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
   * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
   * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
   * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
   * SUCH DAMAGE.
   * ====================================================================
   *
   * This software consists of voluntary contributions made by many
   * individuals on behalf of the Apache Software Foundation and was
   * originally based on software copyright (c) 1999-2001, The dbXML
   * Group, L.L.C., http://www.dbxmlgroup.com.  For more
   * information on the Apache Software Foundation, please see
   * <http://www.apache.org/>.
   *
   * $Id: Collection.java,v 1.1 2001/12/06 21:00:11 bradford Exp $
   */
  
  import org.apache.xindice.xml.*;
  import org.apache.xindice.xml.dom.*;
  import org.apache.xindice.core.objects.*;
  import org.apache.xindice.core.data.*;
  import org.apache.xindice.core.filer.*;
  import org.apache.xindice.core.indexer.*;
  import org.apache.xindice.core.query.*;
  import org.apache.xindice.util.*;
  
  import org.w3c.dom.*;
  
  import java.io.*;
  import java.net.*;
  import java.util.*;
  
  /**
   * Collection represents a collection of Documents maintains links to the
   * Filer storage implementation, the Indexes, and any XMLObjects that may
   * be associated with the Collection.
   */
  
  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 LOCATION = "location";
     private static final String INDEXES = "indexes";
     private static final String COMPRESSED = "compressed";
     private static final String CACHE = "cache";
     private static final String XMLOBJECTS = "xmlobjects";
     private static final String DOCUMENTS = "documents";
     private static final String SYMBOLS = "symbols";
     private static final String CLASSNAME = "xindice-class";
     
     private static final String[] EmptyStrings = new String[0];
     
     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 XMLObjectManager xmlObjects;
     private DocumentCache documentCache;
  
     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 ( parent != null ) {
           setCanonicalName(parent.getCanonicalName()+'/'+name);
           setCollectionRoot(new File(parent.getCollectionRoot(), name));
        }
  
        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 ) {
           
           // Symbol Table Setup
           Configuration symConfig = config.getChild(SYMBOLS);
           internalSymbols = (symConfig != null);
           if ( internalSymbols ) {
              try {
                 symbols = new SymbolTable(symConfig.getElement());
              }
              catch ( Exception e ) {
                 org.apache.xindice.Debug.printStackTrace(e);
              }
           }
           else {
              try {
                 symbols = getSystemCollection().loadSymbols(this);
              }
              catch ( Exception e ) {
                 org.apache.xindice.Debug.printStackTrace(e);
              }
           }
           
           String className = filerConfig.getAttribute(CLASS);
           try {
              filer = (Filer)Class.forName(className).newInstance();
              filer.setCollection(this);
              filer.setConfig(filerConfig);
              if ( !filer.exists() )
                 filer.create();
              filer.open();
           }
           catch ( Exception e ) {
              org.apache.xindice.Debug.println("Filer '"+className+"' not available");
           }
           
           // Index Manager
           try {
              indexManager = new IndexManager(this);
              Configuration idxConfig = config.getChild(INDEXES, true);
              indexManager.setConfig(idxConfig);
           }
           catch ( Exception e ) {
              org.apache.xindice.Debug.printStackTrace(e);
           }
        }
  
        // XMLObject Manager
        xmlObjects = new XMLObjectManager(this);
        try {
           Configuration objConfig = config.getChild(XMLOBJECTS, true);
           xmlObjects.setConfig(objConfig);
        }
        catch ( Exception e ) {
           org.apache.xindice.Debug.printStackTrace(e);
        }
        
        super.setConfig(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;
     }
  
     
     /**
      * getXMLObjectManager returns the Object's XMLObjectManager.
      *
      * @return The XMLObjectManager
      */
     public final XMLObjectManager getXMLObjectManager() throws DBException {
        return xmlObjects;
     }
     
     /**
      * getXMLObject retrieves an XMLObject by name.
      *
      * @param name The XMLObject's name
      * @return The XMLObject (or null)
      */
     public final XMLObject getXMLObject(String name) throws DBException {
        return xmlObjects.get(name);
     }
  
     /**
      * listXMLObjects returns a list of the currently registered XMLObjects
      * as an array of String.
      *
      * @return The XMLObject list
      */
     public String[] listXMLObjects() throws DBException {
        return xmlObjects.list();
     }
  
     /**
      * dropXMLObject physically removes the specified XMLObject and any
      * associated system resources that the XMLObject uses.
      *
      * @param xmlObject The XMLObject to drop
      * @return Whether or not the XMLObject was dropped
      */
     public final boolean dropXMLObject(XMLObject xmlObject) throws DBException {
        if ( xmlObject == null )
           throw new DBException(FaultCodes.OBJ_OBJECT_NOT_FOUND, "Object Value Null");
        
        boolean success = xmlObjects.drop(xmlObject.getName());
        getDatabase().flushConfig();
        return success;
     }
  
     /**
      * createXMLObject creates a new XMLObject object and any associated
      * system resources that the XMLObject will need.
      *
      * @param config The XMLObject's configuration
      * @return The newly created XMLObject
      */
     public final XMLObject createXMLObject(Configuration config) throws DBException {
        XMLObject obj = xmlObjects.create(config);
        getDatabase().flushConfig();
        return obj;
     }
  
     /**
      * 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");
        }
        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) {
        StringBuffer sb = new StringBuffer();
        sb.append(canonicalName);
        sb.append('/');
        sb.append(key.toString());
        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 {
        return true;
     }
  
     public boolean drop() throws DBException {
        if ( this == getDatabase() )
           throw new DBException(FaultCodes.DBE_CANNOT_DROP, "You Cannot Drop The Database");
  
        // Drop Child Collections
        String[] cols = listCollections();
        for ( int i = 0; i < cols.length; i++ )
           dropCollection(getCollection(cols[i]));
        
        // Drop XMLObjects
        String[] objs = listXMLObjects();
        for ( int i = 0; i < objs.length; i++ )
           dropXMLObject(getXMLObject(objs[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);
     }
     
     private void putDocument(Key key, Document document, boolean create) throws DBException {
        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));
        }
  
        Value value =  null;
        if ( compressed ) {
           try {
              byte[] b = DOMCompressor.Compress(document, symbols);
              value = new Value(b);
              
              document = new DocumentImpl(b, symbols, new NodeSource(this, key));
           }
           catch ( Exception e ) {
              throw new DBException(FaultCodes.COL_CANNOT_STORE, "Error storing Document '"+key+"'");
           }
        }
        else
           value = new Value(new Variant(document).toString());
  
        flushSymbolTable();
        
        // Temporary until insert and update are separate
        Document oldDoc = getDocument(key);
        if ( oldDoc != null )
           indexManager.removeDocument(key, oldDoc);
        indexManager.addDocument(key, document);
              
        filer.writeRecord(key, value);
              
        // Cache Stuff
        if ( documentCache != null ) {
           if ( compressed )
              documentCache.putDocument(this, key, value.getData());
           else
              documentCache.putDocument(this, key, document);
        }
     }
  
     /**
      * 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);
        return key;
     }
  
     /**
      * insertDocument inserts a new Document into a Xindice Collection.
      *
      * @param docKey The document Key
      * @param value The Document
      */
     public final void insertDocument(Object docKey, Document document) throws DBException {
        putDocument(createNewKey(docKey), document, true);
     }
  
     /**
      * 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);
     }
  
     /**
      * 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");
     }
  
     /**
      * getDocument retrieves a Document by Key.
      *
      * @param docKey The Document Key
      * @return The Document
      */
     public final Document getDocument(Object docKey) throws DBException {
        getDatabase().getSecurityManager().checkAccess(getCanonicalName() +
           "/", org.apache.xindice.core.security.Permission.READ);
        
        checkFiler(FaultCodes.COL_NO_FILER);
        
        Key key = createNewKey(docKey);
  
        Document doc = null;
        if ( documentCache != null )
           doc = documentCache.getDocument(this, key);
        
        if ( doc == null ) {
           Record record = filer.readRecord(key);
           if ( record == null )
              return null;
  
           Value value = record.getValue();
  
           if ( compressed ) {
              doc = new DocumentImpl(value.getData(), symbols, new NodeSource(this, key));
  
              if ( documentCache != null )
                 documentCache.putDocument(this, key, value.getData());
           }
           else
              doc = parseDocument(key, value.toString());
           
           flushSymbolTable();
        }
        return doc;
     }
  
     /**
      * 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 ) {
                 org.apache.xindice.Debug.printStackTrace(e);
              }
           }
        }
  
        return null;
     }
  
     private void putObject(Key key, XMLSerializable obj, boolean create) throws DBException {
        Document doc = new DocumentImpl();
        ProcessingInstruction pi = doc.createProcessingInstruction(CLASSNAME, obj.getClass().getName());
        doc.appendChild(pi);
        Element elem = obj.streamToXML(doc);
        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 {
        checkFiler(FaultCodes.QRY_STYLE_NOT_FOUND);
        return 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 {
        checkFiler(FaultCodes.COL_NO_FILER);
        
        return 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 {
        checkFiler(FaultCodes.COL_NO_FILER);
        
        RecordSet set = filer.getRecordSet();
        ArrayList temp = new ArrayList();
        
        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 {
        checkFiler(FaultCodes.COL_NO_FILER);
        
        return filer.getRecordCount();
     }
  
     public void dispose() {
        try {
           ((Collection)this).close();
        }
        catch ( Exception e ) {
           org.apache.xindice.Debug.printStackTrace(e);
        }
     }
  
     
     /**
      * 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 ) {
                    org.apache.xindice.Debug.printStackTrace(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);
        }
     }
  }
  
  
  
  1.1                  xml-xindice/Xindice/java/src/org/apache/xindice/core/CollectionManager.java
  
  Index: CollectionManager.java
  ===================================================================
  package org.apache.xindice.core;
  
  /*
   * The Apache Software License, Version 1.1
   *
   *
   * Copyright (c) 1999 The Apache Software Foundation.  All rights
   * reserved.
   *
   * Redistribution and use in source and binary forms, with or without
   * modification, are permitted provided that the following conditions
   * are met:
   *
   * 1. Redistributions of source code must retain the above copyright
   *    notice, this list of conditions and the following disclaimer.
   *
   * 2. Redistributions in binary form must reproduce the above copyright
   *    notice, this list of conditions and the following disclaimer in
   *    the documentation and/or other materials provided with the
   *    distribution.
   *
   * 3. The end-user documentation included with the redistribution,
   *    if any, must include the following acknowledgment:
   *       "This product includes software developed by the
   *        Apache Software Foundation (http://www.apache.org/)."
   *    Alternately, this acknowledgment may appear in the software itself,
   *    if and wherever such third-party acknowledgments normally appear.
   *
   * 4. The names "Xindice" and "Apache Software Foundation" must
   *    not be used to endorse or promote products derived from this
   *    software without prior written permission. For written
   *    permission, please contact apache@apache.org.
   *
   * 5. Products derived from this software may not be called "Apache",
   *    nor may "Apache" appear in their name, without prior written
   *    permission of the Apache Software Foundation.
   *
   * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
   * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
   * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
   * DISCLAIMED.  IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
   * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
   * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
   * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
   * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
   * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
   * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
   * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
   * SUCH DAMAGE.
   * ====================================================================
   *
   * This software consists of voluntary contributions made by many
   * individuals on behalf of the Apache Software Foundation and was
   * originally based on software copyright (c) 1999-2001, The dbXML
   * Group, L.L.C., http://www.dbxmlgroup.com.  For more
   * information on the Apache Software Foundation, please see
   * <http://www.apache.org/>.
   *
   * $Id: CollectionManager.java,v 1.1 2001/12/06 21:00:11 bradford Exp $
   */
  
  import org.apache.xindice.core.objects.*;
  import org.apache.xindice.core.Collection;
  import org.apache.xindice.util.*;
  
  import java.util.*;
  import org.w3c.dom.*;
  
  /**
   * CollectionManager is the base class for both Database and Collection.
   */
  
  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 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 {
                    Collection col = new Collection((Collection)CollectionManager.this);
                    col.setConfig(cfg);
                    collections.put(col.getName(), col);
                 }
           });
        }
     }
  
     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);
     }
  
     /**
      * 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 {
           String path = collection.getCanonicalName();
           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 ) {
                          org.apache.xindice.Debug.printStackTrace(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");
        }
  
        String url = "";
        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);
        }
        catch ( DBException d ) {
           throw d;
        }
        catch ( Exception e ) {
           throw new DBException(FaultCodes.COL_CANNOT_CREATE, "Error Creating Collection '"+path+"'");
        }
        return collection;
     }
     
     public void dispose() {
     }
  }
  
  
  
  1.1                  xml-xindice/Xindice/java/src/org/apache/xindice/core/Container.java
  
  Index: Container.java
  ===================================================================
  package org.apache.xindice.core;
  
  /*
   * The Apache Software License, Version 1.1
   *
   *
   * Copyright (c) 1999 The Apache Software Foundation.  All rights
   * reserved.
   *
   * Redistribution and use in source and binary forms, with or without
   * modification, are permitted provided that the following conditions
   * are met:
   *
   * 1. Redistributions of source code must retain the above copyright
   *    notice, this list of conditions and the following disclaimer.
   *
   * 2. Redistributions in binary form must reproduce the above copyright
   *    notice, this list of conditions and the following disclaimer in
   *    the documentation and/or other materials provided with the
   *    distribution.
   *
   * 3. The end-user documentation included with the redistribution,
   *    if any, must include the following acknowledgment:
   *       "This product includes software developed by the
   *        Apache Software Foundation (http://www.apache.org/)."
   *    Alternately, this acknowledgment may appear in the software itself,
   *    if and wherever such third-party acknowledgments normally appear.
   *
   * 4. The names "Xindice" and "Apache Software Foundation" must
   *    not be used to endorse or promote products derived from this
   *    software without prior written permission. For written
   *    permission, please contact apache@apache.org.
   *
   * 5. Products derived from this software may not be called "Apache",
   *    nor may "Apache" appear in their name, without prior written
   *    permission of the Apache Software Foundation.
   *
   * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
   * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
   * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
   * DISCLAIMED.  IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
   * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
   * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
   * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
   * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
   * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
   * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
   * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
   * SUCH DAMAGE.
   * ====================================================================
   *
   * This software consists of voluntary contributions made by many
   * individuals on behalf of the Apache Software Foundation and was
   * originally based on software copyright (c) 1999-2001, The dbXML
   * Group, L.L.C., http://www.dbxmlgroup.com.  For more
   * information on the Apache Software Foundation, please see
   * <http://www.apache.org/>.
   *
   * $Id: Container.java,v 1.1 2001/12/06 21:00:11 bradford Exp $
   */
  
  import org.w3c.dom.*;
  import org.apache.xindice.core.data.*;
  import org.apache.xindice.util.*;
  
  /**
   * Container is a generic container for Key and Document pairs.
   */
  
  public interface Container {
     /**
      * getCollection returns the Collection that the Document contained
      * belongs to.
      *
      * @return The owner Collection
      */
     Collection getCollection();
     
     /**
      * getKey returns the Document Key.
      *
      * @return The Document Key
      */
     Key getKey();
     
     /**
      * getCanonicalName returns the canonical name for the contained
      * Document.
      * <br>
      * ex: /local/test/ocs/ytd
      *
      * @return The canonical name
      */
     String getCanonicalName() throws DBException;
     
     /**
      * getDocument returns the contained Document.
      *
      * @return The Document
      */
     Document getDocument();
     
     /**
      * rollback reloads the Document from the Collection.
      *
      * @return The Document
      */
     Document rollback() throws DBException;
     
     /**
      * delete removes the Document from the Collection.
      */
     void remove() throws DBException;
     
     /**
      * commit saves the Document in the Collection.
      */
     void commit() throws DBException;
     
     /**
      * commit replaces the Document in the Collection with the
      * specified Document.
      *
      * @param document The Document
      */
     void commit(Document document) throws DBException;
  }
  
  
  
  
  1.1                  xml-xindice/Xindice/java/src/org/apache/xindice/core/DBException.java
  
  Index: DBException.java
  ===================================================================
  package org.apache.xindice.core;
  
  /*
   * The Apache Software License, Version 1.1
   *
   *
   * Copyright (c) 1999 The Apache Software Foundation.  All rights
   * reserved.
   *
   * Redistribution and use in source and binary forms, with or without
   * modification, are permitted provided that the following conditions
   * are met:
   *
   * 1. Redistributions of source code must retain the above copyright
   *    notice, this list of conditions and the following disclaimer.
   *
   * 2. Redistributions in binary form must reproduce the above copyright
   *    notice, this list of conditions and the following disclaimer in
   *    the documentation and/or other materials provided with the
   *    distribution.
   *
   * 3. The end-user documentation included with the redistribution,
   *    if any, must include the following acknowledgment:
   *       "This product includes software developed by the
   *        Apache Software Foundation (http://www.apache.org/)."
   *    Alternately, this acknowledgment may appear in the software itself,
   *    if and wherever such third-party acknowledgments normally appear.
   *
   * 4. The names "Xindice" and "Apache Software Foundation" must
   *    not be used to endorse or promote products derived from this
   *    software without prior written permission. For written
   *    permission, please contact apache@apache.org.
   *
   * 5. Products derived from this software may not be called "Apache",
   *    nor may "Apache" appear in their name, without prior written
   *    permission of the Apache Software Foundation.
   *
   * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
   * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
   * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
   * DISCLAIMED.  IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
   * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
   * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
   * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
   * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
   * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
   * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
   * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
   * SUCH DAMAGE.
   * ====================================================================
   *
   * This software consists of voluntary contributions made by many
   * individuals on behalf of the Apache Software Foundation and was
   * originally based on software copyright (c) 1999-2001, The dbXML
   * Group, L.L.C., http://www.dbxmlgroup.com.  For more
   * information on the Apache Software Foundation, please see
   * <http://www.apache.org/>.
   *
   * $Id: DBException.java,v 1.1 2001/12/06 21:00:11 bradford Exp $
   */
  
  import org.apache.xindice.util.*;
  
  /**
   * A DBException is thrown by the database if an exception occurs in the
   * managing (creating, dropping) database objects such as Collections,
   * Indexes, and XMLObjects.
   */
  
  public class DBException extends XindiceException {
     public int faultCode;
  
     public DBException() {
        this(FaultCodes.GEN_UNKNOWN,  "");
     }
  
     public DBException(int faultCode) {
        this(faultCode, "");
     }
  
     public DBException(int faultCode, String message) {
        super(message);
        this.faultCode = faultCode;
     }
  }
  
  
  
  1.1                  xml-xindice/Xindice/java/src/org/apache/xindice/core/DBObject.java
  
  Index: DBObject.java
  ===================================================================
  package org.apache.xindice.core;
  
  /*
   * The Apache Software License, Version 1.1
   *
   *
   * Copyright (c) 1999 The Apache Software Foundation.  All rights
   * reserved.
   *
   * Redistribution and use in source and binary forms, with or without
   * modification, are permitted provided that the following conditions
   * are met:
   *
   * 1. Redistributions of source code must retain the above copyright
   *    notice, this list of conditions and the following disclaimer.
   *
   * 2. Redistributions in binary form must reproduce the above copyright
   *    notice, this list of conditions and the following disclaimer in
   *    the documentation and/or other materials provided with the
   *    distribution.
   *
   * 3. The end-user documentation included with the redistribution,
   *    if any, must include the following acknowledgment:
   *       "This product includes software developed by the
   *        Apache Software Foundation (http://www.apache.org/)."
   *    Alternately, this acknowledgment may appear in the software itself,
   *    if and wherever such third-party acknowledgments normally appear.
   *
   * 4. The names "Xindice" and "Apache Software Foundation" must
   *    not be used to endorse or promote products derived from this
   *    software without prior written permission. For written
   *    permission, please contact apache@apache.org.
   *
   * 5. Products derived from this software may not be called "Apache",
   *    nor may "Apache" appear in their name, without prior written
   *    permission of the Apache Software Foundation.
   *
   * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
   * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
   * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
   * DISCLAIMED.  IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
   * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
   * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
   * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
   * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
   * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
   * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
   * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
   * SUCH DAMAGE.
   * ====================================================================
   *
   * This software consists of voluntary contributions made by many
   * individuals on behalf of the Apache Software Foundation and was
   * originally based on software copyright (c) 1999-2001, The dbXML
   * Group, L.L.C., http://www.dbxmlgroup.com.  For more
   * information on the Apache Software Foundation, please see
   * <http://www.apache.org/>.
   *
   * $Id: DBObject.java,v 1.1 2001/12/06 21:00:11 bradford Exp $
   */
  
  import org.apache.xindice.util.*;
  
  /**
   * DBObject is the interface implemented by all Xindice database objects.
   * DBObjects are typically objects that can be managed using XML
   * configuration information, which is typically stored in the system
   * database.  XMLObjects are not considered DBObjects because of the
   * steps involved in having to generate them, which is usually
   * compilation of source code.
   */
  
  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;
  }
  
  
  
  1.1                  xml-xindice/Xindice/java/src/org/apache/xindice/core/Database.java
  
  Index: Database.java
  ===================================================================
  package org.apache.xindice.core;
  
  /*
   * The Apache Software License, Version 1.1
   *
   *
   * Copyright (c) 1999 The Apache Software Foundation.  All rights
   * reserved.
   *
   * Redistribution and use in source and binary forms, with or without
   * modification, are permitted provided that the following conditions
   * are met:
   *
   * 1. Redistributions of source code must retain the above copyright
   *    notice, this list of conditions and the following disclaimer.
   *
   * 2. Redistributions in binary form must reproduce the above copyright
   *    notice, this list of conditions and the following disclaimer in
   *    the documentation and/or other materials provided with the
   *    distribution.
   *
   * 3. The end-user documentation included with the redistribution,
   *    if any, must include the following acknowledgment:
   *       "This product includes software developed by the
   *        Apache Software Foundation (http://www.apache.org/)."
   *    Alternately, this acknowledgment may appear in the software itself,
   *    if and wherever such third-party acknowledgments normally appear.
   *
   * 4. The names "Xindice" and "Apache Software Foundation" must
   *    not be used to endorse or promote products derived from this
   *    software without prior written permission. For written
   *    permission, please contact apache@apache.org.
   *
   * 5. Products derived from this software may not be called "Apache",
   *    nor may "Apache" appear in their name, without prior written
   *    permission of the Apache Software Foundation.
   *
   * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
   * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
   * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
   * DISCLAIMED.  IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
   * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
   * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
   * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
   * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
   * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
   * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
   * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
   * SUCH DAMAGE.
   * ====================================================================
   *
   * This software consists of voluntary contributions made by many
   * individuals on behalf of the Apache Software Foundation and was
   * originally based on software copyright (c) 1999-2001, The dbXML
   * Group, L.L.C., http://www.dbxmlgroup.com.  For more
   * information on the Apache Software Foundation, please see
   * <http://www.apache.org/>.
   *
   * $Id: Database.java,v 1.1 2001/12/06 21:00:11 bradford Exp $
   */
  
  import org.apache.xindice.core.query.*;
  import org.apache.xindice.core.security.*;
  import org.apache.xindice.core.objects.*;
  import org.apache.xindice.core.request.*;
  import org.apache.xindice.util.*;
  
  import org.w3c.dom.*;
  
  import java.io.*;
  import java.util.*;
  import javax.xml.parsers.*;
  
  /**
   * Database is the primary container for the Xindice Database Engine.
   */
  
  public final class Database extends Collection implements Named {
     private static final String DBROOT = "dbroot";
     private static final String SECURITY = "security";
     private static final String PACKAGE = "package";
     private static final String QUERYENGINE = "queryengine";
     private static final String DATABASE = "database";
     private static final String COLKEY = "database.xml";
     private static final String NAME = "name";
  
     private static final Map databases = new HashMap(); // String to Database
  
     private DocumentCache docCache = new DocumentCache();
     private DBSecurityManager securityManager = null;
     
     private ObjectPool uriPool = new ObjectPool() {
        public Poolable createObject() {
           return new URIMapper();
        }
     };
  
     private SystemCollection sysCol = null;
  
     private boolean sysInit = false;
  
     private QueryEngine engine = new QueryEngine(this);
  
     public Database() {
     }
  
     public static Database getDatabase(String name) {
        return (Database)databases.get(name);
     }
  
     public static String[] listDatabases() {
        return (String[]) databases.keySet().toArray(new String[0]);
     }
  
     public void setConfig(Configuration config) {
        this.config = config;
  
        name = config.getAttribute(NAME);
        setCanonicalName('/' + getName());
        setCollectionRoot(new File(config.getAttribute(DBROOT)));
  
        // Create the security manager so that it exists for loading the system
        // collections.
        // TODO: Finish security manager implementation
        if (securityManager == null) {
           boolean disableSecurity = false;
           if (config.getAttribute(SECURITY).equals("false")) {
              disableSecurity = true;
           }
  
           securityManager = new LocalSecurityManager(this, disableSecurity);
        }
  
        try {
           Configuration queryCfg = config.getChild(QUERYENGINE);
           if ( queryCfg != null )
              engine.setConfig(queryCfg);
        }
        catch ( Exception e ) {
           org.apache.xindice.Debug.printStackTrace(e);
        }
  
        if ( !sysInit ) {
           sysCol = new SystemCollection(this);
  
           try {
              sysCol.init();
           }
           catch ( XindiceException e ) {
              org.apache.xindice.Debug.printStackTrace(e);
           }
  
           collections.put(sysCol.getName(), sysCol);
           sysInit = true;
        }
  
        // System collections are loaded so we need to load the security config
        // and setup the system for secure operation.
        // TODO: Finish security manager implementation
        /*if (securityManager != null) {
           securityManager.readConfig();
           // Default admin level for the primary thread for testing.
           try {
              securityManager.authenticate("scott", "tiger");
           }
           catch (Exception e) {
              org.apache.xindice.Debug.printStackTrace(e);
           }
           securityManager.setActive();
        }*/
  
        
        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 = sysCol.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);
              sysCol.getCollection(SystemCollection.CONFIGS).setDocument(COLKEY, colDoc);
           }
           
           super.setConfig(new Configuration(colDoc.getDocumentElement(), false));
        }
        catch ( Exception e ) {
           org.apache.xindice.Debug.printStackTrace(e);
        }
  
        // Register the Database with the VM
        databases.put(getName(), this);
     }
  
     public SystemCollection getSystemCollection() {
        return sysCol;
     }
  
     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();
           sysCol.getCollection(SystemCollection.CONFIGS).setDocument(COLKEY, d);
        }
        catch ( Exception e ) {
           org.apache.xindice.Debug.println(this, "Error Writing Configuration '"+name+"'");
        }
     }
    
     public boolean close() throws DBException {
        flushConfig();
        return true;
     }
        
     /**
      * getURIMapper returns a pooled URIMapper instance.
      *
      * @return A Pooled URIMapper
      */
     public URIMapper getURIMapper() {
        return (URIMapper)uriPool.getObject();
     }
  
     /**
      * getURIMapper returns a pooled URIMapper instance.
      *
      * @param uri The URI to resolve
      * @return A Pooled (and resolved) URIMapper
      */
     public URIMapper getURIMapper(String uri) throws DBException {
        try {
           URIMapper map = (URIMapper)uriPool.getObject();
           map.setURI(uri);
           return map;
        }
        catch ( Exception e ) {
           throw new DBException(FaultCodes.URI_PARSE_ERROR, "Couldn't Parse URL: '"+uri+"'");
        }
     }
  
     /**
      * 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;
     }
  
     /**
      * Returns the security manager instance for this Database.
      *
      * @return The security manager
      */
     public DBSecurityManager getSecurityManager() {
        return securityManager;
     }
  }
  
  
  
  
  1.1                  xml-xindice/Xindice/java/src/org/apache/xindice/core/DocumentCache.java
  
  Index: DocumentCache.java
  ===================================================================
  package org.apache.xindice.core;
  
  /*
   * The Apache Software License, Version 1.1
   *
   *
   * Copyright (c) 1999 The Apache Software Foundation.  All rights
   * reserved.
   *
   * Redistribution and use in source and binary forms, with or without
   * modification, are permitted provided that the following conditions
   * are met:
   *
   * 1. Redistributions of source code must retain the above copyright
   *    notice, this list of conditions and the following disclaimer.
   *
   * 2. Redistributions in binary form must reproduce the above copyright
   *    notice, this list of conditions and the following disclaimer in
   *    the documentation and/or other materials provided with the
   *    distribution.
   *
   * 3. The end-user documentation included with the redistribution,
   *    if any, must include the following acknowledgment:
   *       "This product includes software developed by the
   *        Apache Software Foundation (http://www.apache.org/)."
   *    Alternately, this acknowledgment may appear in the software itself,
   *    if and wherever such third-party acknowledgments normally appear.
   *
   * 4. The names "Xindice" and "Apache Software Foundation" must
   *    not be used to endorse or promote products derived from this
   *    software without prior written permission. For written
   *    permission, please contact apache@apache.org.
   *
   * 5. Products derived from this software may not be called "Apache",
   *    nor may "Apache" appear in their name, without prior written
   *    permission of the Apache Software Foundation.
   *
   * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
   * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
   * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
   * DISCLAIMED.  IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
   * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
   * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
   * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
   * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
   * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
   * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
   * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
   * SUCH DAMAGE.
   * ====================================================================
   *
   * This software consists of voluntary contributions made by many
   * individuals on behalf of the Apache Software Foundation and was
   * originally based on software copyright (c) 1999-2001, The dbXML
   * Group, L.L.C., http://www.dbxmlgroup.com.  For more
   * information on the Apache Software Foundation, please see
   * <http://www.apache.org/>.
   *
   * $Id: DocumentCache.java,v 1.1 2001/12/06 21:00:11 bradford Exp $
   */
   
  import java.util.*;
  
  import org.apache.xindice.util.*;
  import org.apache.xindice.core.data.*;
  import org.apache.xindice.xml.*;
  import org.apache.xindice.xml.dom.*;
  import org.w3c.dom.*;
  
  /**
   * DocumentCache implements a simple Document caching system for
   * Collections.
   */
  
  public final class DocumentCache {
     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) {
           CacheKey comp = (CacheKey)o;
           if ( col != comp.col )
              return false;
           return key.equals(comp.key );
        }
     }
  }
  
  
  
  
  1.1                  xml-xindice/Xindice/java/src/org/apache/xindice/core/FaultCodes.java
  
  Index: FaultCodes.java
  ===================================================================
  package org.apache.xindice.core;
  
  /*
   * The Apache Software License, Version 1.1
   *
   *
   * Copyright (c) 1999 The Apache Software Foundation.  All rights
   * reserved.
   *
   * Redistribution and use in source and binary forms, with or without
   * modification, are permitted provided that the following conditions
   * are met:
   *
   * 1. Redistributions of source code must retain the above copyright
   *    notice, this list of conditions and the following disclaimer.
   *
   * 2. Redistributions in binary form must reproduce the above copyright
   *    notice, this list of conditions and the following disclaimer in
   *    the documentation and/or other materials provided with the
   *    distribution.
   *
   * 3. The end-user documentation included with the redistribution,
   *    if any, must include the following acknowledgment:
   *       "This product includes software developed by the
   *        Apache Software Foundation (http://www.apache.org/)."
   *    Alternately, this acknowledgment may appear in the software itself,
   *    if and wherever such third-party acknowledgments normally appear.
   *
   * 4. The names "Xindice" and "Apache Software Foundation" must
   *    not be used to endorse or promote products derived from this
   *    software without prior written permission. For written
   *    permission, please contact apache@apache.org.
   *
   * 5. Products derived from this software may not be called "Apache",
   *    nor may "Apache" appear in their name, without prior written
   *    permission of the Apache Software Foundation.
   *
   * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
   * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
   * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
   * DISCLAIMED.  IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
   * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
   * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
   * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
   * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
   * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
   * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
   * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
   * SUCH DAMAGE.
   * ====================================================================
   *
   * This software consists of voluntary contributions made by many
   * individuals on behalf of the Apache Software Foundation and was
   * originally based on software copyright (c) 1999-2001, The dbXML
   * Group, L.L.C., http://www.dbxmlgroup.com.  For more
   * information on the Apache Software Foundation, please see
   * <http://www.apache.org/>.
   *
   * $Id: FaultCodes.java,v 1.1 2001/12/06 21:00:11 bradford Exp $
   */
  
  import java.util.*;
  import org.apache.xindice.client.corba.db.*;
  import org.apache.xindice.util.*;
  
  import org.xmldb.api.base.*;
  
  /**
   * FaultCodes defines the Xindice specific fault codes and associated error
   * messages.
   */
  
  public abstract class FaultCodes implements org.apache.xindice.client.corba.db.FaultCodes {
     private static final Map FaultMsg = new HashMap();
  
     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");
  
        // XMLObject invocation errors 100 series
        putCodeMessage(OBJ_OBJECT_NOT_FOUND, "XMLObject Not Found");
        putCodeMessage(OBJ_METHOD_NOT_FOUND, "XMLObject Method Not Found");
        putCodeMessage(OBJ_NULL_RESULT, "XMLObject Null Result");
        putCodeMessage(OBJ_INVALID_RESULT, "XMLObject Invalid Result");
        putCodeMessage(OBJ_DUPLICATE_OBJECT, "XMLObject Duplicate Object");
        putCodeMessage(OBJ_RUNTIME_EXCEPTION, "XMLObject Runtime Exception");
        putCodeMessage(OBJ_CLASS_FORMAT_ERROR, "XMLObject Class Format Error");
        putCodeMessage(OBJ_INVALID_CONTEXT, "XMLObject Invalid Context");
        putCodeMessage(OBJ_CANNOT_CREATE, "XMLObject Cannot Create");
        
        // 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");
  
        // 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) {
        FaultMsg.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)FaultMsg.get(new Integer(code));
        return msg != null ? msg
                           : "";
     }
  
     /**
      * createAPIException creates an APIException instance based
      * on the specified parameters.
      *
      * @param code The Fault Code
      * @return An APIException instance
      */
     public static APIException createAPIException(int code) {
        return new APIException(code, getMessage(code), "");
     }
  
     /**
      * createAPIException creates an APIException instance based
      * on the specified parameters.
      *
      * @param code The Fault Code
      * @param message A specific message to associate
      * @return An APIException instance
      */
     public static APIException createAPIException(int code, String message) {
        return new APIException(code, getMessage(code), message);
     }
  
     /**
      * createAPIException creates an APIException 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 APIException instance
      */
     public static APIException createAPIException(Exception e) {
        if ( e instanceof APIException )
           return (APIException)e;
        else {
           String m = e.getMessage();
           if ( m == null )
              m = "";
  
           if ( e instanceof RuntimeException )
              return new APIException(JAVA_RUNTIME_ERROR, getMessage(JAVA_RUNTIME_ERROR), m);
           else if ( e instanceof DBException ) {
              DBException d = (DBException)e;
              return new APIException(d.faultCode, getMessage(d.faultCode), m);
           }
           else
              return new APIException(GEN_UNKNOWN, getMessage(GEN_UNKNOWN), m);
        }
     }
  
     /**
      * 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;
        else if ( e instanceof DBException ) {
           DBException d = (DBException)e;
           return new XMLDBException(ErrorCodes.VENDOR_ERROR, d.faultCode, getMessage(d.faultCode));
        }
        else if ( e instanceof APIException ) {
           APIException a = (APIException)e;
           return new XMLDBException(ErrorCodes.VENDOR_ERROR, a.faultCode, a.faultMessage);
        }
        else {
           String m = e.getMessage();
           if ( m == null )
              m = "";
           int code = e instanceof RuntimeException ? JAVA_RUNTIME_ERROR
                                                    : GEN_UNKNOWN;
           return new XMLDBException(ErrorCodes.VENDOR_ERROR, code, m);
        }
     }
  
     /**
      * 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;
        else if ( e instanceof APIException )
           code = ((APIException)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;
        else if ( e instanceof APIException )
           code = ((APIException)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 if ( e instanceof APIException )
           return ((APIException)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.1                  xml-xindice/Xindice/java/src/org/apache/xindice/core/SystemCollection.java
  
  Index: SystemCollection.java
  ===================================================================
  package org.apache.xindice.core;
  
  /*
   * The Apache Software License, Version 1.1
   *
   *
   * Copyright (c) 1999 The Apache Software Foundation.  All rights
   * reserved.
   *
   * Redistribution and use in source and binary forms, with or without
   * modification, are permitted provided that the following conditions
   * are met:
   *
   * 1. Redistributions of source code must retain the above copyright
   *    notice, this list of conditions and the following disclaimer.
   *
   * 2. Redistributions in binary form must reproduce the above copyright
   *    notice, this list of conditions and the following disclaimer in
   *    the documentation and/or other materials provided with the
   *    distribution.
   *
   * 3. The end-user documentation included with the redistribution,
   *    if any, must include the following acknowledgment:
   *       "This product includes software developed by the
   *        Apache Software Foundation (http://www.apache.org/)."
   *    Alternately, this acknowledgment may appear in the software itself,
   *    if and wherever such third-party acknowledgments normally appear.
   *
   * 4. The names "Xindice" and "Apache Software Foundation" must
   *    not be used to endorse or promote products derived from this
   *    software without prior written permission. For written
   *    permission, please contact apache@apache.org.
   *
   * 5. Products derived from this software may not be called "Apache",
   *    nor may "Apache" appear in their name, without prior written
   *    permission of the Apache Software Foundation.
   *
   * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
   * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
   * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
   * DISCLAIMED.  IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
   * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
   * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
   * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
   * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
   * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
   * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
   * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
   * SUCH DAMAGE.
   * ====================================================================
   *
   * This software consists of voluntary contributions made by many
   * individuals on behalf of the Apache Software Foundation and was
   * originally based on software copyright (c) 1999-2001, The dbXML
   * Group, L.L.C., http://www.dbxmlgroup.com.  For more
   * information on the Apache Software Foundation, please see
   * <http://www.apache.org/>.
   *
   * $Id: SystemCollection.java,v 1.1 2001/12/06 21:00:11 bradford Exp $
   */
  
  import org.apache.xindice.core.*;
  import org.apache.xindice.core.Collection;
  import org.apache.xindice.server.*;
  import org.apache.xindice.core.objects.*;
  import org.apache.xindice.xml.*;
  import org.apache.xindice.xml.dom.*;
  import org.apache.xindice.tools.*;
  import org.apache.xindice.util.*;
  
  import org.w3c.dom.*;
  
  import java.io.*;
  import java.util.*;
  
  /**
   * SystemCollection represents the System Collection.  Beyond
   * standard Collection operations, this class will provide facilities
   * for Schema and SymbolTable management among other things.
   */
  
  public final class SystemCollection extends Collection {
     public static final String CLASSGEN = "classgen";
  
     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 String classGen = "./classgen";
  
     public SystemCollection(Database db) {
        super(db);
     }
  
     void init() throws DBException {
        // Bootstrap the System Collection
        File f = new File(getDatabase().getCollectionRoot(), SYSCOL);
        File cfgDir = new File(System.getProperty(Xindice.PROP_XINDICE_HOME), "/config");
        
        classGen = getDatabase().getConfig().getAttribute(CLASSGEN, classGen);
  
        if ( !f.exists() )
           f.mkdirs();
  
        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>"
           
           // XML Object Configuration Collection
         + "      <collection name=\""+OBJECTS+"\" compressed=\"true\">"
         + "         <filer class=\"org.apache.xindice.core.filer.BTreeFiler\" />"
         + "      </collection>"
  
           // System Configuration Collection
         + "      <collection name=\""+CONFIGS+"\" compressed=\"false\" cache=\"false\" >"
         + "         <filer class=\"org.apache.xindice.core.filer.BTreeFiler\" />"
         + "      </collection>"
           
           // User Information Collection
         + "      <collection name=\""+USERS+"\" compressed=\"true\">"
         + "         <filer class=\"org.apache.xindice.core.filer.BTreeFiler\" />"
         + "      </collection>"
           
           // Group Information Collection
         + "      <collection name=\""+GROUPS+"\" compressed=\"true\">"
         + "         <filer class=\"org.apache.xindice.core.filer.BTreeFiler\" />"
         + "      </collection>"
           
           // Access Control Collection
         + "      <collection name=\""+ACCESS+"\" compressed=\"true\">"
         + "         <filer class=\"org.apache.xindice.core.filer.BTreeFiler\" />"
         + "      </collection>"
           
         + "   </collections>"
           
           // System-level XMLObjects
         + "   <xmlobjects>"
         + "      <xmlobject class=\"org.apache.xindice.core.system.Sequencer\" name=\"sequencer\" />"
         + "   </xmlobjects>"
         + "</collection>";
  
        try {
           Document sysDoc = DOMParser.toDocument(SysCol);
           Configuration sysCfg = new Configuration(sysDoc.getDocumentElement(), false);
           setConfig(sysCfg);
        }
        catch ( Exception e ) {
           org.apache.xindice.Debug.println("\u0007FATAL ERROR: Generating System Collection '"+SYSCOL+"'");
           org.apache.xindice.Debug.printStackTrace(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.1                  xml-xindice/Xindice/java/src/org/apache/xindice/core/package.html
  
  Index: package.html
  ===================================================================
  <html>
    <title>The Xindice Core.</title>
    <body>
      <p>This is the top-level package for all Xindice Core functionality.</p>
   </body>
  </html>
  
  
  
  
  
  1.1                  xml-xindice/Xindice/java/src/org/apache/xindice/core/data/DocumentSet.java
  
  Index: DocumentSet.java
  ===================================================================
  package org.apache.xindice.core.data;
  
  /*
   * The Apache Software License, Version 1.1
   *
   *
   * Copyright (c) 1999 The Apache Software Foundation.  All rights
   * reserved.
   *
   * Redistribution and use in source and binary forms, with or without
   * modification, are permitted provided that the following conditions
   * are met:
   *
   * 1. Redistributions of source code must retain the above copyright
   *    notice, this list of conditions and the following disclaimer.
   *
   * 2. Redistributions in binary form must reproduce the above copyright
   *    notice, this list of conditions and the following disclaimer in
   *    the documentation and/or other materials provided with the
   *    distribution.
   *
   * 3. The end-user documentation included with the redistribution,
   *    if any, must include the following acknowledgment:
   *       "This product includes software developed by the
   *        Apache Software Foundation (http://www.apache.org/)."
   *    Alternately, this acknowledgment may appear in the software itself,
   *    if and wherever such third-party acknowledgments normally appear.
   *
   * 4. The names "Xindice" and "Apache Software Foundation" must
   *    not be used to endorse or promote products derived from this
   *    software without prior written permission. For written
   *    permission, please contact apache@apache.org.
   *
   * 5. Products derived from this software may not be called "Apache",
   *    nor may "Apache" appear in their name, without prior written
   *    permission of the Apache Software Foundation.
   *
   * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
   * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
   * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
   * DISCLAIMED.  IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
   * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
   * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
   * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
   * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
   * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
   * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
   * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
   * SUCH DAMAGE.
   * ====================================================================
   *
   * This software consists of voluntary contributions made by many
   * individuals on behalf of the Apache Software Foundation and was
   * originally based on software copyright (c) 1999-2001, The dbXML
   * Group, L.L.C., http://www.dbxmlgroup.com.  For more
   * information on the Apache Software Foundation, please see
   * <http://www.apache.org/>.
   *
   * $Id: DocumentSet.java,v 1.1 2001/12/06 21:00:11 bradford Exp $
   */
  
  import org.apache.xindice.core.*;
  import org.w3c.dom.*;
  
  /**
   * DocumentSet is an interface for iterating over a set of Documents.
   */
  
  public interface DocumentSet {
     /**
      * hasMoreDocuments returns whether there are any more Documents
      * left in the set.
      *
      * @return Whether there are more Documents
      */
     boolean hasMoreDocuments() throws DBException;
     
     /**
      * getNextDocument returns the next Document in the set.
      *
      * @return The next Document
      */
     Document getNextDocument() throws DBException;
     
     /**
      * getNextContainer returns the next Document in the set wrapped
      * in a Collection Container.  Containers store extra information
      * about the Document (like its Key)
      *
      * @return The next Container
      */
     Container getNextContainer() throws DBException;
  }
  
  
  
  1.1                  xml-xindice/Xindice/java/src/org/apache/xindice/core/data/EmptyDocumentSet.java
  
  Index: EmptyDocumentSet.java
  ===================================================================
  package org.apache.xindice.core.data;
  
  /*
   * The Apache Software License, Version 1.1
   *
   *
   * Copyright (c) 1999 The Apache Software Foundation.  All rights
   * reserved.
   *
   * Redistribution and use in source and binary forms, with or without
   * modification, are permitted provided that the following conditions
   * are met:
   *
   * 1. Redistributions of source code must retain the above copyright
   *    notice, this list of conditions and the following disclaimer.
   *
   * 2. Redistributions in binary form must reproduce the above copyright
   *    notice, this list of conditions and the following disclaimer in
   *    the documentation and/or other materials provided with the
   *    distribution.
   *
   * 3. The end-user documentation included with the redistribution,
   *    if any, must include the following acknowledgment:
   *       "This product includes software developed by the
   *        Apache Software Foundation (http://www.apache.org/)."
   *    Alternately, this acknowledgment may appear in the software itself,
   *    if and wherever such third-party acknowledgments normally appear.
   *
   * 4. The names "Xindice" and "Apache Software Foundation" must
   *    not be used to endorse or promote products derived from this
   *    software without prior written permission. For written
   *    permission, please contact apache@apache.org.
   *
   * 5. Products derived from this software may not be called "Apache",
   *    nor may "Apache" appear in their name, without prior written
   *    permission of the Apache Software Foundation.
   *
   * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
   * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
   * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
   * DISCLAIMED.  IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
   * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
   * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
   * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
   * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
   * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
   * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
   * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
   * SUCH DAMAGE.
   * ====================================================================
   *
   * This software consists of voluntary contributions made by many
   * individuals on behalf of the Apache Software Foundation and was
   * originally based on software copyright (c) 1999-2001, The dbXML
   * Group, L.L.C., http://www.dbxmlgroup.com.  For more
   * information on the Apache Software Foundation, please see
   * <http://www.apache.org/>.
   *
   * $Id: EmptyDocumentSet.java,v 1.1 2001/12/06 21:00:11 bradford Exp $
   */
  
  import org.apache.xindice.core.*;
  import org.w3c.dom.*;
  
  /**
   * EmptyDocumentSet implements an empty DocumentSet.
   */
  
  public final class EmptyDocumentSet implements DocumentSet {
     public boolean hasMoreDocuments() {
        return false;
     }
     
     public Document getNextDocument() {
        return null;
     }
     
     public Container getNextContainer() {
        return null;
     }
  }
  
  
  
  1.1                  xml-xindice/Xindice/java/src/org/apache/xindice/core/data/EmptyNodeSet.java
  
  Index: EmptyNodeSet.java
  ===================================================================
  package org.apache.xindice.core.data;
  
  /*
   * The Apache Software License, Version 1.1
   *
   *
   * Copyright (c) 1999 The Apache Software Foundation.  All rights
   * reserved.
   *
   * Redistribution and use in source and binary forms, with or without
   * modification, are permitted provided that the following conditions
   * are met:
   *
   * 1. Redistributions of source code must retain the above copyright
   *    notice, this list of conditions and the following disclaimer.
   *
   * 2. Redistributions in binary form must reproduce the above copyright
   *    notice, this list of conditions and the following disclaimer in
   *    the documentation and/or other materials provided with the
   *    distribution.
   *
   * 3. The end-user documentation included with the redistribution,
   *    if any, must include the following acknowledgment:
   *       "This product includes software developed by the
   *        Apache Software Foundation (http://www.apache.org/)."
   *    Alternately, this acknowledgment may appear in the software itself,
   *    if and wherever such third-party acknowledgments normally appear.
   *
   * 4. The names "Xindice" and "Apache Software Foundation" must
   *    not be used to endorse or promote products derived from this
   *    software without prior written permission. For written
   *    permission, please contact apache@apache.org.
   *
   * 5. Products derived from this software may not be called "Apache",
   *    nor may "Apache" appear in their name, without prior written
   *    permission of the Apache Software Foundation.
   *
   * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
   * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
   * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
   * DISCLAIMED.  IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
   * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
   * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
   * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
   * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
   * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
   * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
   * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
   * SUCH DAMAGE.
   * ====================================================================
   *
   * This software consists of voluntary contributions made by many
   * individuals on behalf of the Apache Software Foundation and was
   * originally based on software copyright (c) 1999-2001, The dbXML
   * Group, L.L.C., http://www.dbxmlgroup.com.  For more
   * information on the Apache Software Foundation, please see
   * <http://www.apache.org/>.
   *
   * $Id: EmptyNodeSet.java,v 1.1 2001/12/06 21:00:11 bradford Exp $
   */
  
  import org.w3c.dom.*;
  
  /**
   * EmptyNodeSet implements an empty NodeSet.
   */
  
  public final class EmptyNodeSet implements NodeSet {
     public boolean hasMoreNodes() {
        return false;
     }
     
     public Node getNextNode() {
        return null;
     }
  }
  
  
  
  1.1                  xml-xindice/Xindice/java/src/org/apache/xindice/core/data/EmptyRecordSet.java
  
  Index: EmptyRecordSet.java
  ===================================================================
  package org.apache.xindice.core.data;
  
  /*
   * The Apache Software License, Version 1.1
   *
   *
   * Copyright (c) 1999 The Apache Software Foundation.  All rights
   * reserved.
   *
   * Redistribution and use in source and binary forms, with or without
   * modification, are permitted provided that the following conditions
   * are met:
   *
   * 1. Redistributions of source code must retain the above copyright
   *    notice, this list of conditions and the following disclaimer.
   *
   * 2. Redistributions in binary form must reproduce the above copyright
   *    notice, this list of conditions and the following disclaimer in
   *    the documentation and/or other materials provided with the
   *    distribution.
   *
   * 3. The end-user documentation included with the redistribution,
   *    if any, must include the following acknowledgment:
   *       "This product includes software developed by the
   *        Apache Software Foundation (http://www.apache.org/)."
   *    Alternately, this acknowledgment may appear in the software itself,
   *    if and wherever such third-party acknowledgments normally appear.
   *
   * 4. The names "Xindice" and "Apache Software Foundation" must
   *    not be used to endorse or promote products derived from this
   *    software without prior written permission. For written
   *    permission, please contact apache@apache.org.
   *
   * 5. Products derived from this software may not be called "Apache",
   *    nor may "Apache" appear in their name, without prior written
   *    permission of the Apache Software Foundation.
   *
   * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
   * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
   * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
   * DISCLAIMED.  IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
   * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
   * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
   * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
   * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
   * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
   * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
   * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
   * SUCH DAMAGE.
   * ====================================================================
   *
   * This software consists of voluntary contributions made by many
   * individuals on behalf of the Apache Software Foundation and was
   * originally based on software copyright (c) 1999-2001, The dbXML
   * Group, L.L.C., http://www.dbxmlgroup.com.  For more
   * information on the Apache Software Foundation, please see
   * <http://www.apache.org/>.
   *
   * $Id: EmptyRecordSet.java,v 1.1 2001/12/06 21:00:11 bradford Exp $
   */
  
  import org.apache.xindice.core.*;
  
  /**
   * EmptyRecordSet implements an empty RecordSet.
   */
  
  public final class EmptyRecordSet implements RecordSet {
     public boolean hasMoreRecords() {
        return false;
     }
     
     public Record getNextRecord() {
        return null;
     }
     
     public Key getNextKey() {
        return null;
     }
  
     public Value getNextValue() {
        return null;
     }
  }
  
  
  
  1.1                  xml-xindice/Xindice/java/src/org/apache/xindice/core/data/Key.java
  
  Index: Key.java
  ===================================================================
  package org.apache.xindice.core.data;
  
  /*
   * The Apache Software License, Version 1.1
   *
   *
   * Copyright (c) 1999 The Apache Software Foundation.  All rights
   * reserved.
   *
   * Redistribution and use in source and binary forms, with or without
   * modification, are permitted provided that the following conditions
   * are met:
   *
   * 1. Redistributions of source code must retain the above copyright
   *    notice, this list of conditions and the following disclaimer.
   *
   * 2. Redistributions in binary form must reproduce the above copyright
   *    notice, this list of conditions and the following disclaimer in
   *    the documentation and/or other materials provided with the
   *    distribution.
   *
   * 3. The end-user documentation included with the redistribution,
   *    if any, must include the following acknowledgment:
   *       "This product includes software developed by the
   *        Apache Software Foundation (http://www.apache.org/)."
   *    Alternately, this acknowledgment may appear in the software itself,
   *    if and wherever such third-party acknowledgments normally appear.
   *
   * 4. The names "Xindice" and "Apache Software Foundation" must
   *    not be used to endorse or promote products derived from this
   *    software without prior written permission. For written
   *    permission, please contact apache@apache.org.
   *
   * 5. Products derived from this software may not be called "Apache",
   *    nor may "Apache" appear in their name, without prior written
   *    permission of the Apache Software Foundation.
   *
   * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
   * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
   * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
   * DISCLAIMED.  IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
   * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
   * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
   * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
   * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
   * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
   * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
   * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
   * SUCH DAMAGE.
   * ====================================================================
   *
   * This software consists of voluntary contributions made by many
   * individuals on behalf of the Apache Software Foundation and was
   * originally based on software copyright (c) 1999-2001, The dbXML
   * Group, L.L.C., http://www.dbxmlgroup.com.  For more
   * information on the Apache Software Foundation, please see
   * <http://www.apache.org/>.
   *
   * $Id: Key.java,v 1.1 2001/12/06 21:00:11 bradford Exp $
   */
  
  import java.io.*;
  
  /**
   * Key extends Value by providing a hash value for the Key.
   */
  
  public final class Key extends Value {
     private int hash = 0;
  
     public Key(Value value) {
        super(value);
     }
  
     public Key(byte[] data) {
        super(data);
     }
  
     public Key(byte[] data, int pos, int len) {
        super(data, pos, len);
     }
  
     public Key(String data) {
        super(data);
     }
  
     // TODO: This has to be revisited
     private void calculateHash() {
        hash = 0;
        int pl = pos+len;
        for ( int i = pos; i < pl; i++ ) {
           hash = (hash << 5) ^ data[i];
           hash = hash % 1234567891;
        }
        hash = Math.abs(hash);
     }
  
     public int getHash() {
        if ( hash == 0 )
           calculateHash();
        return hash;
     }
  
     public boolean equals(Value value) {
        if ( value instanceof Key ) {
           Key key = (Key)value;
           return getHash() == key.getHash() ? compareTo(key) == 0
                                             : false;
        }
        else
           return super.equals(value);
     }
  
     public int hashCode() {
        return getHash();
     }
  
     public boolean equals(Object obj) {
        if ( obj instanceof Key )
           return equals((Key)obj);
        else
           return super.equals(obj);
     }
  }
  
  
  
  
  1.1                  xml-xindice/Xindice/java/src/org/apache/xindice/core/data/NodeSet.java
  
  Index: NodeSet.java
  ===================================================================
  package org.apache.xindice.core.data;
  
  /*
   * The Apache Software License, Version 1.1
   *
   *
   * Copyright (c) 1999 The Apache Software Foundation.  All rights
   * reserved.
   *
   * Redistribution and use in source and binary forms, with or without
   * modification, are permitted provided that the following conditions
   * are met:
   *
   * 1. Redistributions of source code must retain the above copyright
   *    notice, this list of conditions and the following disclaimer.
   *
   * 2. Redistributions in binary form must reproduce the above copyright
   *    notice, this list of conditions and the following disclaimer in
   *    the documentation and/or other materials provided with the
   *    distribution.
   *
   * 3. The end-user documentation included with the redistribution,
   *    if any, must include the following acknowledgment:
   *       "This product includes software developed by the
   *        Apache Software Foundation (http://www.apache.org/)."
   *    Alternately, this acknowledgment may appear in the software itself,
   *    if and wherever such third-party acknowledgments normally appear.
   *
   * 4. The names "Xindice" and "Apache Software Foundation" must
   *    not be used to endorse or promote products derived from this
   *    software without prior written permission. For written
   *    permission, please contact apache@apache.org.
   *
   * 5. Products derived from this software may not be called "Apache",
   *    nor may "Apache" appear in their name, without prior written
   *    permission of the Apache Software Foundation.
   *
   * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
   * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
   * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
   * DISCLAIMED.  IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
   * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
   * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
   * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
   * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
   * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
   * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
   * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
   * SUCH DAMAGE.
   * ====================================================================
   *
   * This software consists of voluntary contributions made by many
   * individuals on behalf of the Apache Software Foundation and was
   * originally based on software copyright (c) 1999-2001, The dbXML
   * Group, L.L.C., http://www.dbxmlgroup.com.  For more
   * information on the Apache Software Foundation, please see
   * <http://www.apache.org/>.
   *
   * $Id: NodeSet.java,v 1.1 2001/12/06 21:00:11 bradford Exp $
   */
  
  import org.w3c.dom.*;
  
  /**
   * NodeSet is an interface for iterating over a set of Nodes.  NodeSets
   * are generally returned by the QueryEngine.
   */
  
  public interface NodeSet {
     /**
      * hasMoreNodes returns whether or not there are any Nodes remaining
      * in the NodeSet.
      *
      * @return Whether there are any more Nodes
      */
     boolean hasMoreNodes();
     
     /**
      * getNextNode returns the next Node from the NodeSet.
      *
      * @return The next Node
      */
     Node getNextNode();
  }
  
  
  
  1.1                  xml-xindice/Xindice/java/src/org/apache/xindice/core/data/Record.java
  
  Index: Record.java
  ===================================================================
  package org.apache.xindice.core.data;
  
  /*
   * The Apache Software License, Version 1.1
   *
   *
   * Copyright (c) 1999 The Apache Software Foundation.  All rights
   * reserved.
   *
   * Redistribution and use in source and binary forms, with or without
   * modification, are permitted provided that the following conditions
   * are met:
   *
   * 1. Redistributions of source code must retain the above copyright
   *    notice, this list of conditions and the following disclaimer.
   *
   * 2. Redistributions in binary form must reproduce the above copyright
   *    notice, this list of conditions and the following disclaimer in
   *    the documentation and/or other materials provided with the
   *    distribution.
   *
   * 3. The end-user documentation included with the redistribution,
   *    if any, must include the following acknowledgment:
   *       "This product includes software developed by the
   *        Apache Software Foundation (http://www.apache.org/)."
   *    Alternately, this acknowledgment may appear in the software itself,
   *    if and wherever such third-party acknowledgments normally appear.
   *
   * 4. The names "Xindice" and "Apache Software Foundation" must
   *    not be used to endorse or promote products derived from this
   *    software without prior written permission. For written
   *    permission, please contact apache@apache.org.
   *
   * 5. Products derived from this software may not be called "Apache",
   *    nor may "Apache" appear in their name, without prior written
   *    permission of the Apache Software Foundation.
   *
   * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
   * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
   * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
   * DISCLAIMED.  IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
   * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
   * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
   * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
   * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
   * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
   * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
   * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
   * SUCH DAMAGE.
   * ====================================================================
   *
   * This software consists of voluntary contributions made by many
   * individuals on behalf of the Apache Software Foundation and was
   * originally based on software copyright (c) 1999-2001, The dbXML
   * Group, L.L.C., http://www.dbxmlgroup.com.  For more
   * information on the Apache Software Foundation, please see
   * <http://www.apache.org/>.
   *
   * $Id: Record.java,v 1.1 2001/12/06 21:00:11 bradford Exp $
   */
  
  import java.util.Map;
  
  /**
   * Record is a container for Key/Value pairs.  Record also provides
   * metadata for a Value stored in the database.
   */
  
  public final class Record {
     public static final String CREATED = "created";
     public static final String MODIFIED = "modified";
     public static final String OWNER = "owner";
     public static final String GROUP = "group";
     
     private Key key = null;
     private Value value = null;
     private Map meta = null;
  
     public Record() {
     }
  
     public Record(Key key, Value value, Map meta) {
        this.key = key;
        this.value = value;
        this.meta = meta;
     }
     
     public Record(Key key, Value value) {
        this.key = key;
        this.value = value;
     }
  
     /**
      * getKey returns the Record's Key.
      *
      * @return The Record's Key
      */
     public Key getKey() {
        return key;
     }
  
     /**
      * setValue sets the Record's Value.
      *
      * @param value The new Value
      */
     public void setValue(Value value) {
        this.value = value;
     }
  
     /**
      * setValue sets the Record's Value.
      *
      * @param value The new Value
      */
     public void setValue(String value) {
        this.value = new Value(value);
     }
  
     /**
      * getValue returns the Record's Value.
      *
      * @return The Record's Value
      */
     public Value getValue() {
        return value;
     }
     
     /**
      * getMetaData returns metadata about the Value.
      *
      * @param name The property name
      * @return The metadata value
      */
     public Object getMetaData(Object name) {
        return meta != null ? meta.get(name)
                            : null;
     }
  }
  
  
  
  1.1                  xml-xindice/Xindice/java/src/org/apache/xindice/core/data/RecordSet.java
  
  Index: RecordSet.java
  ===================================================================
  package org.apache.xindice.core.data;
  
  /*
   * The Apache Software License, Version 1.1
   *
   *
   * Copyright (c) 1999 The Apache Software Foundation.  All rights
   * reserved.
   *
   * Redistribution and use in source and binary forms, with or without
   * modification, are permitted provided that the following conditions
   * are met:
   *
   * 1. Redistributions of source code must retain the above copyright
   *    notice, this list of conditions and the following disclaimer.
   *
   * 2. Redistributions in binary form must reproduce the above copyright
   *    notice, this list of conditions and the following disclaimer in
   *    the documentation and/or other materials provided with the
   *    distribution.
   *
   * 3. The end-user documentation included with the redistribution,
   *    if any, must include the following acknowledgment:
   *       "This product includes software developed by the
   *        Apache Software Foundation (http://www.apache.org/)."
   *    Alternately, this acknowledgment may appear in the software itself,
   *    if and wherever such third-party acknowledgments normally appear.
   *
   * 4. The names "Xindice" and "Apache Software Foundation" must
   *    not be used to endorse or promote products derived from this
   *    software without prior written permission. For written
   *    permission, please contact apache@apache.org.
   *
   * 5. Products derived from this software may not be called "Apache",
   *    nor may "Apache" appear in their name, without prior written
   *    permission of the Apache Software Foundation.
   *
   * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
   * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
   * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
   * DISCLAIMED.  IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
   * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
   * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
   * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
   * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
   * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
   * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
   * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
   * SUCH DAMAGE.
   * ====================================================================
   *
   * This software consists of voluntary contributions made by many
   * individuals on behalf of the Apache Software Foundation and was
   * originally based on software copyright (c) 1999-2001, The dbXML
   * Group, L.L.C., http://www.dbxmlgroup.com.  For more
   * information on the Apache Software Foundation, please see
   * <http://www.apache.org/>.
   *
   * $Id: RecordSet.java,v 1.1 2001/12/06 21:00:11 bradford Exp $
   */
  
  import org.apache.xindice.core.*;
  
  /**
   * RecordSet is an interface for iterating over a set of Records.
   * It is almost always returned by Filers.
   */
  
  public interface RecordSet {
     /**
      * hasMoreRecords returns whether or not there are any Records
      * left in the set.
      *
      * @return Whether there are any more Records
      */
     boolean hasMoreRecords() throws DBException;
     
     /**
      * getNextRecord returns the next Record in the set.
      *
      * @return The next Record
      */
     Record getNextRecord() throws DBException;
     
     /**
      * getNextKey returns the next Record's Key, and skips the
      * RecordSet ahead to the next Record.
      *
      * @return The next Key
      */
     Key getNextKey() throws DBException;
  
     /**
      * getNextValue returns the next Record's Value, and skips the
      * RecordSet ahead to the next Record.
      *
      * @return The next Value
      */
     Value getNextValue() throws DBException;
  }
  
  
  
  1.1                  xml-xindice/Xindice/java/src/org/apache/xindice/core/data/Value.java
  
  Index: Value.java
  ===================================================================
  package org.apache.xindice.core.data;
  
  /*
   * The Apache Software License, Version 1.1
   *
   *
   * Copyright (c) 1999 The Apache Software Foundation.  All rights
   * reserved.
   *
   * Redistribution and use in source and binary forms, with or without
   * modification, are permitted provided that the following conditions
   * are met:
   *
   * 1. Redistributions of source code must retain the above copyright
   *    notice, this list of conditions and the following disclaimer.
   *
   * 2. Redistributions in binary form must reproduce the above copyright
   *    notice, this list of conditions and the following disclaimer in
   *    the documentation and/or other materials provided with the
   *    distribution.
   *
   * 3. The end-user documentation included with the redistribution,
   *    if any, must include the following acknowledgment:
   *       "This product includes software developed by the
   *        Apache Software Foundation (http://www.apache.org/)."
   *    Alternately, this acknowledgment may appear in the software itself,
   *    if and wherever such third-party acknowledgments normally appear.
   *
   * 4. The names "Xindice" and "Apache Software Foundation" must
   *    not be used to endorse or promote products derived from this
   *    software without prior written permission. For written
   *    permission, please contact apache@apache.org.
   *
   * 5. Products derived from this software may not be called "Apache",
   *    nor may "Apache" appear in their name, without prior written
   *    permission of the Apache Software Foundation.
   *
   * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
   * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
   * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
   * DISCLAIMED.  IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
   * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
   * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
   * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
   * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
   * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
   * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
   * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
   * SUCH DAMAGE.
   * ====================================================================
   *
   * This software consists of voluntary contributions made by many
   * individuals on behalf of the Apache Software Foundation and was
   * originally based on software copyright (c) 1999-2001, The dbXML
   * Group, L.L.C., http://www.dbxmlgroup.com.  For more
   * information on the Apache Software Foundation, please see
   * <http://www.apache.org/>.
   *
   * $Id: Value.java,v 1.1 2001/12/06 21:00:11 bradford Exp $
   */
  
  import java.io.*;
  
  /**
   * Value is the primary base class for all data storing objects.
   * The content window of Value objects are immutable, but the
   * underlying byte array is not.
   */
  
  public class Value implements Comparable {
     protected byte[] data = null;
     protected int pos = 0;
     protected int len = -1;
  
     private Value() {
     }
  
     public Value(Value value) {
        data = value.data;
        pos = value.pos;
        len = value.len;
     }
  
     public Value(byte[] data) {
        this.data = data;
        len = data.length;
     }
  
     public Value(byte[] data, int pos, int len) {
        this.data = data;
        this.pos = pos;
        this.len = len;
     }
  
     public Value(String data) {
        this(data.getBytes());
     }
  
     /**
      * getData retrieves the data being stored by the Value as a byte array.
      *
      * @return The Data
      */
     public final byte[] getData() {
        if ( len != data.length ) {
           byte[] b = new byte[len];
           System.arraycopy(data, pos, b, 0, len);
           return b;
        }
        else
           return data;
     }
  
     /**
      * getLength retrieves the length of the data being stored by the Value.
      *
      * @return The Value length
      */
     public final int getLength() {
        return len;
     }
  
     /**
      * getInputStream returns an InputStream for the Value.
      *
      * @return An InputStream
      */
     public final InputStream getInputStream() {
        return new ByteArrayInputStream(data, pos, len);
     }
  
     /**
      * streamTo streams the content of the Value to an OutputStream.
      *
      * @param out the OutputStream
      */
     public final void streamTo(OutputStream out) throws IOException {
        out.write(data, pos, len);
     }
  
     public final void copyTo(byte[] tdata, int tpos) {
        System.arraycopy(data, pos, tdata, tpos, len);
     }
  
     public final String toString() {
        return new String(getData());
     }
  
     public int hashCode() {
        return toString().hashCode();
     }
  
     public boolean equals(Value value) {
        return len == value.len ? compareTo(value) == 0
                                : false;
     }
  
     public boolean equals(Object obj) {
        if ( this == obj )
           return true;
        if ( obj instanceof Value )
           return equals((Value)obj);
        else
           return equals(new Value(obj.toString()));
     }
  
     public final int compareTo(Value value) {
        byte[] ddata = value.data;
        int dpos = value.pos;
        int dlen = value.len;
  
        int stop = len > dlen ? dlen
                              : len;
  
        for ( int i = 0; i < stop; i++ ) {
           byte b1 = data[pos+i];
           byte b2 = ddata[dpos+i];
  
           if ( b1 == b2 )
              continue;
           else {
              short s1 = (short)(b1 >>> 0);
              short s2 = (short)(b2 >>> 0);
              return s1 > s2 ? (i+1)
                             : -(i+1);
           }
        }
  
        if ( len == dlen )
           return 0;
        else
           return len > dlen ? stop+1
                             : -(stop+1);
     }
  
     public final int compareTo(Object obj) {
        if ( obj instanceof Value )
           return compareTo((Value)obj);
        else
           return compareTo(new Value(obj.toString()));
     }
     
     public final boolean startsWith(Value value) {
        if ( len < value.len )
           return false;
        
        byte[] ddata = value.data;
        int dpos = value.pos;
        
        for ( int i = 0; i < value.len; i++ )
           if ( data[i+pos] != ddata[i+dpos] )
              return false;
        
        return true;
     }
  }
  
  
  
  1.1                  xml-xindice/Xindice/java/src/org/apache/xindice/core/data/package.html
  
  Index: package.html
  ===================================================================
  <html>
    <title>Basic Data Types and Containers.</title>
    <body>
      <p>Defines and Implements several basic data types and container
      interfaces, including Key, Value, DocumentSet and NodeSet.</p>
   </body>
  </html>
  
  
  
  
  
  1.1                  xml-xindice/Xindice/java/src/org/apache/xindice/core/filer/BTree.java
  
  Index: BTree.java
  ===================================================================
  package org.apache.xindice.core.filer;
  
  /*
   * The Apache Software License, Version 1.1
   *
   *
   * Copyright (c) 1999 The Apache Software Foundation.  All rights
   * reserved.
   *
   * Redistribution and use in source and binary forms, with or without
   * modification, are permitted provided that the following conditions
   * are met:
   *
   * 1. Redistributions of source code must retain the above copyright
   *    notice, this list of conditions and the following disclaimer.
   *
   * 2. Redistributions in binary form must reproduce the above copyright
   *    notice, this list of conditions and the following disclaimer in
   *    the documentation and/or other materials provided with the
   *    distribution.
   *
   * 3. The end-user documentation included with the redistribution,
   *    if any, must include the following acknowledgment:
   *       "This product includes software developed by the
   *        Apache Software Foundation (http://www.apache.org/)."
   *    Alternately, this acknowledgment may appear in the software itself,
   *    if and wherever such third-party acknowledgments normally appear.
   *
   * 4. The names "Xindice" and "Apache Software Foundation" must
   *    not be used to endorse or promote products derived from this
   *    software without prior written permission. For written
   *    permission, please contact apache@apache.org.
   *
   * 5. Products derived from this software may not be called "Apache",
   *    nor may "Apache" appear in their name, without prior written
   *    permission of the Apache Software Foundation.
   *
   * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
   * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
   * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
   * DISCLAIMED.  IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
   * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
   * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
   * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
   * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
   * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
   * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
   * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
   * SUCH DAMAGE.
   * ====================================================================
   *
   * This software consists of voluntary contributions made by many
   * individuals on behalf of the Apache Software Foundation and was
   * originally based on software copyright (c) 1999-2001, The dbXML
   * Group, L.L.C., http://www.dbxmlgroup.com.  For more
   * information on the Apache Software Foundation, please see
   * <http://www.apache.org/>.
   *
   * $Id: BTree.java,v 1.1 2001/12/06 21:00:12 bradford Exp $
   */
  
  import org.apache.xindice.core.*;
  import org.apache.xindice.core.data.*;
  import org.apache.xindice.core.indexer.*;
  import org.apache.xindice.core.indexer.helpers.*;
  import org.apache.xindice.util.*;
  
  import java.io.*;
  import java.util.*;
  
  /**
   * BTree represents a Variable Magnitude Simple-Prefix B+Tree File.
   * A BTree is a bit flexible in that it can be used for set or
   * map-based indexing.  HashFiler uses the BTree as a set for
   * producing RecordSet entries.  The Indexers use BTree as a map for
   * indexing entity and attribute values in Documents.
   * <br><br>
   * For those who don't know how a Simple-Prefix B+Tree works, the primary
   * distinction is that instead of promoting actual keys to branch pages,
   * when leaves are split, a shortest-possible separator is generated at
   * the pivot.  That separator is what is promoted to the parent branch
   * (and continuing up the list).  As a result, actual keys and pointers
   * can only be found at the leaf level.  This also affords the index the
   * ability to ignore costly merging and redistribution of pages when
   * deletions occur.  Deletions only affect leaf pages in this
   * implementation, and so it is entirely possible for a leaf page to be
   * completely empty after all of its keys have been removed.
   * <br><br>
   * Also, the Variable Magnitude attribute means that the btree attempts
   * to store as many values and pointers on one page as is possible.
   * <br><br>
   * This implementation supports the notion of nested roots.  This means
   * that you can create a btree where the pointers actually point to the
   * root of a separate btree being managed in the same file.
   */
  
  public class BTree extends Paged {
     protected static final byte LEAF = 1;
     protected static final byte BRANCH = 2;
     protected static final byte STREAM = 3;
  
     private Map cache = new WeakHashMap();
     
     private BTreeFileHeader fileHeader;
     private BTreeRootInfo rootInfo;
     private BTreeNode rootNode;
     
     public BTree() {
        super();
        fileHeader = (BTreeFileHeader)getFileHeader();
        fileHeader.setPageCount(1);
        fileHeader.setTotalCount(1);
     }
  
     public BTree(File file) {
        this();
        setFile(file);
     }
  
     public boolean open() throws DBException {
        if ( super.open() ) {
           long p = fileHeader.getRootPage();
           rootInfo = new BTreeRootInfo(p);
           rootNode = getBTreeNode(rootInfo, p, null);
           return true;
        }
        else
           return false;
     }
  
     public boolean create() throws DBException {
        if ( super.create() ) {
           try {
              long p = fileHeader.getRootPage();
              rootInfo = new BTreeRootInfo(p);
              rootNode = new BTreeNode(rootInfo, getPage(p));
              rootNode.ph.setStatus(LEAF);
              rootNode.setValues(new Value[0]);
              rootNode.setPointers(new long[0]);
              rootNode.write();
              return true;
           }
           catch ( Exception e ) {
  org.apache.xindice.Debug.printStackTrace(e);
           }
        }
        return false;
     }
  
     /**
      * addValue adds a Value to the BTree and associates a pointer with
      * it.  The pointer can be used for referencing any type of data, it
      * just so happens that Xindice uses it for referencing pages of
      * associated data in the BTree file or other files.
      *
      * @param value The Value to add
      * @param pointer The pointer to associate with it
      * @return The previous value for the pointer (or -1)
      */
     public long addValue(Value value, long pointer) throws IOException, BTreeException {
        return getRootNode().addValue(value, pointer);
     }
  
     /**
      * addValue adds a Value to the BTree and associates a pointer with
      * it.  The pointer can be used for referencing any type of data, it
      * just so happens that Xindice uses it for referencing pages of
      * associated data in the BTree file or other files.
      *
      * @param root The BTree's root information (for nested trees)
      * @param value The Value to add
      * @param pointer The pointer to associate with it
      * @return The previous value for the pointer (or -1)
      */
     public long addValue(BTreeRootInfo root, Value value, long pointer) throws IOException, BTreeException {
        return getRootNode(root).addValue(value, pointer);
     }
     
     /**
      * removeValue removes a Value from the BTree and returns the
      * associated pointer for it.
      *
      * @param value The Value to remove
      * @return The pointer that was associated with it
      */
     public long removeValue(Value value) throws IOException, BTreeException {
        return getRootNode().removeValue(value);
     }
  
     /**
      * removeValue removes a Value from the BTree and returns the
      * associated pointer for it.
      *
      * @param root The BTree's root information (for nested trees)
      * @param value The Value to remove
      * @return The pointer that was associated with it
      */
     public long removeValue(BTreeRootInfo root, Value value) throws IOException, BTreeException {
        return getRootNode(root).removeValue(value);
     }
     
     /**
      * findValue finds a Value in the BTree and returns the associated
      * pointer for it.
      *
      * @param value The Value to find
      * @return The pointer that was associated with it
      */
     public long findValue(Value value) throws IOException, BTreeException {
        return getRootNode().findValue(value);
     }
  
     /**
      * findValue finds a Value in the BTree and returns the associated
      * pointer for it.
      *
      * @param root The BTree's root information (for nested trees)
      * @param value The Value to find
      * @return The pointer that was associated with it
      */
     public long findValue(BTreeRootInfo root, Value value) throws IOException, BTreeException {
        return getRootNode(root).findValue(value);
     }
     
     /**
      * query performs a query against the BTree and performs callback
      * operations to report the search results.
      *
      * @param query The IndexQuery to use (or null for everything)
      * @param callback The callback instance
      */
     public void query(IndexQuery query, BTreeCallback callback) throws IOException, BTreeException {
        getRootNode().query(query, callback);
     }
  
     /**
      * query performs a query against the BTree and performs callback
      * operations to report the search results.
      *
      * @param root The BTree's root information (for nested trees)
      * @param query The IndexQuery to use (or null for everything)
      * @param callback The callback instance
      */
     public void query(BTreeRootInfo root, IndexQuery query, BTreeCallback callback) throws IOException, BTreeException {
        getRootNode(root).query(query, callback);
     }
  
     /**
      * createBTreeRoot creates a new BTree root node in the BTree file
      * based on the provided value for the main tree.
      *
      * @param v The sub-tree Value to create
      * @return The new BTreeRootInfo instance
      */
     protected final BTreeRootInfo createBTreeRoot(Value v) throws IOException, BTreeException {
        BTreeNode n = createBTreeNode(rootInfo, BTree.LEAF, null);
        n.write();
        
        long position = n.page.getPageNum();
        addValue(v, position);
        return new BTreeRootInfo(v, position);
     }
  
     /**
      * createBTreeRoot creates a new BTree root node in the BTree file
      * based on the provided root information, and value for the tree.
      *
      * @param root The BTreeRootInfo to build off of
      * @param v The sub-tree Value to create
      * @return The new BTreeRootInfo instance
      */
     protected final BTreeRootInfo createBTreeRoot(BTreeRootInfo root, Value v) throws IOException, BTreeException {
        BTreeNode n = createBTreeNode(root, BTree.LEAF, null);
        n.write();
        
        long position = n.page.getPageNum();
        addValue(v, position);
        return new BTreeRootInfo(root, v, position);
     }
  
     /**
      * findBTreeRoot searches for a BTreeRoot in the file and returns
      * the BTreeRootInfo for the specified value based on the main tree.
      *
      * @param v The sub-tree Value to search for
      * @return The new BTreeRootInfo instance
      */
     protected final BTreeRootInfo findBTreeRoot(Value v) throws IOException, BTreeException {
        long position = findValue(v);
        return new BTreeRootInfo(v, position);
     }
  
     /**
      * findBTreeRoot searches for a BTreeRoot in the file and returns
      * the BTreeRootInfo for the specified value based on the provided
      * BTreeRootInfo value.
      *
      * @param root The BTreeRootInfo to search from
      * @param v The sub-tree Value to search for
      * @return The new BTreeRootInfo instance
      */
     protected final BTreeRootInfo findBTreeRoot(BTreeRootInfo root, Value v) throws IOException, BTreeException {
        long position = findValue(root, v);
        return new BTreeRootInfo(root, v, position);
     }
     
     /**
      * setRootNode resets the root for the specified root object to the
      * provided BTreeNode's page number.
      *
      * @param root The root to reset
      * @param rootNode the new root node to use
      */
     protected final void setRootNode(BTreeRootInfo root, BTreeNode newRoot) throws IOException, BTreeException {
        BTreeRootInfo parent = root.getParent();
        if ( parent == null ) {
           rootNode = newRoot;
           long p = rootNode.page.getPageNum();
           rootInfo.setPage(p);
           fileHeader.setRootPage(p);
        }
        else {
           long p = newRoot.page.getPageNum();
           root.setPage(p);
           addValue(parent, root.name, p);
        }
     }
  
     /**
      * setRootNode resets the file's root to the provided
      * BTreeNode's page number.
      *
      * @param rootNode the new root node to use
      */
     protected final void setRootNode(BTreeNode rootNode) throws IOException, BTreeException {
        setRootNode(rootInfo, rootNode);
     }
  
     /**
      * getRootNode retreives the BTree node for the specified
      * root object.
      *
      * @param root The root object to retrieve with
      * @return The root node
      */
     protected final BTreeNode getRootNode(BTreeRootInfo root) {
        if ( root.page == rootInfo.page )
           return rootNode;
        else
           return getBTreeNode(root, root.getPage(), null);
     }
  
     /**
      * getRootNode retreives the BTree node for the file's root.
      *
      * @return The root node
      */
     protected final BTreeNode getRootNode() {
        return rootNode;
     }
     
     private BTreeNode getBTreeNode(BTreeRootInfo root, long page, BTreeNode parent) {
        try {
           Long pNum = new Long(page);
           BTreeNode node = (BTreeNode)cache.get(pNum);
           if ( node == null ) {
              Page p = getPage(pNum);
              node = new BTreeNode(root, p, parent);
              node.read();
           }
           else {
              node.root = root;
              node.parent = parent;
           }
           return node;
        }
        catch ( Exception e ) {
           return null;
        }
     }
  
     private BTreeNode createBTreeNode(BTreeRootInfo root, byte status, BTreeNode parent) {
        try {
           Page p = getFreePage();
           BTreeNode node = new BTreeNode(root, p, parent);
           node.ph.setStatus(status);
           node.setValues(new Value[0]);
           node.setPointers(new long[0]);
           return node;
        }
        catch ( Exception e ) {
           return null;
        }
     }
     
     
     /**
      * BTreeRootInfo
      */
  
     public final class BTreeRootInfo {
        private BTreeRootInfo parent;
        private Value name;
        private long page;
  
        public BTreeRootInfo(BTreeRootInfo parent, String name, long page) {
           this.parent = parent;
           this.name = new Value(name);
           this.page = page;
        }
  
        public BTreeRootInfo(BTreeRootInfo parent, Value name, long page) {
           this.parent = parent;
           this.name = name;
           this.page = page;
        }
        
        public BTreeRootInfo(String name, long page) {
           this.parent = rootInfo;
           this.name = new Value(name);
           this.page = page;
        }
  
        public BTreeRootInfo(Value name, long page) {
           this.parent = rootInfo;
           this.name = name;
           this.page = page;
        }
        
        private BTreeRootInfo(long page) {
           parent = null;
           name = null;
           this.page = page;
        }
  
        public BTreeRootInfo getParent() {
           return parent;
        }
        
        public Value getName() {
           return name;
        }
        
        public long getPage() {
           return page;
        }
        
        public void setPage(long page) {
           this.page = page;
        }
     }
  
     
     /**
      * BTreeNode
      */
  
     private final class BTreeNode {
        private BTreeRootInfo root;
        private Page page;
        private BTreePageHeader ph;
        private Value[] values;
        private long[] ptrs;
        private BTreeNode parent;
  
        public BTreeNode(BTreeRootInfo root, Page page, BTreeNode parent) {
           this.root = root;
           this.page = page;
           this.parent = parent;
           ph = (BTreePageHeader)page.getPageHeader();
        }
        
        public BTreeNode(BTreeRootInfo root, Page page) {
           this.root = root;
           this.page = page;
           ph = (BTreePageHeader)page.getPageHeader();
        }
  
        public void setValues(Value[] values) {
           this.values = values;
           ph.setValueCount((short)values.length);
        }
  
        public Value[] getValues() {
           return values;
        }
  
        public void setPointers(long[] ptrs) {
           this.ptrs = ptrs;
        }
  
        public long[] getPointers() {
           return ptrs;
        }
  
        public void read() throws IOException {
           Value v = readValue(page);
           DataInputStream is = new DataInputStream(v.getInputStream());
  
           // Read in the Values
           values = new Value[ph.getValueCount()];
           for ( int i = 0; i < values.length; i++ ) {
              short valSize = is.readShort();
              byte[] b = new byte[valSize];
  
              is.read(b);
              values[i] = new Value(b);
           }
  
           // Read in the pointers
           ptrs = new long[ph.getPointerCount()];
           for ( int i = 0; i < ptrs.length; i++ )
              ptrs[i] = is.readLong();
           
           cache.put(new Long(page.getPageNum()), this);
        }
  
        public void write() throws IOException {
           ByteArrayOutputStream bos = new ByteArrayOutputStream((int)fileHeader.getWorkSize());
           DataOutputStream os = new DataOutputStream(bos);
  
           // Write out the Values
           for ( int i = 0; i < values.length; i++ ) {
              os.writeShort(values[i].getLength());
              values[i].streamTo(os);
           }
  
           // Write out the pointers
           for ( int i = 0; i < ptrs.length; i++ )
              os.writeLong(ptrs[i]);
           
           writeValue(page, new Value(bos.toByteArray()));
           
           cache.put(new Long(page.getPageNum()), this);
        }
  
        public BTreeNode getChildNode(int idx) throws IOException {
           if ( ph.getStatus() == BRANCH && idx >= 0 && idx < ptrs.length )
              return getBTreeNode(root, ptrs[idx], this);
           else
              return null;
        }
  
        public void getChildStream(int idx, Streamable stream) throws IOException {
           if ( ph.getStatus() == LEAF && idx >= 0 && idx < ptrs.length ) {
              Value v = readValue(ptrs[idx]);
              DataInputStream dis = new DataInputStream(v.getInputStream());
              stream.read(dis);
           }
        }
  
        public long removeValue(Value value) throws IOException, BTreeException {
           int idx = Arrays.binarySearch(values, value);
           switch ( ph.getStatus() ) {
              case BRANCH:
                 if ( idx < 0 )
                    idx = -(idx+1);
                 return getChildNode(idx).removeValue(value);
  
              case LEAF:
                 if ( idx < 0 )
                    throw new BTreeNotFoundException("Value '"+value.toString()+"' doesn't exist");
                 else {
                    long oldPtr = ptrs[idx];
  
                    setValues(deleteArrayValue(values, idx));
                    setPointers(deleteArrayLong(ptrs, idx));
  
                    write();
                    return oldPtr;
                 }
  
              default:
                 throw new BTreeCorruptException("Invalid Page Type In removeValue");
           }
        }
  
        public long addValue(Value value, long pointer) throws IOException, BTreeException {
           int idx = Arrays.binarySearch(values, value);
  
           switch ( ph.getStatus() ) {
              case BRANCH:
                 if ( idx < 0 )
                    idx = -(idx+1);
                 return getChildNode(idx).addValue(value, pointer);
  
              case LEAF:
                 if ( idx >= 0 ) {
                    // Value was found... Overwrite
                    long oldPtr = ptrs[idx];
                    ptrs[idx] = pointer;
                    
                    setValues(values);
                    setPointers(ptrs);
                    
                    write();
                    return oldPtr;
                 }
                 else {
                    // Value was not found
                    idx = -(idx+1);
  
                    // Check to see if we've exhausted the block
                    boolean split = ph.getDataLen()+6+value.getLength() > fileHeader.getWorkSize();
  
                    setValues(insertArrayValue(values, value, idx));
                    setPointers(insertArrayLong(ptrs, pointer, idx));
  
                    if ( split )
                       split();
                    else
                       write();
                 }
                 return -1;
  
              default:
                 throw new BTreeCorruptException("Invalid Page Type In addValue");
           }
        }
  
        public void promoteValue(Value value, long rightPointer) throws IOException, BTreeException {
           // Check to see if we've exhausted the block
           boolean split = ph.getDataLen()+6+value.getLength() > fileHeader.getWorkSize();
  
           int idx = Arrays.binarySearch(values, value);
           if ( idx < 0 )
              idx = -(idx+1);
  
           setValues(insertArrayValue(values, value, idx));
           setPointers(insertArrayLong(ptrs, rightPointer, idx+1));
  
           if ( split )
              split();
           else
              write();
        }
  
        public Value getSeparator(Value value1, Value value2) {
           int idx = value1.compareTo(value2);
           byte[] b = new byte[Math.abs(idx)];
           System.arraycopy(value2.getData(), 0, b, 0, b.length);
           return new Value(b);
        }
  
        public void split() throws IOException, BTreeException {
           Value[] leftVals;
           Value[] rightVals;
           long[] leftPtrs;
           long[] rightPtrs;
           Value separator;
  
           short vc = ph.getValueCount();
           int pivot = vc / 2;
  
           // Split the node into two nodes
           switch ( ph.getStatus() ) {
              case BRANCH:
                 leftVals = new Value[pivot];
                 leftPtrs = new long[leftVals.length+1];
                 rightVals = new Value[vc-(pivot+1)];
                 rightPtrs = new long[rightVals.length+1];
  
                 System.arraycopy(values, 0, leftVals, 0, leftVals.length);
                 System.arraycopy(ptrs, 0, leftPtrs, 0, leftPtrs.length);
                 System.arraycopy(values, leftVals.length+1, rightVals, 0, rightVals.length);
                 System.arraycopy(ptrs, leftPtrs.length, rightPtrs, 0, rightPtrs.length);
  
                 separator = values[leftVals.length];
                 break;
  
              case LEAF:
                 leftVals = new Value[pivot];
                 leftPtrs = new long[leftVals.length];
                 rightVals = new Value[vc-pivot];
                 rightPtrs = new long[rightVals.length];
  
                 System.arraycopy(values, 0, leftVals, 0, leftVals.length);
                 System.arraycopy(ptrs, 0, leftPtrs, 0, leftPtrs.length);
                 System.arraycopy(values, leftVals.length, rightVals, 0, rightVals.length);
                 System.arraycopy(ptrs, leftPtrs.length, rightPtrs, 0, rightPtrs.length);
  
                 separator = getSeparator(leftVals[leftVals.length-1], rightVals[0]);
                 break;
  
              default:
                 throw new BTreeCorruptException("Invalid Page Type In split");
           }
  
           setValues(leftVals);
           setPointers(leftPtrs);
  
           // Promote the pivot to the parent branch
           if ( parent == null ) {
              // This can only happen if this is the root
              BTreeNode np = createBTreeNode(root, BRANCH, null);
  
              BTreeNode rNode = createBTreeNode(root, ph.getStatus(), np);
              rNode.setValues(rightVals);
              rNode.setPointers(rightPtrs);
  
              np.setValues(new Value[] { separator });
              np.setPointers(new long[] { page.getPageNum(), rNode.page.getPageNum()});
  
              parent = np;
              
              setRootNode(root, np);
              
              write();
              rNode.write();
              np.write();
           }
           else {
              BTreeNode rNode = createBTreeNode(root, ph.getStatus(), parent);
              rNode.setValues(rightVals);
              rNode.setPointers(rightPtrs);
  
              write();
              rNode.write();
              parent.promoteValue(separator, rNode.page.getPageNum());
           }
        }
  
        /////////////////////////////////////////////////////////////////
  
        public long findValue(Value value) throws IOException, BTreeException {
           int idx = Arrays.binarySearch(values, value);
  
           switch ( ph.getStatus() ) {
              case BRANCH:
                 if ( idx < 0 )
                    idx = -(idx+1);
                 return getChildNode(idx).findValue(value);
  
              case LEAF:
                 if ( idx < 0 )
                    throw new BTreeNotFoundException("Value '"+value.toString()+"' doesn't exist");
                 else
                    return ptrs[idx];
  
              default:
                 throw new BTreeCorruptException("Invalid Page Type In findValue");
           }
        }
  
        // query is a BEAST of a method
        public void query(IndexQuery query, BTreeCallback callback) throws IOException, BTreeException {
           if ( query != null && query.getOperator() != IndexQuery.ANY ) {
              Value[] qvals = query.getValues();
              int leftIdx = Arrays.binarySearch(values, qvals[0]);
              int rightIdx = qvals.length > 1 ? Arrays.binarySearch(values, qvals[qvals.length-1])
                                              : leftIdx;
              int op = query.getOperator();
              
              switch ( ph.getStatus() ) {
                 case BRANCH:
                    if ( leftIdx < 0 )
                       leftIdx = -(leftIdx+1);
                    if ( rightIdx < 0 )
                       rightIdx = -(rightIdx+1);
  
                    switch ( query.getOperator() ) {
                       case IndexQuery.BWX:
                       case IndexQuery.BW:
                       case IndexQuery.IN:
                       case IndexQuery.SW:
                          for ( int i = 0; i < ptrs.length; i++ )
                             if ( i >= leftIdx && i <= rightIdx )
                                getChildNode(i).query(query, callback);
                          break;
  
                       case IndexQuery.NBWX:
                       case IndexQuery.NBW:
                       case IndexQuery.NIN:
                       case IndexQuery.NSW:
                          for ( int i = 0; i < ptrs.length; i++ )
                             if ( i <= leftIdx || i >= rightIdx )
                                getChildNode(i).query(query, callback);
                          break;
  
                       case IndexQuery.EQ:
                          getChildNode(leftIdx).query(query, callback);
                          break;
  
                       case IndexQuery.LT:
                       case IndexQuery.LEQ:
                          for ( int i = 0; i < ptrs.length; i++ )
                             if ( i <= leftIdx )
                                getChildNode(i).query(query, callback);
                          break;
  
                       case IndexQuery.GT:
                       case IndexQuery.GEQ:
                          for ( int i = 0; i < ptrs.length; i++ )
                             if ( i >= rightIdx )
                                getChildNode(i).query(query, callback);
                          break;
  
                       case IndexQuery.NEQ:
                       default:
                          for ( int i = 0; i < ptrs.length; i++ )
                             getChildNode(i).query(query, callback);
                          break;
                    }
                    break;
  
                 case LEAF:
                    switch ( query.getOperator() ) {
                       case IndexQuery.EQ:
                          if ( leftIdx >= 0 )
                             callback.indexInfo(values[leftIdx], ptrs[leftIdx]);
                          break;
  
                       case IndexQuery.NEQ:
                          for ( int i = 0; i < ptrs.length; i++ )
                             if ( i != leftIdx )
                                callback.indexInfo(values[i], ptrs[i]);
                          break;
  
                       case IndexQuery.BWX:
                       case IndexQuery.BW:
                       case IndexQuery.SW:
                       case IndexQuery.IN:
                          if ( leftIdx < 0 )
                             leftIdx = -(leftIdx+1);
                          if ( rightIdx < 0 )
                             rightIdx = -(rightIdx+1);
                          for ( int i = 0; i < ptrs.length; i++ )
                             if ( i >= leftIdx && i <= rightIdx && query.testValue(values[i]) )
                               callback.indexInfo(values[i], ptrs[i]);
                          break;
  
                       case IndexQuery.NBWX:
                       case IndexQuery.NBW:
                       case IndexQuery.NSW:
                          if ( leftIdx < 0 )
                             leftIdx = -(leftIdx+1);
                          if ( rightIdx < 0 )
                             rightIdx = -(rightIdx+1);
                          for ( int i = 0; i < ptrs.length; i++ )
                             if ( (i <= leftIdx || i >= rightIdx) && query.testValue(values[i]) )
                               callback.indexInfo(values[i], ptrs[i]);
                          break;
  
                       case IndexQuery.LT:
                       case IndexQuery.LEQ:
                          if ( leftIdx < 0 )
                             leftIdx = -(leftIdx+1);
                          for ( int i = 0; i < ptrs.length; i++ )
                             if ( i <= leftIdx && query.testValue(values[i]) )
                                callback.indexInfo(values[i], ptrs[i]);
                          break;
  
                       case IndexQuery.GT:
                       case IndexQuery.GEQ:
                          if ( rightIdx < 0 )
                             rightIdx = -(rightIdx+1);
                          for ( int i = 0; i < ptrs.length; i++ )
                             if ( i >= rightIdx && query.testValue(values[i]) )
                                callback.indexInfo(values[i], ptrs[i]);
                          break;
  
                       case IndexQuery.NIN:
                       default:
                          for ( int i = 0; i < ptrs.length; i++ )
                             if ( query.testValue(values[i]) )
                                callback.indexInfo(values[i], ptrs[i]);
                          break;
                    }
                    break;
  
                 default:
                    throw new BTreeCorruptException("Invalid Page Type In query");
              }
  
           }
           else {
              // No Query - Just Walk The Tree
              switch ( ph.getStatus() ) {
                 case BRANCH:
                    for ( int i = 0; i < ptrs.length; i++ )
                       getChildNode(i).query(query, callback);
                    break;
  
                 case LEAF:
                    for ( int i = 0; i < values.length; i++ )
                       callback.indexInfo(values[i], ptrs[i]);
                    break;
  
                 default:
                    throw new BTreeCorruptException("Invalid Page Type In query");
              }
           }
        }
     }
  
     ////////////////////////////////////////////////////////////////////
  
     public FileHeader createFileHeader() {
        return new BTreeFileHeader();
     }
  
     public FileHeader createFileHeader(boolean read) throws IOException {
        return new BTreeFileHeader(read);
     }
  
     public FileHeader createFileHeader(long pageCount) {
        return new BTreeFileHeader(pageCount);
     }
  
     public FileHeader createFileHeader(long pageCount, int pageSize) {
        return new BTreeFileHeader(pageCount, pageSize);
     }
  
     public PageHeader createPageHeader() {
        return new BTreePageHeader();
     }
  
  
     /**
      * BTreeFileHeader
      */
  
     protected class BTreeFileHeader extends FileHeader {
        private long rootPage = 0;
  
        public BTreeFileHeader() {
        }
  
        public BTreeFileHeader(long pageCount) {
           super(pageCount);
        }
  
        public BTreeFileHeader(long pageCount, int pageSize) {
           super(pageCount, pageSize);
        }
  
        public BTreeFileHeader(boolean read) throws IOException {
           super(read);
        }
  
        public void read(RandomAccessFile raf) throws IOException {
           super.read(raf);
           rootPage = raf.readLong();
        }
  
        public void write(RandomAccessFile raf) throws IOException {
           super.write(raf);
           raf.writeLong(rootPage);
        }
  
        /** The root page of the storage tree */
        public final void setRootPage(long rootPage) {
           this.rootPage = rootPage;
           setDirty();
        }
  
        /** The root page of the storage tree */
        public final long getRootPage() {
           return rootPage;
        }
     }
  
  
     /**
      * BTreePageHeader
      */
  
     protected class BTreePageHeader extends PageHeader {
        private short valueCount = 0;
  
        public BTreePageHeader() {
        }
  
        public BTreePageHeader(DataInputStream dis) throws IOException {
           super(dis);
        }
  
        public void read(DataInputStream dis) throws IOException {
           super.read(dis);
  
           if ( getStatus() == UNUSED )
              return;
  
           valueCount = dis.readShort();
        }
  
        public void write(DataOutputStream dos) throws IOException {
           super.write(dos);
           dos.writeShort(valueCount);
        }
  
        /** The number of values stored by this page */
        public final void setValueCount(short valueCount) {
           this.valueCount = valueCount;
           setDirty();
        }
  
        /** The number of values stored by this page */
        public final short getValueCount() {
           return valueCount;
        }
  
        /** The number of pointers stored by this page */
        public final short getPointerCount() {
           if ( getStatus() == BRANCH )
              return (short)(valueCount + 1);
           else
              return valueCount;
        }
     }
  }
  
  
  
  
  
  1.1                  xml-xindice/Xindice/java/src/org/apache/xindice/core/filer/BTreeCallback.java
  
  Index: BTreeCallback.java
  ===================================================================
  package org.apache.xindice.core.filer;
  
  /*
   * The Apache Software License, Version 1.1
   *
   *
   * Copyright (c) 1999 The Apache Software Foundation.  All rights
   * reserved.
   *
   * Redistribution and use in source and binary forms, with or without
   * modification, are permitted provided that the following conditions
   * are met:
   *
   * 1. Redistributions of source code must retain the above copyright
   *    notice, this list of conditions and the following disclaimer.
   *
   * 2. Redistributions in binary form must reproduce the above copyright
   *    notice, this list of conditions and the following disclaimer in
   *    the documentation and/or other materials provided with the
   *    distribution.
   *
   * 3. The end-user documentation included with the redistribution,
   *    if any, must include the following acknowledgment:
   *       "This product includes software developed by the
   *        Apache Software Foundation (http://www.apache.org/)."
   *    Alternately, this acknowledgment may appear in the software itself,
   *    if and wherever such third-party acknowledgments normally appear.
   *
   * 4. The names "Xindice" and "Apache Software Foundation" must
   *    not be used to endorse or promote products derived from this
   *    software without prior written permission. For written
   *    permission, please contact apache@apache.org.
   *
   * 5. Products derived from this software may not be called "Apache",
   *    nor may "Apache" appear in their name, without prior written
   *    permission of the Apache Software Foundation.
   *
   * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
   * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
   * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
   * DISCLAIMED.  IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
   * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
   * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
   * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
   * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
   * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
   * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
   * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
   * SUCH DAMAGE.
   * ====================================================================
   *
   * This software consists of voluntary contributions made by many
   * individuals on behalf of the Apache Software Foundation and was
   * originally based on software copyright (c) 1999-2001, The dbXML
   * Group, L.L.C., http://www.dbxmlgroup.com.  For more
   * information on the Apache Software Foundation, please see
   * <http://www.apache.org/>.
   *
   * $Id: BTreeCallback.java,v 1.1 2001/12/06 21:00:12 bradford Exp $
   */
  
  import org.apache.xindice.core.data.*;
  
  /**
   * BTreeCallback is a callback interface for BTree queries.
   */
  
  public interface BTreeCallback {
     /**
      * indexInfo is a callback method for index enumeration.
      *
      * @param value The Value being reported
      * @param pointer The data pointer being reported
      * @return false to cancel the enumeration
      */
     boolean indexInfo(Value value, long pointer);
  }
  
  
  
  
  1.1                  xml-xindice/Xindice/java/src/org/apache/xindice/core/filer/BTreeCorruptException.java
  
  Index: BTreeCorruptException.java
  ===================================================================
  package org.apache.xindice.core.filer;
  
  /*
   * The Apache Software License, Version 1.1
   *
   *
   * Copyright (c) 1999 The Apache Software Foundation.  All rights
   * reserved.
   *
   * Redistribution and use in source and binary forms, with or without
   * modification, are permitted provided that the following conditions
   * are met:
   *
   * 1. Redistributions of source code must retain the above copyright
   *    notice, this list of conditions and the following disclaimer.
   *
   * 2. Redistributions in binary form must reproduce the above copyright
   *    notice, this list of conditions and the following disclaimer in
   *    the documentation and/or other materials provided with the
   *    distribution.
   *
   * 3. The end-user documentation included with the redistribution,
   *    if any, must include the following acknowledgment:
   *       "This product includes software developed by the
   *        Apache Software Foundation (http://www.apache.org/)."
   *    Alternately, this acknowledgment may appear in the software itself,
   *    if and wherever such third-party acknowledgments normally appear.
   *
   * 4. The names "Xindice" and "Apache Software Foundation" must
   *    not be used to endorse or promote products derived from this
   *    software without prior written permission. For written
   *    permission, please contact apache@apache.org.
   *
   * 5. Products derived from this software may not be called "Apache",
   *    nor may "Apache" appear in their name, without prior written
   *    permission of the Apache Software Foundation.
   *
   * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
   * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
   * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
   * DISCLAIMED.  IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
   * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
   * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
   * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
   * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
   * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
   * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
   * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
   * SUCH DAMAGE.
   * ====================================================================
   *
   * This software consists of voluntary contributions made by many
   * individuals on behalf of the Apache Software Foundation and was
   * originally based on software copyright (c) 1999-2001, The dbXML
   * Group, L.L.C., http://www.dbxmlgroup.com.  For more
   * information on the Apache Software Foundation, please see
   * <http://www.apache.org/>.
   *
   * $Id: BTreeCorruptException.java,v 1.1 2001/12/06 21:00:12 bradford Exp $
   */
  
  import org.apache.xindice.core.*;
  
  /**
   * A BTreecorruptException is thrown by the BTree if the BTree
   * appears to be corrupted in some way.
   */
  
  public final class BTreeCorruptException extends BTreeException {
     public BTreeCorruptException() {
        super(FaultCodes.IDX_CORRUPTED);
     }
     
     public BTreeCorruptException(String message) {
        super(FaultCodes.IDX_CORRUPTED, message);
     }
  }
  
  
  
  1.1                  xml-xindice/Xindice/java/src/org/apache/xindice/core/filer/BTreeException.java
  
  Index: BTreeException.java
  ===================================================================
  package org.apache.xindice.core.filer;
  
  /*
   * The Apache Software License, Version 1.1
   *
   *
   * Copyright (c) 1999 The Apache Software Foundation.  All rights
   * reserved.
   *
   * Redistribution and use in source and binary forms, with or without
   * modification, are permitted provided that the following conditions
   * are met:
   *
   * 1. Redistributions of source code must retain the above copyright
   *    notice, this list of conditions and the following disclaimer.
   *
   * 2. Redistributions in binary form must reproduce the above copyright
   *    notice, this list of conditions and the following disclaimer in
   *    the documentation and/or other materials provided with the
   *    distribution.
   *
   * 3. The end-user documentation included with the redistribution,
   *    if any, must include the following acknowledgment:
   *       "This product includes software developed by the
   *        Apache Software Foundation (http://www.apache.org/)."
   *    Alternately, this acknowledgment may appear in the software itself,
   *    if and wherever such third-party acknowledgments normally appear.
   *
   * 4. The names "Xindice" and "Apache Software Foundation" must
   *    not be used to endorse or promote products derived from this
   *    software without prior written permission. For written
   *    permission, please contact apache@apache.org.
   *
   * 5. Products derived from this software may not be called "Apache",
   *    nor may "Apache" appear in their name, without prior written
   *    permission of the Apache Software Foundation.
   *
   * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
   * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
   * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
   * DISCLAIMED.  IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
   * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
   * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
   * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
   * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
   * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
   * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
   * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
   * SUCH DAMAGE.
   * ====================================================================
   *
   * This software consists of voluntary contributions made by many
   * individuals on behalf of the Apache Software Foundation and was
   * originally based on software copyright (c) 1999-2001, The dbXML
   * Group, L.L.C., http://www.dbxmlgroup.com.  For more
   * information on the Apache Software Foundation, please see
   * <http://www.apache.org/>.
   *
   * $Id: BTreeException.java,v 1.1 2001/12/06 21:00:12 bradford Exp $
   */
  
  import org.apache.xindice.core.*;
  
  /**
   * A BTreeException is thrown by the BTree if an exception occurs
   * in the managing of the BTree.
   */
  
  public class BTreeException extends FilerException {
     public BTreeException(int faultCode) {
        super(faultCode);
     }
     
     public BTreeException(int faultCode, String message) {
        super(faultCode, message);
     }
  }
  
  
  
  1.1                  xml-xindice/Xindice/java/src/org/apache/xindice/core/filer/BTreeFiler.java
  
  Index: BTreeFiler.java
  ===================================================================
  package org.apache.xindice.core.filer;
  
  /*
   * The Apache Software License, Version 1.1
   *
   *
   * Copyright (c) 1999 The Apache Software Foundation.  All rights
   * reserved.
   *
   * Redistribution and use in source and binary forms, with or without
   * modification, are permitted provided that the following conditions
   * are met:
   *
   * 1. Redistributions of source code must retain the above copyright
   *    notice, this list of conditions and the following disclaimer.
   *
   * 2. Redistributions in binary form must reproduce the above copyright
   *    notice, this list of conditions and the following disclaimer in
   *    the documentation and/or other materials provided with the
   *    distribution.
   *
   * 3. The end-user documentation included with the redistribution,
   *    if any, must include the following acknowledgment:
   *       "This product includes software developed by the
   *        Apache Software Foundation (http://www.apache.org/)."
   *    Alternately, this acknowledgment may appear in the software itself,
   *    if and wherever such third-party acknowledgments normally appear.
   *
   * 4. The names "Xindice" and "Apache Software Foundation" must
   *    not be used to endorse or promote products derived from this
   *    software without prior written permission. For written
   *    permission, please contact apache@apache.org.
   *
   * 5. Products derived from this software may not be called "Apache",
   *    nor may "Apache" appear in their name, without prior written
   *    permission of the Apache Software Foundation.
   *
   * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
   * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
   * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
   * DISCLAIMED.  IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
   * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
   * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
   * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
   * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
   * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
   * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
   * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
   * SUCH DAMAGE.
   * ====================================================================
   *
   * This software consists of voluntary contributions made by many
   * individuals on behalf of the Apache Software Foundation and was
   * originally based on software copyright (c) 1999-2001, The dbXML
   * Group, L.L.C., http://www.dbxmlgroup.com.  For more
   * information on the Apache Software Foundation, please see
   * <http://www.apache.org/>.
   *
   * $Id: BTreeFiler.java,v 1.1 2001/12/06 21:00:12 bradford Exp $
   */
  
  import org.apache.xindice.util.*;
  import org.apache.xindice.core.*;
  import org.apache.xindice.core.Collection;
  import org.apache.xindice.core.data.*;
  
  import java.io.*;
  import java.util.*;
  
  /**
   * BTreeFiler is a Filer implementation based on the BTree class.
   */
  
  public final class BTreeFiler extends BTree implements Configurable, Filer {
     protected static final byte RECORD = 20;
  
     private static final String PAGESIZE = "pagesize";
     private static final String MAXKEYSIZE = "maxkeysize";
  
     private Collection collection;
     private Configuration config;
     private BTreeFilerHeader fileHeader;
  
     public BTreeFiler() {
        super();
        fileHeader = (BTreeFilerHeader)getFileHeader();
     }
  
     public void setConfig(Configuration config) {
        this.config = config;
     }
  
     public Configuration getConfig() {
        return config;
     }
  
     public void setLocation(String location) {
        setFile(new File(collection.getCollectionRoot(), location+".tbl"));
     }
  
     public String getName() {
        return "BTreeFiler";
     }
  
     public boolean open() throws DBException {
        if ( super.open() ) {
           // These are the only properties that can be changed after creation
           fileHeader.setMaxKeySize(config.getShortAttribute(MAXKEYSIZE, fileHeader.getMaxKeySize()));
           return true;
        }
        else
           return false;
     }
  
     public boolean create() throws DBException {
        fileHeader.setPageSize(config.getIntAttribute(PAGESIZE, fileHeader.getPageSize()));
        fileHeader.setMaxKeySize(config.getShortAttribute(MAXKEYSIZE, fileHeader.getMaxKeySize()));
        return super.create();
     }
  
     public void setCollection(Collection collection) {
        this.collection = collection;
        setLocation(collection.getName());
     }
  
     public synchronized Record readRecord(Key key) throws DBException {
        checkOpened();
        try {
           long pos = findValue(key);
           Page startPage = getPage(pos);
           Value v = readValue(startPage);
           BTreeFilerPageHeader sph = (BTreeFilerPageHeader)startPage.getPageHeader();
           
           HashMap meta = new HashMap(2);
           meta.put(Record.CREATED, new Long(sph.getCreated()));
           meta.put(Record.MODIFIED, new Long(sph.getModified()));
           
           return new Record(key, v, meta);
        }
        catch ( BTreeNotFoundException b ) {
        }
        catch ( BTreeException b ) {
           throw b;
        }
        catch ( Exception e ) {
           org.apache.xindice.Debug.printStackTrace(e);
        }
        return null;
     }
  
     public synchronized boolean writeRecord(Key key, Value value) throws DBException {
        checkOpened();
        try {
           Page p;
           try {
              long pos = findValue(key);
              p = getPage(pos);
           }
           catch ( BTreeNotFoundException b ) {
              p = getFreePage();
              addValue(key, p.getPageNum());
              fileHeader.incRecordCount();
           }
           BTreeFilerPageHeader ph = (BTreeFilerPageHeader)p.getPageHeader();
  
           long t = System.currentTimeMillis();
           if ( ph.getStatus() == UNUSED )
              ph.setCreated(t);
           
           ph.setModified(t);
           ph.setStatus(RECORD);
  
           writeValue(p, value);
           
           flush();
        }
        catch ( DBException d ) {
           throw d;
        }
        catch ( Exception e ) {
           org.apache.xindice.Debug.printStackTrace(e);
        }
        return true;
     }
  
     public synchronized boolean deleteRecord(Key key) throws DBException {
        checkOpened();
        try {
           long pos = findValue(key);
           Page p = getPage(pos);
  
           removeValue(key);
           unlinkPages(p.getPageNum());
           
           fileHeader.decRecordCount();
  
           flush();
           
           return true;
        }
        catch ( BTreeNotFoundException b ) {
        }
        catch ( BTreeException b ) {
           throw b;
        }
        catch ( Exception e ) {
           org.apache.xindice.Debug.printStackTrace(e);
        }
        return false;
     }
  
     public synchronized long getRecordCount() throws DBException {
        checkOpened();
        return fileHeader.getRecordCount();
     }
  
     public synchronized RecordSet getRecordSet() throws DBException {
        checkOpened();
        return new BTreeFilerRecordSet();
     }
  
     public synchronized void flush() throws DBException {
        super.flush();
     }
     
     
     /**
      * BTreeFilerRecordSet
      */
  
     private class BTreeFilerRecordSet implements RecordSet, BTreeCallback {
        private List keys = new ArrayList();
        private Iterator enum;
  
        public BTreeFilerRecordSet() throws DBException {
           try {
              query(null, this);
              enum = keys.iterator();
           }
           catch ( IOException e ) {
              throw new FilerException(FaultCodes.GEN_CRITICAL_ERROR, "Error generating RecordSet");
           }
        }
  
        public boolean indexInfo(Value value, long pointer) {
           keys.add(new Key(value));
           return true;
        }
  
        public Key getNextKey() {
           return (Key)enum.next();
        }
  
        public Record getNextRecord() throws DBException {
           return readRecord((Key)enum.next());
        }
  
        public Value getNextValue() throws DBException {
           return getNextRecord().getValue();
        }
  
        public boolean hasMoreRecords() {
           return enum.hasNext();
        }
     }
  
     ////////////////////////////////////////////////////////////////////
  
     public FileHeader createFileHeader() {
        return new BTreeFilerHeader();
     }
  
     public FileHeader createFileHeader(boolean read) throws IOException {
        return new BTreeFilerHeader(read);
     }
  
     public FileHeader createFileHeader(long pageCount) {
        return new BTreeFilerHeader(pageCount);
     }
  
     public FileHeader createFileHeader(long pageCount, int pageSize) {
        return new BTreeFilerHeader(pageCount, pageSize);
     }
  
     public PageHeader createPageHeader() {
        return new BTreeFilerPageHeader();
     }
  
  
     /**
      * BTreeFilerHeader
      */
  
     private final class BTreeFilerHeader extends BTreeFileHeader {
        private long totalBytes = 0;
  
        public BTreeFilerHeader() {
        }
  
        public BTreeFilerHeader(long pageCount) {
           super(pageCount);
        }
  
        public BTreeFilerHeader(long pageCount, int pageSize) {
           super(pageCount, pageSize);
        }
  
        public BTreeFilerHeader(boolean read) throws IOException {
           super(read);
        }
  
        public void read(RandomAccessFile raf) throws IOException {
           super.read(raf);
           totalBytes = raf.readLong();
        }
  
        public void write(RandomAccessFile raf) throws IOException {
           super.write(raf);
           raf.writeLong(totalBytes);
        }
  
        /** The total number of bytes in use by the file */
        public void setTotalBytes(long totalBytes) {
           this.totalBytes = totalBytes;
           setDirty();
        }
  
        /** The total number of bytes in use by the file */
        public long getTotalBytes() {
           return totalBytes;
        }
     }
  
     /**
      * BTreeFilerPageHeader
      */
  
     private final class BTreeFilerPageHeader extends BTreePageHeader {
        private long created = 0;
        private long modified = 0;
  
        public BTreeFilerPageHeader() {
        }
  
        public BTreeFilerPageHeader(DataInputStream dis) throws IOException {
           super(dis);
        }
  
        public void read(DataInputStream dis) throws IOException {
           super.read(dis);
  
           if ( getStatus() == UNUSED )
              return;
  
           created = dis.readLong();
           modified = dis.readLong();
        }
  
        public void write(DataOutputStream dos) throws IOException {
           super.write(dos);
           dos.writeLong(created);
           dos.writeLong(modified);
        }
  
        public void setRecordLen(int recordLen) {
           synchronized(fileHeader) {
              fileHeader.setTotalBytes((fileHeader.totalBytes - getRecordLen()) + recordLen);
           }
           super.setRecordLen(recordLen);
        }
  
        /** UNIX-time when this record was created */
        public void setCreated(long created) {
           this.created = created;
           setDirty();
        }
  
        /** UNIX-time when this record was created */
        public long getCreated() {
           return created;
        }
  
        /** UNIX-time when this record was last modified */
        public void setModified(long modified) {
           this.modified = modified;
           setDirty();
        }
  
        /** UNIX-time when this record was last modified */
        public long getModified() {
           return modified;
        }
     }
  }
  
  
  
  
  
  
  1.1                  xml-xindice/Xindice/java/src/org/apache/xindice/core/filer/BTreeNotFoundException.java
  
  Index: BTreeNotFoundException.java
  ===================================================================
  package org.apache.xindice.core.filer;
  
  /*
   * The Apache Software License, Version 1.1
   *
   *
   * Copyright (c) 1999 The Apache Software Foundation.  All rights
   * reserved.
   *
   * Redistribution and use in source and binary forms, with or without
   * modification, are permitted provided that the following conditions
   * are met:
   *
   * 1. Redistributions of source code must retain the above copyright
   *    notice, this list of conditions and the following disclaimer.
   *
   * 2. Redistributions in binary form must reproduce the above copyright
   *    notice, this list of conditions and the following disclaimer in
   *    the documentation and/or other materials provided with the
   *    distribution.
   *
   * 3. The end-user documentation included with the redistribution,
   *    if any, must include the following acknowledgment:
   *       "This product includes software developed by the
   *        Apache Software Foundation (http://www.apache.org/)."
   *    Alternately, this acknowledgment may appear in the software itself,
   *    if and wherever such third-party acknowledgments normally appear.
   *
   * 4. The names "Xindice" and "Apache Software Foundation" must
   *    not be used to endorse or promote products derived from this
   *    software without prior written permission. For written
   *    permission, please contact apache@apache.org.
   *
   * 5. Products derived from this software may not be called "Apache",
   *    nor may "Apache" appear in their name, without prior written
   *    permission of the Apache Software Foundation.
   *
   * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
   * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
   * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
   * DISCLAIMED.  IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
   * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
   * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
   * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
   * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
   * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
   * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
   * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
   * SUCH DAMAGE.
   * ====================================================================
   *
   * This software consists of voluntary contributions made by many
   * individuals on behalf of the Apache Software Foundation and was
   * originally based on software copyright (c) 1999-2001, The dbXML
   * Group, L.L.C., http://www.dbxmlgroup.com.  For more
   * information on the Apache Software Foundation, please see
   * <http://www.apache.org/>.
   *
   * $Id: BTreeNotFoundException.java,v 1.1 2001/12/06 21:00:12 bradford Exp $
   */
  
  import org.apache.xindice.core.*;
  
  /**
   * A BTreeNotFoundException is thrown by the BTree if a Value
   * can't be found in the BTree.
   */
  
  public final class BTreeNotFoundException extends BTreeException {
     public BTreeNotFoundException() {
        super(FaultCodes.IDX_VALUE_NOT_FOUND);
     }
     
     public BTreeNotFoundException(String message) {
        super(FaultCodes.IDX_VALUE_NOT_FOUND, message);
     }
  }
  
  
  
  1.1                  xml-xindice/Xindice/java/src/org/apache/xindice/core/filer/FSFiler.java
  
  Index: FSFiler.java
  ===================================================================
  package org.apache.xindice.core.filer;
  
  /*
   * The Apache Software License, Version 1.1
   *
   *
   * Copyright (c) 1999 The Apache Software Foundation.  All rights
   * reserved.
   *
   * Redistribution and use in source and binary forms, with or without
   * modification, are permitted provided that the following conditions
   * are met:
   *
   * 1. Redistributions of source code must retain the above copyright
   *    notice, this list of conditions and the following disclaimer.
   *
   * 2. Redistributions in binary form must reproduce the above copyright
   *    notice, this list of conditions and the following disclaimer in
   *    the documentation and/or other materials provided with the
   *    distribution.
   *
   * 3. The end-user documentation included with the redistribution,
   *    if any, must include the following acknowledgment:
   *       "This product includes software developed by the
   *        Apache Software Foundation (http://www.apache.org/)."
   *    Alternately, this acknowledgment may appear in the software itself,
   *    if and wherever such third-party acknowledgments normally appear.
   *
   * 4. The names "Xindice" and "Apache Software Foundation" must
   *    not be used to endorse or promote products derived from this
   *    software without prior written permission. For written
   *    permission, please contact apache@apache.org.
   *
   * 5. Products derived from this software may not be called "Apache",
   *    nor may "Apache" appear in their name, without prior written
   *    permission of the Apache Software Foundation.
   *
   * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
   * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
   * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
   * DISCLAIMED.  IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
   * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
   * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
   * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
   * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
   * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
   * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
   * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
   * SUCH DAMAGE.
   * ====================================================================
   *
   * This software consists of voluntary contributions made by many
   * individuals on behalf of the Apache Software Foundation and was
   * originally based on software copyright (c) 1999-2001, The dbXML
   * Group, L.L.C., http://www.dbxmlgroup.com.  For more
   * information on the Apache Software Foundation, please see
   * <http://www.apache.org/>.
   *
   * $Id: FSFiler.java,v 1.1 2001/12/06 21:00:12 bradford Exp $
   */
  
  import org.apache.xindice.core.*;
  import org.apache.xindice.core.Collection;
  import org.apache.xindice.core.data.*;
  import org.apache.xindice.util.*;
  import java.io.*;
  import java.util.*;
  
  /**
   * FSFiler allows you to use existing file systems withing Xindice.
   */
  
  public final class FSFiler extends SimpleConfigurable implements Filer {
     private static final String LOCATION = "location";
     private static final String EXT = "ext";
     private static final String READONLY = "readonly";
  
     private FileCache cache = new FileCache();
     private LockManager locks = new LockManager(16);
  
     private Set extensions = null;
     
     private String location;
     private Collection collection;
     private File dir;
     private boolean opened = false;
     private boolean readOnly = false;
  
     public FSFiler() {
     }
  
     public String getName() {
        return "FSFiler";
     }
  
     public void setCollection(Collection collection) {
        this.collection = collection;
     }
  
     public void setConfig(Configuration config) throws XindiceException {
        super.setConfig(config);
        location = config.getAttribute(LOCATION);
        readOnly = config.getBooleanAttribute(READONLY, readOnly);
        String exts = config.getAttribute(EXT);
        if ( exts != null && exts.trim().length() > 0 ) {
           extensions = new HashSet();
           StringTokenizer st = new StringTokenizer(exts);
           while ( st.hasMoreTokens() )
              extensions.add(st.nextToken());
        }
        dir = new File(location);
        opened = false;
     }
  
     private void checkOpened() throws DBException {
        if ( !opened )
           throw new FilerException(FaultCodes.COL_COLLECTION_CLOSED, "Filer is closed");
     }
  
     private void checkReadOnly() throws DBException {
        if ( readOnly )
           throw new FilerException(FaultCodes.COL_COLLECTION_READ_ONLY, "Filer is read-only");
     }
     
     public boolean close() {
        opened = false;
        return true;
     }
  
     public boolean open() {
        opened = ( dir.exists() && dir.isDirectory() );
        return opened;
     }
  
     public boolean drop() {
        opened = false;
        return true;
     }
  
     public boolean isOpened() {
        return opened;
     }
  
     public boolean exists() {
        return dir.exists();
     }
  
     public boolean create() {
        if ( !dir.exists() )
           return dir.mkdirs();
        else
           return true;
     }
     
     public void flush() {
     }
  
     public Record readRecord(Key key) throws DBException {
        checkOpened();
        
        String fname = key.toString();
        if ( !isExtensionValid(fname) )
           return null;
        
        File file = new File(dir, fname);
        try {
           locks.acquireSharedLock(file);
           
           HashMap meta = new HashMap(1);
           meta.put(Record.MODIFIED, new Long(file.lastModified()));
           
           byte[] valueData = cache.getFile(file);
           if ( valueData != null )
              return new Record(key, new Value(valueData), meta);
        }
        catch ( Exception e ) {
           org.apache.xindice.Debug.printStackTrace(e);
        }
        finally {
           locks.releaseSharedLock(file);
        }
        return null;
     }
  
     public boolean writeRecord(Key key, Value value) throws DBException {
        checkOpened();
        checkReadOnly();
              
        String fname = key.toString();
        if ( !isExtensionValid(fname) )
           return false;
        
        File file = new File(dir, fname);
        try {
           locks.acquireExclusiveLock(file);
           FileOutputStream fos = new FileOutputStream(file);
           value.streamTo(fos);
           fos.close();
           return true;
        }
        catch ( Exception e ) {
           org.apache.xindice.Debug.printStackTrace(e);
        }
        finally {
           locks.releaseExclusiveLock(file);
        }
        return true;
     }
  
     public boolean deleteRecord(Key key) throws DBException {
        checkOpened();
        checkReadOnly();
        
        String fname = key.toString();
        if ( !isExtensionValid(fname) )
           return false;
        
        File file = new File(dir, fname);
        try {
           locks.acquireExclusiveLock(file);
           return file.delete();
        }
        catch ( Exception e ) {
           org.apache.xindice.Debug.printStackTrace(e);
        }
        finally {
           locks.releaseExclusiveLock(file);
        }
        return true;
     }
  
     public long getRecordCount() throws DBException {
        checkOpened();
        
        File[] files = dir.listFiles(new FileFilter() {
           public boolean accept(File file) {
              return file.isFile() && isExtensionValid(file.getName());
           }
        });
        return files.length;
     }
  
     public RecordSet getRecordSet() throws DBException {
        checkOpened();
        return new FSRecordSet();
     }
  
     private boolean isExtensionValid(String fname) {
        if ( extensions != null ) {
           int idx = fname.lastIndexOf('.');
           if ( idx == -1 )
              return false;
           String ext = fname.substring(idx+1);
           if ( !extensions.contains(ext) )
              return false;
        }
        return true;
     }
  
     
     /**
      * FSRecordSet
      */
     
     private class FSRecordSet implements RecordSet {
        public File[] files;
        public int pos = 0;
  
        public FSRecordSet() {
           files = dir.listFiles(new FileFilter() {
              public boolean accept(File file) {
                 return file.isFile() && isExtensionValid(file.getName());
              }
           });
        }
  
        public boolean hasMoreRecords() {
           return pos < files.length;
        }
  
        public Record getNextRecord() throws DBException {
           File file = files[pos++];
           return readRecord(new Key(file.getName()));
        }
  
        public Value getNextValue() throws DBException {
           return getNextRecord().getValue();
        }
        
        public Key getNextKey() {
           return new Key(files[pos++].getName());
        }
     }
  }
  
  
  
  
  1.1                  xml-xindice/Xindice/java/src/org/apache/xindice/core/filer/Filer.java
  
  Index: Filer.java
  ===================================================================
  package org.apache.xindice.core.filer;
  
  /*
   * The Apache Software License, Version 1.1
   *
   *
   * Copyright (c) 1999 The Apache Software Foundation.  All rights
   * reserved.
   *
   * Redistribution and use in source and binary forms, with or without
   * modification, are permitted provided that the following conditions
   * are met:
   *
   * 1. Redistributions of source code must retain the above copyright
   *    notice, this list of conditions and the following disclaimer.
   *
   * 2. Redistributions in binary form must reproduce the above copyright
   *    notice, this list of conditions and the following disclaimer in
   *    the documentation and/or other materials provided with the
   *    distribution.
   *
   * 3. The end-user documentation included with the redistribution,
   *    if any, must include the following acknowledgment:
   *       "This product includes software developed by the
   *        Apache Software Foundation (http://www.apache.org/)."
   *    Alternately, this acknowledgment may appear in the software itself,
   *    if and wherever such third-party acknowledgments normally appear.
   *
   * 4. The names "Xindice" and "Apache Software Foundation" must
   *    not be used to endorse or promote products derived from this
   *    software without prior written permission. For written
   *    permission, please contact apache@apache.org.
   *
   * 5. Products derived from this software may not be called "Apache",
   *    nor may "Apache" appear in their name, without prior written
   *    permission of the Apache Software Foundation.
   *
   * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
   * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
   * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
   * DISCLAIMED.  IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
   * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
   * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
   * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
   * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
   * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
   * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
   * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
   * SUCH DAMAGE.
   * ====================================================================
   *
   * This software consists of voluntary contributions made by many
   * individuals on behalf of the Apache Software Foundation and was
   * originally based on software copyright (c) 1999-2001, The dbXML
   * Group, L.L.C., http://www.dbxmlgroup.com.  For more
   * information on the Apache Software Foundation, please see
   * <http://www.apache.org/>.
   *
   * $Id: Filer.java,v 1.1 2001/12/06 21:00:12 bradford Exp $
   */
  
  import org.apache.xindice.core.*;
  import org.apache.xindice.core.data.*;
  import org.apache.xindice.util.*;
  
  /**
   * Filer is the low-level file management interface for Xindice.  A Filer object
   * is implemented in order to provide a data source to the Xindice Collection
   * class.  Filers are developed to perform transparent storage and retrieval to
   * and from heterogenous data sources (such as FTP, HTTP, RDBMS, etc...)
   */
  
  public interface Filer extends Named, DBObject, Configurable {
     /**
      * setCollection tells the Filer who its parent is.
      *
      * @param collection The owner Collection
      */
     void setCollection(Collection collection);
  
     /**
      * readRecord returns a Record from the Filer based on the specified
      * Key.
      *
      * @param key The Record's Key
      * @return The returned Record
      */
     Record readRecord(Key key) throws DBException;
  
     /**
      * writeRecord writes a Value to the Filer based on the specified Key.
      *
      * @param key The Record's Key
      * @param value The Record's Value
      * @return Whether or not the Record could be written
      */
     boolean writeRecord(Key key, Value value) throws DBException;
  
     /**
      * deleteRecord removes a Record from the Filer based on the
      * specified Key.
      *
      * @param key The Record's Key
      * @return Whether or not the Record was deleted
      */
     boolean deleteRecord(Key key) throws DBException;
  
     /**
      * getRecordCount returns the number of Records in the Filer.
      *
      * @return The Record count
      */
     long getRecordCount() throws DBException;
  
     /**
      * getRecordSet returns a RecordSet object for the current Filer.
      *
      * @return The Filer Enumerator
      */
     RecordSet getRecordSet() throws DBException;
     
     /**
      * flush forcefully flushes any unwritten buffers to disk.
      */
     void flush() throws DBException;
  }
  
  
  
  1.1                  xml-xindice/Xindice/java/src/org/apache/xindice/core/filer/FilerException.java
  
  Index: FilerException.java
  ===================================================================
  package org.apache.xindice.core.filer;
  
  /*
   * The Apache Software License, Version 1.1
   *
   *
   * Copyright (c) 1999 The Apache Software Foundation.  All rights
   * reserved.
   *
   * Redistribution and use in source and binary forms, with or without
   * modification, are permitted provided that the following conditions
   * are met:
   *
   * 1. Redistributions of source code must retain the above copyright
   *    notice, this list of conditions and the following disclaimer.
   *
   * 2. Redistributions in binary form must reproduce the above copyright
   *    notice, this list of conditions and the following disclaimer in
   *    the documentation and/or other materials provided with the
   *    distribution.
   *
   * 3. The end-user documentation included with the redistribution,
   *    if any, must include the following acknowledgment:
   *       "This product includes software developed by the
   *        Apache Software Foundation (http://www.apache.org/)."
   *    Alternately, this acknowledgment may appear in the software itself,
   *    if and wherever such third-party acknowledgments normally appear.
   *
   * 4. The names "Xindice" and "Apache Software Foundation" must
   *    not be used to endorse or promote products derived from this
   *    software without prior written permission. For written
   *    permission, please contact apache@apache.org.
   *
   * 5. Products derived from this software may not be called "Apache",
   *    nor may "Apache" appear in their name, without prior written
   *    permission of the Apache Software Foundation.
   *
   * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
   * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
   * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
   * DISCLAIMED.  IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
   * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
   * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
   * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
   * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
   * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
   * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
   * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
   * SUCH DAMAGE.
   * ====================================================================
   *
   * This software consists of voluntary contributions made by many
   * individuals on behalf of the Apache Software Foundation and was
   * originally based on software copyright (c) 1999-2001, The dbXML
   * Group, L.L.C., http://www.dbxmlgroup.com.  For more
   * information on the Apache Software Foundation, please see
   * <http://www.apache.org/>.
   *
   * $Id: FilerException.java,v 1.1 2001/12/06 21:00:12 bradford Exp $
   */
  
  import org.apache.xindice.core.*;
  
  /**
   * A FilerException is thrown by a Filer if an exception occurs
   * in the managing of the Filer.
   */
  
  public class FilerException extends DBException {
     public FilerException(int faultCode) {
        super(faultCode);
     }
     
     public FilerException(int faultCode, String message) {
        super(faultCode, message);
     }
  }
  
  
  
  1.1                  xml-xindice/Xindice/java/src/org/apache/xindice/core/filer/HashFiler.java
  
  Index: HashFiler.java
  ===================================================================
  package org.apache.xindice.core.filer;
  
  /*
   * The Apache Software License, Version 1.1
   *
   *
   * Copyright (c) 1999 The Apache Software Foundation.  All rights
   * reserved.
   *
   * Redistribution and use in source and binary forms, with or without
   * modification, are permitted provided that the following conditions
   * are met:
   *
   * 1. Redistributions of source code must retain the above copyright
   *    notice, this list of conditions and the following disclaimer.
   *
   * 2. Redistributions in binary form must reproduce the above copyright
   *    notice, this list of conditions and the following disclaimer in
   *    the documentation and/or other materials provided with the
   *    distribution.
   *
   * 3. The end-user documentation included with the redistribution,
   *    if any, must include the following acknowledgment:
   *       "This product includes software developed by the
   *        Apache Software Foundation (http://www.apache.org/)."
   *    Alternately, this acknowledgment may appear in the software itself,
   *    if and wherever such third-party acknowledgments normally appear.
   *
   * 4. The names "Xindice" and "Apache Software Foundation" must
   *    not be used to endorse or promote products derived from this
   *    software without prior written permission. For written
   *    permission, please contact apache@apache.org.
   *
   * 5. Products derived from this software may not be called "Apache",
   *    nor may "Apache" appear in their name, without prior written
   *    permission of the Apache Software Foundation.
   *
   * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
   * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
   * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
   * DISCLAIMED.  IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
   * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
   * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
   * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
   * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
   * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
   * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
   * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
   * SUCH DAMAGE.
   * ====================================================================
   *
   * This software consists of voluntary contributions made by many
   * individuals on behalf of the Apache Software Foundation and was
   * originally based on software copyright (c) 1999-2001, The dbXML
   * Group, L.L.C., http://www.dbxmlgroup.com.  For more
   * information on the Apache Software Foundation, please see
   * <http://www.apache.org/>.
   *
   * $Id: HashFiler.java,v 1.1 2001/12/06 21:00:12 bradford Exp $
   */
  
  import org.apache.xindice.core.*;
  import org.apache.xindice.core.Collection;
  import org.apache.xindice.core.data.*;
  import org.apache.xindice.util.*;
  
  import java.io.*;
  import java.util.*;
  
  /**
   * HashFiler is a Filer implementation based on the Paged class.
   * By extending Paged, HashFiler inherits the ability to maintain
   * Record metadata such as creation and modification time.  It also
   * provides quite a bit more flexibility in its ability to retreive
   * blocks of data and allocate Record space.
   * <br><br>
   * NOTE: This class has been temporarily (maybe indefinitely)
   * deprecated by BTreeFiler.
   */
  
  public final class HashFiler extends Paged implements Configurable, Filer {
     protected static final byte RECORD = 1;
  
     private static final String PAGECOUNT = "pagecount";
     private static final String PAGESIZE = "pagesize";
     private static final String MAXKEYSIZE = "maxkeysize";
  
     private Collection collection;
     private Configuration config;
     private HashFileHeader fileHeader;
     private BTree btree;
  
     public HashFiler() {
        super();
        fileHeader = (HashFileHeader)getFileHeader();
     }
  
     public void setConfig(Configuration config) {
        this.config = config;
     }
  
     public Configuration getConfig() {
        return config;
     }
  
     public void setLocation(String location) {
        setFile(new File(collection.getCollectionRoot(), location+".tbl"));
        btree = new BTree(new File(collection.getCollectionRoot(), location+".pkx"));
     }
  
     public String getName() {
        return "HashFiler";
     }
  
     public boolean open() throws DBException {
        if ( super.open() ) {
           // These are the only properties that can be changed after creation
           fileHeader.setMaxKeySize(config.getShortAttribute(MAXKEYSIZE, fileHeader.getMaxKeySize()));
           btree.open();
           return true;
        }
        else
           return false;
     }
  
     public boolean create() throws DBException {
        fileHeader.setPageCount(config.getLongAttribute(PAGECOUNT, fileHeader.getPageCount()));
        fileHeader.setPageSize(config.getIntAttribute(PAGESIZE, fileHeader.getPageSize()));
        fileHeader.setMaxKeySize(config.getShortAttribute(MAXKEYSIZE, fileHeader.getMaxKeySize()));
        btree.create();
        return super.create();
     }
  
     public void setCollection(Collection collection) {
        this.collection = collection;
        setLocation(collection.getName());
     }
  
     private Page seekRecordPage(Key key) throws IOException {
        int hash = key.getHash();
        long pageNum = hash % fileHeader.getPageCount();
        Page p = null;
        HashPageHeader ph = null;
        while ( true ) {
           p = getPage(pageNum);
           ph = (HashPageHeader)p.getPageHeader();
           if ( ph.getStatus() == RECORD
             && ph.getKeyHash() == key.getHash()
             && p.getKey().equals(key) )
              return p;
           pageNum = ph.getNextCollision();
           if ( pageNum == -1 )
              return null;
        }
     }
  
     private Page seekInsertionPage(Key key) throws IOException {
        int hash = key.getHash();
        long pageNum = hash % fileHeader.getPageCount();
        Page p = null;
        HashPageHeader ph = null;
        while ( true ) {
           p = getPage(pageNum);
           ph = (HashPageHeader)p.getPageHeader();
           if ( ( ph.getStatus() == UNUSED || ph.getStatus() == DELETED )
             || ( ph.getStatus() == RECORD
               && ph.getKeyHash() == key.getHash()
               && p.getKey().equals(key) ) )
              return p;
           pageNum = ph.getNextCollision();
           if ( pageNum == -1 ) {
              Page np = getFreePage();
              ph.setNextCollision(np.getPageNum());
              p.write();
              return np;
           }
        }
     }
  
     public synchronized Record readRecord(Key key) throws DBException {
        checkOpened();
        try {
           Page startPage = seekRecordPage(key);
           if ( startPage != null ) {
              Value v = readValue(startPage);
              HashPageHeader sph = (HashPageHeader)startPage.getPageHeader();
              
              HashMap meta = new HashMap(2);
              meta.put(Record.CREATED, new Long(sph.getCreated()));
              meta.put(Record.MODIFIED, new Long(sph.getModified()));
              
              return new Record(key, v, meta);
           }
        }
        catch ( Exception e ) {
           org.apache.xindice.Debug.printStackTrace(e);
        }
        return null;
     }
  
     public synchronized boolean writeRecord(Key key, Value value) throws DBException {
        checkOpened();
        try {
           Page p = seekInsertionPage(key);
           HashPageHeader ph = (HashPageHeader)p.getPageHeader();
           
           long t = System.currentTimeMillis();
           if ( ph.getStatus() == UNUSED ) {
              // This is a new Record
              fileHeader.incRecordCount();
              btree.addValue(key, p.getPageNum());
              ph.setCreated(t);
           }
           
           ph.setModified(t);
           ph.setStatus(RECORD);
  
           p.setKey(key);
           writeValue(p, value);
           
           flush();
        }
        catch ( Exception e ) {
           org.apache.xindice.Debug.printStackTrace(e);
        }
        return true;
     }
  
     public synchronized boolean deleteRecord(Key key) throws DBException {
        checkOpened();
        try {
           int hash = key.getHash();
           long pageNum = hash % fileHeader.getPageCount();
           Page prev = null;
           Page page = null;
           
           HashPageHeader prevHead = null;
           HashPageHeader pageHead = null;
           
           while ( true ) {
              page = getPage(pageNum);
              pageHead = (HashPageHeader)page.getPageHeader();
              if ( pageHead.getStatus() == RECORD
                && pageHead.getKeyHash() == key.getHash()
                && page.getKey().equals(key) )
                 break;
              pageNum = pageHead.getNextCollision();
              if ( pageNum == -1 )
                 return false;
              prev = page;
              prevHead = pageHead;
           }
  
           if ( page == null )
              return false;
  
           if ( prev != null ) {
              prevHead.setNextCollision(pageHead.nextCollision);
              prev.write();
           }
           
           btree.removeValue(key);
           unlinkPages(page);
  
           fileHeader.decRecordCount();
           
           flush();
           
           return true;
        }
        catch ( Exception e ) {
           org.apache.xindice.Debug.printStackTrace(e);
        }
        return false;
     }
  
     public synchronized long getRecordCount() throws DBException {
        checkOpened();
        return fileHeader.getRecordCount();
     }
  
     public synchronized RecordSet getRecordSet() throws DBException {
        checkOpened();
        return new HashFilerRecordSet();
     }
  
     public synchronized void flush() throws DBException {
        super.flush();
     }
     
     /**
      * HashFilerRecordSet
      */
     
     private class HashFilerRecordSet implements RecordSet, BTreeCallback {
        private List keys = new ArrayList();
        private Iterator enum;
  
        public HashFilerRecordSet() {
           try {
              btree.query(null, this);
              enum = keys.iterator();
           }
           catch ( Exception e ) {
              org.apache.xindice.Debug.printStackTrace(e);
           }
        }
  
        public boolean indexInfo(Value value, long pointer) {
           keys.add(new Key(value));
           return true;
        }
  
        public Key getNextKey() {
           return (Key)enum.next();
        }
  
        public Record getNextRecord() throws DBException {
           return readRecord((Key)enum.next());
        }
  
        public Value getNextValue() throws DBException {
           return getNextRecord().getValue();
        }
  
        public boolean hasMoreRecords() {
           return enum.hasNext();
        }
     }
  
     ////////////////////////////////////////////////////////////////////
  
     public FileHeader createFileHeader() {
        return new HashFileHeader();
     }
  
     public FileHeader createFileHeader(boolean read) throws IOException {
        return new HashFileHeader(read);
     }
  
     public FileHeader createFileHeader(long pageCount) {
        return new HashFileHeader(pageCount);
     }
  
     public FileHeader createFileHeader(long pageCount, int pageSize) {
        return new HashFileHeader(pageCount, pageSize);
     }
  
     public PageHeader createPageHeader() {
        return new HashPageHeader();
     }
  
  
     /**
      * HashFileHeader
      */
  
     private final class HashFileHeader extends FileHeader {
        private long totalBytes = 0;
  
        public HashFileHeader() {
        }
  
        public HashFileHeader(long pageCount) {
           super(pageCount);
        }
  
        public HashFileHeader(long pageCount, int pageSize) {
           super(pageCount, pageSize);
        }
  
        public HashFileHeader(boolean read) throws IOException {
           super(read);
        }
  
        public void read(RandomAccessFile raf) throws IOException {
           super.read(raf);
           totalBytes = raf.readLong();
        }
  
        public void write(RandomAccessFile raf) throws IOException {
           super.write(raf);
           raf.writeLong(totalBytes);
        }
  
        /** The total number of bytes in use by the file */
        public void setTotalBytes(long totalBytes) {
           this.totalBytes = totalBytes;
           setDirty();
        }
  
        /** The total number of bytes in use by the file */
        public long getTotalBytes() {
           return totalBytes;
        }
     }
  
     /**
      * HashPageHeader
      */
  
     private final class HashPageHeader extends PageHeader {
        private long created = 0;
        private long modified = 0;
        private long nextCollision = -1;
  
        public HashPageHeader() {
        }
  
        public HashPageHeader(DataInputStream dis) throws IOException {
           super(dis);
        }
  
        public void read(DataInputStream dis) throws IOException {
           super.read(dis);
  
           if ( getStatus() == UNUSED )
              return;
  
           created = dis.readLong();
           modified = dis.readLong();
           nextCollision = dis.readLong();
        }
  
        public void write(DataOutputStream dos) throws IOException {
           super.write(dos);
           dos.writeLong(created);
           dos.writeLong(modified);
           dos.writeLong(nextCollision);
        }
  
        public void setRecordLen(int recordLen) {
           synchronized(fileHeader) {
              fileHeader.setTotalBytes((fileHeader.totalBytes - getRecordLen()) + recordLen);
           }
           super.setRecordLen(recordLen);
        }
  
        /** UNIX-time when this record was created */
        public void setCreated(long created) {
           this.created = created;
           setDirty();
        }
  
        /** UNIX-time when this record was created */
        public long getCreated() {
           return created;
        }
  
        /** UNIX-time when this record was last modified */
        public void setModified(long modified) {
           this.modified = modified;
           setDirty();
        }
  
        /** UNIX-time when this record was last modified */
        public long getModified() {
           return modified;
        }
  
        /** The next page for a Record collision (if any) */
        public void setNextCollision(long nextCollision) {
           this.nextCollision = nextCollision;
           setDirty();
        }
  
        /** The next page for a Record collision (if any) */
        public long getNextCollision() {
           return nextCollision;
        }
     }
  }
  
  
  
  
  
  
  
  
  
  
  
  
  1.1                  xml-xindice/Xindice/java/src/org/apache/xindice/core/filer/MemFiler.java
  
  Index: MemFiler.java
  ===================================================================
  package org.apache.xindice.core.filer;
  
  /*
   * The Apache Software License, Version 1.1
   *
   *
   * Copyright (c) 1999 The Apache Software Foundation.  All rights
   * reserved.
   *
   * Redistribution and use in source and binary forms, with or without
   * modification, are permitted provided that the following conditions
   * are met:
   *
   * 1. Redistributions of source code must retain the above copyright
   *    notice, this list of conditions and the following disclaimer.
   *
   * 2. Redistributions in binary form must reproduce the above copyright
   *    notice, this list of conditions and the following disclaimer in
   *    the documentation and/or other materials provided with the
   *    distribution.
   *
   * 3. The end-user documentation included with the redistribution,
   *    if any, must include the following acknowledgment:
   *       "This product includes software developed by the
   *        Apache Software Foundation (http://www.apache.org/)."
   *    Alternately, this acknowledgment may appear in the software itself,
   *    if and wherever such third-party acknowledgments normally appear.
   *
   * 4. The names "Xindice" and "Apache Software Foundation" must
   *    not be used to endorse or promote products derived from this
   *    software without prior written permission. For written
   *    permission, please contact apache@apache.org.
   *
   * 5. Products derived from this software may not be called "Apache",
   *    nor may "Apache" appear in their name, without prior written
   *    permission of the Apache Software Foundation.
   *
   * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
   * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
   * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
   * DISCLAIMED.  IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
   * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
   * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
   * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
   * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
   * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
   * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
   * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
   * SUCH DAMAGE.
   * ====================================================================
   *
   * This software consists of voluntary contributions made by many
   * individuals on behalf of the Apache Software Foundation and was
   * originally based on software copyright (c) 1999-2001, The dbXML
   * Group, L.L.C., http://www.dbxmlgroup.com.  For more
   * information on the Apache Software Foundation, please see
   * <http://www.apache.org/>.
   *
   * $Id: MemFiler.java,v 1.1 2001/12/06 21:00:12 bradford Exp $
   */
  
  import org.apache.xindice.core.*;
  import org.apache.xindice.core.Collection;
  import org.apache.xindice.core.data.*;
  import org.apache.xindice.util.*;
  
  import java.util.*;
  
  /**
   * MemFiler is an In-Memory Filer implementation for Xindice.  MemFiler can be
   * used for temporary collections and caching.  It's basically a layering on
   * top of HashMap.
   */
  
  public final class MemFiler extends SimpleConfigurable implements Filer {
     private Map hashTable = null;
     private boolean opened = false;
     private boolean readOnly = false;
     private Collection collection;
  
     public MemFiler() {
        hashTable = Collections.synchronizedMap(new HashMap());
     }
  
     public MemFiler(Map hashTable, boolean readOnly) {
        this.hashTable = hashTable;
        this.readOnly = readOnly;
     }
     
     public MemFiler(Map hashTable) {
        this(hashTable, false);
     }
     
     public void setCollection(Collection collection) {
        this.collection = collection;
     }
  
     public String getName() {
        return "MemFiler";
     }
  
     private void checkOpened() throws DBException {
        if ( !opened )
           throw new FilerException(FaultCodes.COL_COLLECTION_CLOSED, "Filer is closed");
     }
  
     private void checkReadOnly() throws DBException {
        if ( readOnly )
           throw new FilerException(FaultCodes.COL_COLLECTION_READ_ONLY, "Filer is read-only");
     }
     
     public boolean create() {
        hashTable.clear();
        return true;
     }
  
     public boolean open() {
        opened = true;
        return opened;
     }
  
     public boolean isOpened() {
        return opened;
     }
  
     public boolean exists() {
        return true;
     }
  
     public boolean drop() {
        hashTable.clear();
        opened = false;
        return !opened;
     }
  
     public boolean close() {
        opened = false;
        return !opened;
     }
     
     public void flush() {
     }
     
     public Record readRecord(Key key) throws DBException {
        checkOpened();
        return(Record)hashTable.get(key);
     }
  
     public boolean writeRecord(Key key, Value value) throws DBException {
        checkOpened();
        checkReadOnly();
        hashTable.put(key, new Record(key, value));
        return true;
     }
  
     public boolean deleteRecord(Key key) throws DBException {
        checkOpened();
        checkReadOnly();
        return hashTable.remove(key) != null;
     }
  
     public long getRecordCount() throws DBException {
        checkOpened();
        return hashTable.size();
     }
  
     public RecordSet getRecordSet() throws DBException {
        checkOpened();
        return new MemRecordSet();
     }
  
     
     /**
      * MemRecordSet
      */
     
     private class MemRecordSet implements RecordSet {
        private Iterator enum = hashTable.values().iterator();
  
        public boolean hasMoreRecords() throws DBException {
           return enum.hasNext();
        }
  
        public Record getNextRecord() throws DBException {
           checkOpened();
           return(Record)enum.next();
        }
  
        public Value getNextValue() throws DBException {
           checkOpened();
           return((Record)enum.next()).getValue();
        }
        
        public Key getNextKey() {
           return((Record)enum.next()).getKey();
        }
     }
  }
  
  
  
  
  
  1.1                  xml-xindice/Xindice/java/src/org/apache/xindice/core/filer/Paged.java
  
  Index: Paged.java
  ===================================================================
  package org.apache.xindice.core.filer;
  
  /*
   * The Apache Software License, Version 1.1
   *
   *
   * Copyright (c) 1999 The Apache Software Foundation.  All rights
   * reserved.
   *
   * Redistribution and use in source and binary forms, with or without
   * modification, are permitted provided that the following conditions
   * are met:
   *
   * 1. Redistributions of source code must retain the above copyright
   *    notice, this list of conditions and the following disclaimer.
   *
   * 2. Redistributions in binary form must reproduce the above copyright
   *    notice, this list of conditions and the following disclaimer in
   *    the documentation and/or other materials provided with the
   *    distribution.
   *
   * 3. The end-user documentation included with the redistribution,
   *    if any, must include the following acknowledgment:
   *       "This product includes software developed by the
   *        Apache Software Foundation (http://www.apache.org/)."
   *    Alternately, this acknowledgment may appear in the software itself,
   *    if and wherever such third-party acknowledgments normally appear.
   *
   * 4. The names "Xindice" and "Apache Software Foundation" must
   *    not be used to endorse or promote products derived from this
   *    software without prior written permission. For written
   *    permission, please contact apache@apache.org.
   *
   * 5. Products derived from this software may not be called "Apache",
   *    nor may "Apache" appear in their name, without prior written
   *    permission of the Apache Software Foundation.
   *
   * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
   * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
   * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
   * DISCLAIMED.  IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
   * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
   * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
   * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
   * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
   * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
   * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
   * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
   * SUCH DAMAGE.
   * ====================================================================
   *
   * This software consists of voluntary contributions made by many
   * individuals on behalf of the Apache Software Foundation and was
   * originally based on software copyright (c) 1999-2001, The dbXML
   * Group, L.L.C., http://www.dbxmlgroup.com.  For more
   * information on the Apache Software Foundation, please see
   * <http://www.apache.org/>.
   *
   * $Id: Paged.java,v 1.1 2001/12/06 21:00:12 bradford Exp $
   */
  
  import org.apache.xindice.util.*;
  import org.apache.xindice.core.*;
  import org.apache.xindice.core.data.*;
  
  import java.io.*;
  import java.util.*;
  
  /**
   * Paged is a paged file foundation that is used by both the BTree
   * class and the HashFiler.  It provides flexible paged I/O and
   * page caching functionality.
   */
  
  public abstract class Paged {
     private static final int MAX_DIRTY_SIZE = 128;
     
     protected static final byte UNUSED = 0;
     protected static final byte OVERFLOW = 126;
     protected static final byte DELETED = 127;
  
     private Map pages = new WeakHashMap();
     private Map dirty = new HashMap();
     
     private File file;
     private RandomAccessFile raf;
     private boolean opened = false;
     private FileHeader fileHeader;
  
     public Paged() {
        fileHeader = createFileHeader();
     }
  
     public Paged(File file) {
        this();
        setFile(file);
     }
  
     /**
      * setFile sets the file object for this Paged.
      *
      * @param file The File
      */
     protected final void setFile(final File file) {
        this.file = file;
     }
  
     /**
      * getFile returns the file object for this Paged.
      *
      * @return The File
      */
     protected final File getFile() {
        return file;
     }
  
     /**
      * getPage returns the page specified by pageNum.
      *
      * @param lp The Page number
      * @return The requested Page
      * @throws IOException if an Exception occurs
      */
     protected final Page getPage(Long lp) throws IOException {
        Page p = (Page)dirty.get(lp); // Check if it's in the dirty stash
        if ( p == null )
           p = (Page)pages.get(lp);   // Check if it's in the volatile cache
        if ( p == null ) {
           p = new Page(lp.longValue());
           p.read();
           pages.put(lp, p);
        }
        return p;
     }
     
     /**
      * getPage returns the page specified by pageNum.
      *
      * @param pageNum The Page number
      * @return The requested Page
      * @throws IOException if an Exception occurs
      */
     protected final Page getPage(long pageNum) throws IOException {
        return getPage(new Long(pageNum));
     }
     
     /**
      * readValue reads the multi-Paged Value starting at the specified
      * Page.
      *
      * @param page The starting Page
      * @return The Value
      * @throws IOException if an Exception occurs
      */
     protected final Value readValue(Page page) throws IOException {
        PageHeader sph = page.getPageHeader();
        ByteArrayOutputStream bos = new ByteArrayOutputStream((int)sph.getRecordLen());
        Page p = page;
        PageHeader ph = null;
        long nextPage;
        while ( true ) {
           ph = p.getPageHeader();
           p.streamTo(bos);
           nextPage = ph.getNextPage();
           if ( nextPage != -1 )
              p = getPage(nextPage);
           else
              break;
        }
        return new Value(bos.toByteArray());
     }
  
     /**
      * readValue reads the multi-Paged Value starting at the specified
      * page number.
      *
      * @param page The starting page number
      * @return The Value
      * @throws IOException if an Exception occurs
      */
     protected final Value readValue(long page) throws IOException {
        return readValue(getPage(page));
     }
  
     /**
      * writeValue writes the multi-Paged Value starting at the specified
      * Page.
      *
      * @param page The starting Page
      * @param value The Value to write
      * @throws IOException if an Exception occurs
      */
     protected final void writeValue(Page page, Value value) throws IOException {
        InputStream is = value.getInputStream();
  
        PageHeader hdr = page.getPageHeader();
        hdr.setRecordLen(value.getLength());
        page.streamFrom(is);
  
        // Write out the rest of the value
        while ( is.available() > 0 ) {
           Page lpage = page;
           PageHeader lhdr = hdr;
  
           long np = lhdr.getNextPage();
           if ( np != -1 )
              page = getPage(np);
           else {
              page = getFreePage();
              lhdr.setNextPage(page.getPageNum());
           }
  
           hdr = page.getPageHeader();
           hdr.setStatus(OVERFLOW);
           page.streamFrom(is);
  
           lpage.write();
        }
  
        long np = hdr.getNextPage();
        if ( np != -1 )
           unlinkPages(np);
        hdr.setNextPage(-1);
        page.write();
     }
  
     /**
      * writeValue writes the multi-Paged Value starting at the specified
      * page number.
      *
      * @param page The starting page number
      * @param value The Value to write
      * @throws IOException if an Exception occurs
      */
     protected final void writeValue(long page, Value value) throws IOException {
        writeValue(getPage(page), value);
     }
  
     /**
      * unlinkPages unlinks a set of pages starting at the specified Page.
      *
      * @param page The starting Page to unlink
      * @throws IOException if an Exception occurs
      */
     protected final void unlinkPages(Page page) throws IOException {
        // If the page is in primary space, just reset it's
        // status.  If it's in overflow, add it to the unused list.
        if ( page.pageNum < fileHeader.pageCount ) {
           long nextPage = page.header.nextPage;
           page.header.setStatus(DELETED);
           page.header.setNextPage(-1);
           page.write();
           page = nextPage != -1 ? getPage(nextPage)
                                 : null;
        }
  
        if ( page != null ) {
           // Walk the chain and add it to the unused list
           long firstPage = page.pageNum;
           while ( page.header.nextPage != -1 )
              page = getPage(page.header.nextPage);
           long lastPage = page.pageNum;
  
           if ( fileHeader.lastFreePage != -1 ) {
              Page p = getPage(fileHeader.lastFreePage);
              p.header.setNextPage(firstPage);
              p.write();
           }
           if ( fileHeader.firstFreePage == -1 )
              fileHeader.setFirstFreePage(firstPage);
           fileHeader.setLastFreePage(lastPage);
        }
     }
  
     /**
      * unlinkPages unlinks a set of pages starting at the specified
      * page number.
      *
      * @param page The starting page number to unlink
      * @throws IOException if an Exception occurs
      */
     protected final void unlinkPages(long pageNum) throws IOException {
        unlinkPages(getPage(pageNum));
     }
  
     /**
      * getFreePage returns the first free Page from secondary storage.
      * If no Pages are available, the file is grown as appropriate.
      *
      * @return The next free Page
      * @throws IOException if an Exception occurs
      */
     protected final Page getFreePage() throws IOException {
        Page p = null;
        long pageNum = fileHeader.firstFreePage;
        if ( pageNum != -1 ) {
           // Steal a deleted page
           p = getPage(pageNum);
           fileHeader.setFirstFreePage(p.getPageHeader().nextPage);
           if ( fileHeader.firstFreePage == -1 )
              fileHeader.setLastFreePage(-1);
        }
        else {
           // Grow the file
           pageNum = fileHeader.totalCount;
           fileHeader.setTotalCount(pageNum+1);
           p = getPage(pageNum);
        }
  
        // Initialize The Page Header (Cleanly)
        p.header.setNextPage(-1);
        p.header.setStatus(UNUSED);
        return p;
     }
  
     protected final void checkOpened() throws DBException {
        if ( !opened )
           throw new FilerException(FaultCodes.COL_COLLECTION_CLOSED, "Filer is closed");
     }
     
     /**
      * getFileHeader returns the FileHeader
      *
      * @return The FileHeader
      */
     public FileHeader getFileHeader() {
        return fileHeader;
     }
  
     public boolean exists() {
        return file.exists();
     }
  
     public boolean create() throws DBException {
        try {
           raf = new RandomAccessFile(file, "rw");
           fileHeader.write();
           return true;
        }
        catch ( Exception e ) {
           throw new FilerException(FaultCodes.GEN_CRITICAL_ERROR, "Error creating "+file.getName());
        }
     }
  
     public boolean open() throws DBException {
        try {
           if ( exists() ) {
              raf = new RandomAccessFile(file, "rw");
              fileHeader.read();
              opened = true;
           }
           else
              opened = false;
           return opened;
        }
        catch ( Exception e ) {
           throw new FilerException(FaultCodes.GEN_CRITICAL_ERROR, "Error opening "+file.getName());
        }
     }
  
     public boolean close() throws DBException {
        try {
           if ( isOpened() ) {
              opened = false;
              raf.close();
              return true;
           }
           else
              return false;
        }
        catch ( Exception e ) {
           throw new FilerException(FaultCodes.GEN_CRITICAL_ERROR, "Error closing "+file.getName());
        }
     }
  
     public boolean isOpened() {
        return opened;
     }
  
     public boolean drop() throws DBException {
        try {
           close();
           if ( exists() )
              return getFile().delete();
           else
              return true;
        }
        catch ( Exception e ) {
           throw new FilerException(FaultCodes.COL_CANNOT_DROP, "Can't drop "+file.getName());
        }
     }
  
     public void flush() throws DBException {
        // TODO: Clean up this code
        Iterator i = dirty.values().iterator();
        boolean error = false;
        while ( i.hasNext() ) {
           Page p = (Page)i.next();
           try {
              p.flush();
           }
           catch ( Exception e ) {
              error = true;
           }
        }
        dirty.clear();
  
        if ( fileHeader.dirty ) {
           try {
              fileHeader.write();
           }
           catch ( Exception e ) {
              error = true;
           }
        }
        
        if ( error )
           throw new FilerException(FaultCodes.GEN_CRITICAL_ERROR, "Error performing flush!");
     }
     
     
     /**
      * createFileHeader must be implemented by a Paged implementation
      * in order to create an appropriate subclass instance of a FileHeader.
      *
      * @return a new FileHeader
      */
     public abstract FileHeader createFileHeader();
  
     /**
      * createFileHeader must be implemented by a Paged implementation
      * in order to create an appropriate subclass instance of a FileHeader.
      *
      * @param read If true, reads the FileHeader from disk
      * @return a new FileHeader
      * @throws IOException if an exception occurs
      */
     public abstract FileHeader createFileHeader(boolean read) throws IOException;
  
     /**
      * createFileHeader must be implemented by a Paged implementation
      * in order to create an appropriate subclass instance of a FileHeader.
      *
      * @param pageCount The number of pages to allocate for primary storage
      * @return a new FileHeader
      */
     public abstract FileHeader createFileHeader(long pageCount);
  
     /**
      * createFileHeader must be implemented by a Paged implementation
      * in order to create an appropriate subclass instance of a FileHeader.
      *
      * @param pageCount The number of pages to allocate for primary storage
      * @param pageSize The size of a Page (should be a multiple of a FS block)
      * @return a new FileHeader
      */
     public abstract FileHeader createFileHeader(long pageCount, int pageSize);
  
     /**
      * createPageHeader must be implemented by a Paged implementation
      * in order to create an appropriate subclass instance of a PageHeader.
      *
      * @return a new PageHeader
      */
     public abstract PageHeader createPageHeader();
  
  
     // These are a bunch of utility methods for subclasses
  
     public static Value[] insertArrayValue(Value[] vals, Value val, int idx) {
        Value[] newVals = new Value[vals.length+1];
        if ( idx > 0 )
           System.arraycopy(vals, 0, newVals, 0, idx);
        newVals[idx] = val;
        if ( idx < vals.length )
           System.arraycopy(vals, idx, newVals, idx+1, vals.length-idx);
        return newVals;
     }
  
     public static Value[] deleteArrayValue(Value[] vals, int idx) {
        Value[] newVals = new Value[vals.length-1];
        if ( idx > 0 )
           System.arraycopy(vals, 0, newVals, 0, idx);
        if ( idx < newVals.length)
           System.arraycopy(vals, idx+1, newVals, idx, newVals.length-idx);
        return newVals;
     }
  
     public static long[] insertArrayLong(long[] vals, long val, int idx) {
        long[] newVals = new long[vals.length+1];
        if ( idx > 0 )
           System.arraycopy(vals, 0, newVals, 0, idx);
        newVals[idx] = val;
        if ( idx < vals.length )
           System.arraycopy(vals, idx, newVals, idx+1, vals.length-idx);
        return newVals;
     }
  
     public static long[] deleteArrayLong(long[] vals, int idx) {
        long[] newVals = new long[vals.length-1];
        if ( idx > 0 )
           System.arraycopy(vals, 0, newVals, 0, idx);
        if ( idx < newVals.length)
           System.arraycopy(vals, idx+1, newVals, idx, newVals.length-idx);
        return newVals;
     }
  
     public static int[] insertArrayInt(int[] vals, int val, int idx) {
        int[] newVals = new int[vals.length+1];
        if ( idx > 0 )
           System.arraycopy(vals, 0, newVals, 0, idx);
        newVals[idx] = val;
        if ( idx < vals.length )
           System.arraycopy(vals, idx, newVals, idx+1, vals.length-idx);
        return newVals;
     }
  
     public static int[] deleteArrayInt(int[] vals, int idx) {
        int[] newVals = new int[vals.length-1];
        if ( idx > 0 )
           System.arraycopy(vals, 0, newVals, 0, idx);
        if ( idx < newVals.length)
           System.arraycopy(vals, idx+1, newVals, idx, newVals.length-idx);
        return newVals;
     }
  
     public static short[] insertArrayShort(short[] vals, short val, int idx) {
        short[] newVals = new short[vals.length+1];
        if ( idx > 0 )
           System.arraycopy(vals, 0, newVals, 0, idx);
        newVals[idx] = val;
        if ( idx < vals.length )
           System.arraycopy(vals, idx, newVals, idx+1, vals.length-idx);
        return newVals;
     }
  
     public static short[] deleteArrayShort(short[] vals, int idx) {
        short[] newVals = new short[vals.length-1];
        if ( idx > 0 )
           System.arraycopy(vals, 0, newVals, 0, idx);
        if ( idx < newVals.length)
           System.arraycopy(vals, idx+1, newVals, idx, newVals.length-idx);
        return newVals;
     }
  
  
     /**
      * FileHeader
      */
  
     public abstract class FileHeader {
        private boolean dirty = false;
        private int workSize;
  
        private short headerSize;
        private int pageSize;
        private long pageCount;
        private long totalCount;
        private long firstFreePage = -1;
        private long lastFreePage = -1;
        private byte pageHeaderSize = 64;
        private short maxKeySize = 256;
        private long recordCount;
  
        public FileHeader() {
           this(1024);
        }
  
        public FileHeader(long pageCount) {
           this(pageCount, 4096);
        }
  
        public FileHeader(long pageCount, int pageSize) {
           this.pageSize = pageSize;
           this.pageCount = pageCount;
           totalCount = pageCount;
           headerSize = (short)4096;
           calculateWorkSize();
        }
  
        public FileHeader(boolean read) throws IOException {
           if ( read )
              read();
        }
  
        public final void read() throws IOException {
           raf.seek(0);
           read(raf);
           calculateWorkSize();
        }
  
        public void read(RandomAccessFile raf) throws IOException {
           headerSize = raf.readShort();
           pageSize = raf.readInt();
           pageCount = raf.readLong();
           totalCount = raf.readLong();
           firstFreePage = raf.readLong();
           lastFreePage = raf.readLong();
           pageHeaderSize = raf.readByte();
           maxKeySize = raf.readShort();
           recordCount = raf.readLong();
        }
  
        public final void write() throws IOException {
           if ( !dirty )
              return;
           
           raf.seek(0);
           write(raf);
           dirty = false;
        }
  
        public void write(RandomAccessFile raf) throws IOException {
           raf.writeShort(headerSize);
           raf.writeInt(pageSize);
           raf.writeLong(pageCount);
           raf.writeLong(totalCount);
           raf.writeLong(firstFreePage);
           raf.writeLong(lastFreePage);
           raf.writeByte(pageHeaderSize);
           raf.writeShort(maxKeySize);
           raf.writeLong(recordCount);
        }
  
        public final void setDirty() {
           dirty = true;
        }
  
        public final boolean isDirty() {
           return dirty;
        }
  
        /** The size of the FileHeader.  Usually 1 OS Page */
        public final void setHeaderSize(short headerSize) {
           this.headerSize = headerSize;
           dirty = true;
        }
  
        /** The size of the FileHeader.  Usually 1 OS Page */
        public final short getHeaderSize() {
           return headerSize;
        }
  
        /** The size of a page.  Usually a multiple of a FS block */
        public final void setPageSize(int pageSize) {
           this.pageSize = pageSize;
           calculateWorkSize();
           dirty = true;
        }
  
        /** The size of a page.  Usually a multiple of a FS block */
        public final int getPageSize() {
           return pageSize;
        }
  
        /** The number of pages in primary storage */
        public final void setPageCount(long pageCount) {
           this.pageCount = pageCount;
           dirty = true;
        }
  
        /** The number of pages in primary storage */
        public final long getPageCount() {
           return pageCount;
        }
  
        /** The number of total pages in the file */
        public final void setTotalCount(long totalCount) {
           this.totalCount = totalCount;
           dirty = true;
        }
  
        /** The number of total pages in the file */
        public final long getTotalCount() {
           return totalCount;
        }
  
        /** The first free page in unused secondary space */
        public final void setFirstFreePage(long firstFreePage) {
           this.firstFreePage = firstFreePage;
           dirty = true;
        }
  
        /** The first free page in unused secondary space */
        public final long getFirstFreePage() {
           return firstFreePage;
        }
  
        /** The last free page in unused secondary space */
        public final void setLastFreePage(long lastFreePage) {
           this.lastFreePage = lastFreePage;
           dirty = true;
        }
  
        /** The last free page in unused secondary space */
        public final long getLastFreePage() {
           return lastFreePage;
        }
  
        /** The size of a page header. 64 is sufficient */
        public final void setPageHeaderSize(byte pageHeaderSize) {
           this.pageHeaderSize = pageHeaderSize;
           calculateWorkSize();
           dirty = true;
        }
  
        /** The size of a page header. 64 is sufficient */
        public final byte getPageHeaderSize() {
           return pageHeaderSize;
        }
  
        /** The maximum number of bytes a key can be.  256 is good */
        public final void setMaxKeySize(short maxKeySize) {
           this.maxKeySize = maxKeySize;
           dirty = true;
        }
  
        /** The maximum number of bytes a key can be.  256 is good */
        public final short getMaxKeySize() {
           return maxKeySize;
        }
  
        /** The number of records being managed by the file (not pages) */
        public final void setRecordCount(long recordCount) {
           this.recordCount = recordCount;
           dirty = true;
        }
  
        /** Increment the number of records being managed by the file */
        public final void incRecordCount() {
           recordCount++;
           dirty = true;
        }
  
        /** Decrement the number of records being managed by the file */
        public final void decRecordCount() {
           recordCount--;
           dirty = true;
        }
  
        /** The number of records being managed by the file (not pages) */
        public final long getRecordCount() {
           return recordCount;
        }
  
        private void calculateWorkSize() {
           workSize = pageSize - pageHeaderSize;
        }
  
        public final int getWorkSize() {
           return workSize;
        }
     }
  
     /**
      * PageHeader
      */
  
     public abstract class PageHeader implements Streamable {
        private boolean dirty = false;
        private byte status = UNUSED;
        private short keyLen = 0;
        private int keyHash = 0;
        private int dataLen = 0;
        private int recordLen = 0;
        private long nextPage = -1;
  
        public PageHeader() {
        }
  
        public PageHeader(DataInputStream dis) throws IOException {
           read(dis);
        }
  
        public void read(DataInputStream dis) throws IOException {
           status = dis.readByte();
           dirty = false;
           
           if ( status == UNUSED )
              return;
  
           keyLen = dis.readShort();
           keyHash = dis.readInt();
           dataLen = dis.readInt();
           recordLen = dis.readInt();
           nextPage = dis.readLong();
        }
  
        public void write(DataOutputStream dos) throws IOException {
           dirty = false;
           dos.writeByte(status);
           dos.writeShort(keyLen);
           dos.writeInt(keyHash);
           dos.writeInt(dataLen);
           dos.writeInt(recordLen);
           dos.writeLong(nextPage);
        }
  
        public final boolean isDirty() {
           return dirty;
        }
        
        public final void setDirty() {
           dirty = true;
        }
        
        /** The status of this page (UNUSED, RECORD, DELETED, etc...) */
        public final void setStatus(byte status) {
           this.status = status;
           dirty = true;
        }
  
        /** The status of this page (UNUSED, RECORD, DELETED, etc...) */
        public final byte getStatus() {
           return status;
        }
  
        public final void setKey(Key key) {
           // setKey WIPES OUT the Page data
           setRecordLen(0);
           dataLen = 0;
           keyHash = key.getHash();
           keyLen = (short)key.getLength();
           dirty = true;
        }
  
        /** The length of the Key */
        public final void setKeyLen(short keyLen) {
           this.keyLen = keyLen;
           dirty = true;
        }
  
        /** The length of the Key */
        public final short getKeyLen() {
           return keyLen;
        }
  
        /** The hashed value of the Key for quick comparisons */
        public final void setKeyHash(int keyHash) {
           this.keyHash = keyHash;
           dirty = true;
        }
  
        /** The hashed value of the Key for quick comparisons */
        public final int getKeyHash() {
           return keyHash;
        }
  
        /** The length of the Data */
        public final void setDataLen(int dataLen) {
           this.dataLen = dataLen;
           dirty = true;
        }
  
        /** The length of the Data */
        public final int getDataLen() {
           return dataLen;
        }
  
        /** The length of the Record's value */
        public void setRecordLen(int recordLen) {
           this.recordLen = recordLen;
           dirty = true;
        }
  
        /** The length of the Record's value */
        public final int getRecordLen() {
           return recordLen;
        }
  
        /** The next page for this Record (if overflowed) */
        public final void setNextPage(long nextPage) {
           this.nextPage = nextPage;
           dirty = true;
        }
  
        /** The next page for this Record (if overflowed) */
        public final long getNextPage() {
           return nextPage;
        }
     }
  
     /**
      * Page
      */
  
     public final class Page implements Comparable {
        /** This page number */
        private long pageNum;
  
        /** The data for this page */
        private byte[] data;
  
        /** The Header for this Page */
        private PageHeader header = createPageHeader();
  
        /** The position (relative) of the Key in the data array */
        private int keyPos;
  
        /** The position (relative) of the Data in the data array */
        private int dataPos;
  
        /** The offset into the file that this page starts */
        private long offset;
  
        public Page() {
        }
  
        public Page(long pageNum) throws IOException {
           this();
           setPageNum(pageNum);
        }
  
        public void read() throws IOException {
           Page page = null;
           data = new byte[fileHeader.pageSize];
  
           raf.seek(offset);
           raf.read(data);
           
           ByteArrayInputStream bis = new ByteArrayInputStream(data);
           DataInputStream dis = new DataInputStream(bis);
  
           // Read in the header
           header.read(dis);
  
           keyPos = fileHeader.pageHeaderSize;
           dataPos = keyPos + header.keyLen;
        }
  
        public void write() throws IOException {
           // Write out the header
           ByteArrayOutputStream bos = new ByteArrayOutputStream(fileHeader.getPageHeaderSize());
           DataOutputStream dos = new DataOutputStream(bos);
           header.write(dos);
           byte[] b = bos.toByteArray();
           System.arraycopy(b, 0, data, 0, b.length);
  
           dirty.put(new Long(pageNum), this);
           if ( dirty.size() > MAX_DIRTY_SIZE ) {
              try {
                 // Too many dirty pages... flush them
                 Paged.this.flush();
              }
              catch ( Exception e ) {
                 throw new IOException(e.getMessage());
              }
           }
        }
  
        public void flush() throws IOException {
           if ( offset >= raf.length() ) {
              // Grow the file
              long o = (fileHeader.headerSize + ((fileHeader.totalCount*3)/2)*fileHeader.pageSize)+(fileHeader.pageSize-1);
              raf.seek(o);
              raf.writeByte(0);
           }
           raf.seek(offset);
           raf.write(data);
        }
        
        public void setPageNum(long pageNum) {
           this.pageNum = pageNum;
           offset = fileHeader.headerSize + (pageNum * fileHeader.pageSize);
        }
  
        public long getPageNum() {
           return pageNum;
        }
  
        public PageHeader getPageHeader() {
           return header;
        }
  
        public void setKey(Key key) {
           header.setKey(key);
           key.copyTo(data, keyPos);
        }
  
        public Key getKey() {
           if ( header.keyLen > 0 )
              return new Key(data, keyPos, header.keyLen);
           else
              return null;
        }
  
        public void streamTo(OutputStream os) throws IOException {
           if ( header.dataLen > 0 )
              os.write(data, dataPos, header.dataLen);
        }
  
        public void streamFrom(InputStream is) throws IOException {
           int avail = is.available();
           header.dataLen = fileHeader.workSize - header.keyLen;
           if ( avail < header.dataLen )
              header.dataLen = avail;
           if ( header.dataLen > 0 )
              is.read(data, keyPos + header.keyLen, header.dataLen);
        }
        
        public int compareTo(Object o) {
           return (int)(pageNum - ((Page)o).pageNum);
        }
     }
  }
  
  
  
  
  1.1                  xml-xindice/Xindice/java/src/org/apache/xindice/core/filer/Streamable.java
  
  Index: Streamable.java
  ===================================================================
  package org.apache.xindice.core.filer;
  
  /*
   * The Apache Software License, Version 1.1
   *
   *
   * Copyright (c) 1999 The Apache Software Foundation.  All rights
   * reserved.
   *
   * Redistribution and use in source and binary forms, with or without
   * modification, are permitted provided that the following conditions
   * are met:
   *
   * 1. Redistributions of source code must retain the above copyright
   *    notice, this list of conditions and the following disclaimer.
   *
   * 2. Redistributions in binary form must reproduce the above copyright
   *    notice, this list of conditions and the following disclaimer in
   *    the documentation and/or other materials provided with the
   *    distribution.
   *
   * 3. The end-user documentation included with the redistribution,
   *    if any, must include the following acknowledgment:
   *       "This product includes software developed by the
   *        Apache Software Foundation (http://www.apache.org/)."
   *    Alternately, this acknowledgment may appear in the software itself,
   *    if and wherever such third-party acknowledgments normally appear.
   *
   * 4. The names "Xindice" and "Apache Software Foundation" must
   *    not be used to endorse or promote products derived from this
   *    software without prior written permission. For written
   *    permission, please contact apache@apache.org.
   *
   * 5. Products derived from this software may not be called "Apache",
   *    nor may "Apache" appear in their name, without prior written
   *    permission of the Apache Software Foundation.
   *
   * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
   * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
   * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
   * DISCLAIMED.  IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
   * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
   * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
   * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
   * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
   * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
   * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
   * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
   * SUCH DAMAGE.
   * ====================================================================
   *
   * This software consists of voluntary contributions made by many
   * individuals on behalf of the Apache Software Foundation and was
   * originally based on software copyright (c) 1999-2001, The dbXML
   * Group, L.L.C., http://www.dbxmlgroup.com.  For more
   * information on the Apache Software Foundation, please see
   * <http://www.apache.org/>.
   *
   * $Id: Streamable.java,v 1.1 2001/12/06 21:00:12 bradford Exp $
   */
  
  import java.io.*;
  
  /**
   * Streamable is an interface implemented by objects used by Filers and
   * Indexers in order to serialize objects to and from IO streams.
   */
  
  public interface Streamable {
     /**
      * read reads the object state from the stream.
      *
      * @param is The DataInputStream
      * @throws IOException if an IOException occurs
      */
     public void read(DataInputStream is) throws IOException;
  
     /**
      * write writes the object state to the stream.
      *
      * @param os The DataOutputStream
      * @throws IOException if an IOException occurs
      */
     public void write(DataOutputStream os) throws IOException;
  }
  
  
  
  1.1                  xml-xindice/Xindice/java/src/org/apache/xindice/core/filer/package.html
  
  Index: package.html
  ===================================================================
  <html>
    <title>Xindice Filers.</title>
    <body>
      <p>Defines the Xindice Filer interface and implements several Filers,
      including BTreeFiler and HashFiler.</p>
   </body>
  </html>
  
  
  
  
  
  1.1                  xml-xindice/Xindice/java/src/org/apache/xindice/core/indexer/CannotCreateException.java
  
  Index: CannotCreateException.java
  ===================================================================
  package org.apache.xindice.core.indexer;
  
  /*
   * The Apache Software License, Version 1.1
   *
   *
   * Copyright (c) 1999 The Apache Software Foundation.  All rights
   * reserved.
   *
   * Redistribution and use in source and binary forms, with or without
   * modification, are permitted provided that the following conditions
   * are met:
   *
   * 1. Redistributions of source code must retain the above copyright
   *    notice, this list of conditions and the following disclaimer.
   *
   * 2. Redistributions in binary form must reproduce the above copyright
   *    notice, this list of conditions and the following disclaimer in
   *    the documentation and/or other materials provided with the
   *    distribution.
   *
   * 3. The end-user documentation included with the redistribution,
   *    if any, must include the following acknowledgment:
   *       "This product includes software developed by the
   *        Apache Software Foundation (http://www.apache.org/)."
   *    Alternately, this acknowledgment may appear in the software itself,
   *    if and wherever such third-party acknowledgments normally appear.
   *
   * 4. The names "Xindice" and "Apache Software Foundation" must
   *    not be used to endorse or promote products derived from this
   *    software without prior written permission. For written
   *    permission, please contact apache@apache.org.
   *
   * 5. Products derived from this software may not be called "Apache",
   *    nor may "Apache" appear in their name, without prior written
   *    permission of the Apache Software Foundation.
   *
   * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
   * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
   * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
   * DISCLAIMED.  IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
   * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
   * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
   * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
   * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
   * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
   * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
   * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
   * SUCH DAMAGE.
   * ====================================================================
   *
   * This software consists of voluntary contributions made by many
   * individuals on behalf of the Apache Software Foundation and was
   * originally based on software copyright (c) 1999-2001, The dbXML
   * Group, L.L.C., http://www.dbxmlgroup.com.  For more
   * information on the Apache Software Foundation, please see
   * <http://www.apache.org/>.
   *
   * $Id: CannotCreateException.java,v 1.1 2001/12/06 21:00:12 bradford Exp $
   */
  
  import org.apache.xindice.core.*;
  
  /**
   * A CannotCreateException is thrown if an Indexer cannot
   * be properly created in the server context for some reason.
   */
  
  public final class CannotCreateException extends IndexerException {
     public CannotCreateException() {
        super(FaultCodes.IDX_CANNOT_CREATE);
     }
     
     public CannotCreateException(String message) {
        super(FaultCodes.IDX_CANNOT_CREATE, message);
     }
  }
  
  
  
  1.1                  xml-xindice/Xindice/java/src/org/apache/xindice/core/indexer/DuplicateIndexException.java
  
  Index: DuplicateIndexException.java
  ===================================================================
  package org.apache.xindice.core.indexer;
  
  /*
   * The Apache Software License, Version 1.1
   *
   *
   * Copyright (c) 1999 The Apache Software Foundation.  All rights
   * reserved.
   *
   * Redistribution and use in source and binary forms, with or without
   * modification, are permitted provided that the following conditions
   * are met:
   *
   * 1. Redistributions of source code must retain the above copyright
   *    notice, this list of conditions and the following disclaimer.
   *
   * 2. Redistributions in binary form must reproduce the above copyright
   *    notice, this list of conditions and the following disclaimer in
   *    the documentation and/or other materials provided with the
   *    distribution.
   *
   * 3. The end-user documentation included with the redistribution,
   *    if any, must include the following acknowledgment:
   *       "This product includes software developed by the
   *        Apache Software Foundation (http://www.apache.org/)."
   *    Alternately, this acknowledgment may appear in the software itself,
   *    if and wherever such third-party acknowledgments normally appear.
   *
   * 4. The names "Xindice" and "Apache Software Foundation" must
   *    not be used to endorse or promote products derived from this
   *    software without prior written permission. For written
   *    permission, please contact apache@apache.org.
   *
   * 5. Products derived from this software may not be called "Apache",
   *    nor may "Apache" appear in their name, without prior written
   *    permission of the Apache Software Foundation.
   *
   * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
   * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
   * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
   * DISCLAIMED.  IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
   * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
   * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
   * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
   * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
   * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
   * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
   * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
   * SUCH DAMAGE.
   * ====================================================================
   *
   * This software consists of voluntary contributions made by many
   * individuals on behalf of the Apache Software Foundation and was
   * originally based on software copyright (c) 1999-2001, The dbXML
   * Group, L.L.C., http://www.dbxmlgroup.com.  For more
   * information on the Apache Software Foundation, please see
   * <http://www.apache.org/>.
   *
   * $Id: DuplicateIndexException.java,v 1.1 2001/12/06 21:00:12 bradford Exp $
   */
  
  import org.apache.xindice.core.*;
  
  /**
   * A DuplicateIndexException is thrown if an Indexer  create
   * attempt duplicates an existing Indexer.
   */
  
  public final class DuplicateIndexException extends IndexerException {
     public DuplicateIndexException() {
        super(FaultCodes.IDX_DUPLICATE_INDEX);
     }
     
     public DuplicateIndexException(String message) {
        super(FaultCodes.IDX_DUPLICATE_INDEX, message);
     }
  }
  
  
  
  1.1                  xml-xindice/Xindice/java/src/org/apache/xindice/core/indexer/IndexManager.java
  
  Index: IndexManager.java
  ===================================================================
  package org.apache.xindice.core.indexer;
  
  /*
   * The Apache Software License, Version 1.1
   *
   *
   * Copyright (c) 1999 The Apache Software Foundation.  All rights
   * reserved.
   *
   * Redistribution and use in source and binary forms, with or without
   * modification, are permitted provided that the following conditions
   * are met:
   *
   * 1. Redistributions of source code must retain the above copyright
   *    notice, this list of conditions and the following disclaimer.
   *
   * 2. Redistributions in binary form must reproduce the above copyright
   *    notice, this list of conditions and the following disclaimer in
   *    the documentation and/or other materials provided with the
   *    distribution.
   *
   * 3. The end-user documentation included with the redistribution,
   *    if any, must include the following acknowledgment:
   *       "This product includes software developed by the
   *        Apache Software Foundation (http://www.apache.org/)."
   *    Alternately, this acknowledgment may appear in the software itself,
   *    if and wherever such third-party acknowledgments normally appear.
   *
   * 4. The names "Xindice" and "Apache Software Foundation" must
   *    not be used to endorse or promote products derived from this
   *    software without prior written permission. For written
   *    permission, please contact apache@apache.org.
   *
   * 5. Products derived from this software may not be called "Apache",
   *    nor may "Apache" appear in their name, without prior written
   *    permission of the Apache Software Foundation.
   *
   * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
   * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
   * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
   * DISCLAIMED.  IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
   * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
   * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
   * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
   * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
   * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
   * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
   * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
   * SUCH DAMAGE.
   * ====================================================================
   *
   * This software consists of voluntary contributions made by many
   * individuals on behalf of the Apache Software Foundation and was
   * originally based on software copyright (c) 1999-2001, The dbXML
   * Group, L.L.C., http://www.dbxmlgroup.com.  For more
   * information on the Apache Software Foundation, please see
   * <http://www.apache.org/>.
   *
   * $Id: IndexManager.java,v 1.1 2001/12/06 21:00:12 bradford Exp $
   */
  
  import org.apache.xindice.core.*;
  import org.apache.xindice.core.Collection;
  import org.apache.xindice.core.data.*;
  import org.apache.xindice.core.query.*;
  import org.apache.xindice.xml.*;
  import org.apache.xindice.xml.sax.*;
  import org.apache.xindice.xml.dom.*;
  import org.apache.xindice.util.*;
  
  import org.w3c.dom.*;
  import org.xml.sax.*;
  import org.xml.sax.helpers.*;
  
  import java.io.*;
  import java.util.*;
  
  import org.w3c.dom.*;
  
  /**
   * IndexManager is a class that manages Indexes.  Good description, eh?
   * I should win a Pulitzer Prize for that one.
   */
  
  public final class IndexManager extends SimpleConfigurable {
     private static final String[] EmptyStrings = new String[0];
     private static final IndexerInfo[] EmptyIndexerInfo = new IndexerInfo[0];
  
     private static final String INDEX = "index";
     private static final String NAME = "name";
     private static final String CLASS = "class";
  
     private static final int STATUS_READY = 0;
     private static final int STATUS_BUSY = 1;
     private static final int STATUS_DELETED = 2;
  
     private static final int ACTION_CREATE = 0;
     private static final int ACTION_UPDATE = 1;
     private static final int ACTION_DELETE = 2;
  
     private static final AutoIndexer autoIndexer = new AutoIndexer();
  
     private Map patternMap = new HashMap();   // IndexPattern to IndexerInfo
     private Map indexes = new HashMap();      // String to IndexerInfo
     private Map bestIndexers = new HashMap(); // String to SoftRefTab
                                               // of IndexPattern to Indexer
  
     private IndexerInfo[] idxList = EmptyIndexerInfo;
  
     private Collection collection;
     private SymbolTable symbols;
     private List newIndexers = new ArrayList(); // of IndexerInfo
  
     public IndexManager(Collection collection) {
        this.collection = collection;
        try {
           symbols = collection.getSymbols();
        }
        catch ( Exception e ) {
           org.apache.xindice.Debug.printStackTrace(e);
        }
     }
  
     public void setConfig(Configuration config) throws XindiceException {
        super.setConfig(config);
  
        try {
           config.processChildren(INDEX,
              new ConfigurationCallback() {
                 public void process(Configuration cfg) {
                    String className = cfg.getAttribute(CLASS);
                    try {
                       register(Class.forName(className), cfg);
                    }
                    catch ( Exception e ) {
                       org.apache.xindice.Debug.printStackTrace(e);
                    }
                 }
           });
        }
        catch ( Exception e ) {
           org.apache.xindice.Debug.println(e.getMessage());
        }
     }
  
     /**
      * list returns a list of the Indexers that this IndexerManager has
      * registered.
      *
      * @return An array containing the Indexer names
      */
     public String[] list() {
        return (String[])indexes.keySet().toArray(EmptyStrings);
     }
  
     /**
      * drop physically removes the specified Indexer and any
      * associated system resources that the Indexer uses.
      *
      * @param name The Indexer to drop
      * @return Whether or not the Indexer was dropped
      */
     public boolean drop(final String name) {
        Indexer idx = get(name);
        unregister(name);
        config.processChildren(INDEX,
           new ConfigurationCallback() {
              public void process(Configuration cfg) {
                 try {
                    if ( cfg.getAttribute(NAME).equals(name) )
                       cfg.delete();
                 }
                 catch ( Exception e ) {
                    org.apache.xindice.Debug.printStackTrace(e);
                 }
              }
        });
  
        boolean res = false;
        try {
           res = idx.drop();
        }
        catch ( Exception e ) {
           org.apache.xindice.Debug.printStackTrace(e);
        }
        return res;
     }
  
     /**
      * create creates a new Indexer object and any associated
      * system resources that the Indexer will need.
      *
      * @param cfg The Indexer's configuration
      * @return The Indexer that was created
      */
     public Indexer create(Configuration cfg) throws DBException {
        String className = cfg.getAttribute(CLASS);
        try {
           // Check for duplicates
           String name = cfg.getAttribute(NAME);
           Configuration[] cfgs = config.getChildren();
           for ( int i = 0; i < cfgs.length; i++ )
              if ( cfgs[i].getAttribute(NAME).equals(name) )
                 throw new DuplicateIndexException("Duplicate Index '"+name+"'");
  
           config.add(cfg);
           
           Class c = Class.forName(className);
           Indexer idx = register(c, cfg);
  
           return idx;
        }
        catch ( DBException d ) {
           throw d;
        }
        catch ( Exception e ) {
           throw new CannotCreateException("Cannot create Index");
        }
     }
  
     public Indexer register(Class c, Configuration cfg) throws DBException {
        String name = null;
        try {
           Indexer idx = (Indexer)c.newInstance();
           initialize(idx, cfg);
           name = idx.getName();
           
           if ( name == null || name.trim().equals("") )
              throw new CannotCreateException("No name specified");
  
           IndexPattern pattern = new IndexPattern(symbols, idx.getPattern(), null);
           String style = idx.getIndexStyle();
           IndexerInfo info = new IndexerInfo(name, style, pattern, idx);
  
           if ( !idx.exists() ) {
              info.status = STATUS_BUSY;
              newIndexers.add(info);
              autoIndexer.populateIndexers(this);
           }
           else {
              info.status = STATUS_READY;
              idx.open();
           }
  
           indexes.put(name, info);
           patternMap.put(pattern, info);
  
           Map tbl = (Map)bestIndexers.get(style);
           if ( tbl == null ) {
              tbl = new WeakHashMap();
              bestIndexers.put(style, tbl);
           }
           tbl.clear();
           idxList = (IndexerInfo[])indexes.values().toArray(EmptyIndexerInfo);
           
           return idx;
        }
        catch ( DBException d ) {
           throw d;
        }
        catch ( Exception e ) {
           throw new CannotCreateException("Cannot create Index '"+name+"'");
        }
     }
  
     public void unregister(String name) {
        IndexerInfo idx = (IndexerInfo)indexes.remove(name);
        String style = idx.style;
        patternMap.remove(idx.pattern);
  
        Map tbl = (Map)bestIndexers.get(style);
        if ( tbl == null ) {
           tbl = new WeakHashMap();
           bestIndexers.put(style, tbl);
        }
        tbl.clear();
  
        idxList = (IndexerInfo[])indexes.values().toArray(EmptyIndexerInfo);
     }
  
     private void initialize(Indexer idx, Configuration cfg) throws XindiceException {
        idx.setCollection(collection);
        idx.setConfig(cfg);
     }
  
     private void populateNewIndexers() throws DBException {
        if ( newIndexers.size() > 0 ) {
           IndexerInfo[] list = (IndexerInfo[])newIndexers.toArray(EmptyIndexerInfo);
           newIndexers.clear();
  
           if ( true ) {
              for ( int i = 0; i < list.length; i++ )
                 org.apache.xindice.Debug.println("Index Creation: "+list[i].indexer.getName());
           }
           
  org.apache.xindice.Stopwatch sw = new org.apache.xindice.Stopwatch("Populated Indexes", true);
           for ( int i = 0; i < list.length; i++ ) {
              try {
                 if ( !list[i].indexer.exists() )
                    list[i].indexer.create();
              }
              catch ( Exception e ) {
                 org.apache.xindice.Debug.printStackTrace(e);
              }
           }
           
           RecordSet rs = collection.getFiler().getRecordSet();
           while ( rs.hasMoreRecords() ) {
              Record rec = rs.getNextRecord();
  
              if ( rec == null )
                 continue;
              
              Key key = rec.getKey();
              Document doc = new DocumentImpl(rec.getValue().getData(), symbols, new NodeSource(collection, key));
              try {
                 new SAXHandler(key, doc, ACTION_CREATE, list);
              }
              catch ( Exception e ) {
                 org.apache.xindice.Debug.printStackTrace(e);
              }
           }
  
           for ( int i = 0; i < list.length; i++ ) {
              try {
                 list[i].indexer.flush();
              }
              catch ( Exception e ) {
                 org.apache.xindice.Debug.printStackTrace(e);
              }
              list[i].status = STATUS_READY;
           }
  sw.stop();
           
           if ( true ) {
              for ( int i = 0; i < list.length; i++ )
                 org.apache.xindice.Debug.println("Index Complete: "+list[i].indexer.getName());
  org.apache.xindice.Debug.println(sw.toString());
           }
        }
     }
  
     /**
      * get retrieves an Indexer by name.
      *
      * @name The Indexer name
      * @return The Indexer
      */
     public Indexer get(String name) {
        IndexerInfo info = (IndexerInfo)indexes.get(name);
        return info != null ? info.indexer
                            : null;
     }
  
     /**
      * getBestIndexer retrieves the best Indexer to use for the specified
      * IndexPattern.
      *
      * @param style The Indexer Style (ex: Node, Value)
      * @param pattern The IndexPattern to use
      * @return The best Indexer (or null)
      */
     public Indexer getBestIndexer(String style, IndexPattern pattern) {
        Map tbl = (Map)bestIndexers.get(style);
        if ( tbl == null ) {
           tbl = new WeakHashMap();
           bestIndexers.put(style, tbl);
        }
        Indexer idx = (Indexer)tbl.get(pattern);
        if ( idx == null ) {
           int highScore = 0;
           Iterator enum = indexes.values().iterator();
           while ( enum.hasNext() ) {
              IndexerInfo info = (IndexerInfo)enum.next();
              if ( info.status != STATUS_READY
                || !info.indexer.getIndexStyle().equals(style) )
                 continue;
              int score = pattern.getMatchLevel(info.pattern);
              if ( score > highScore ) {
                 idx = info.indexer;
                 highScore = score;
              }
           }
           tbl.put(pattern, idx);
        }
        return idx;
     }
     
     public void addDocument(Key key, Document doc) {
        if ( idxList.length > 0 ) {
           new SAXHandler(key, doc, ACTION_CREATE);
           for ( int i = 0; i < idxList.length; i++ ) {
              try {
                 idxList[i].indexer.flush();
              }
              catch ( Exception e ) {
              }
           }
        }
     }
  
     public void removeDocument(Key key, Document doc) {
        if ( idxList.length > 0 ) {
           new SAXHandler(key, doc, ACTION_DELETE);
           for ( int i = 0; i < idxList.length; i++ ) {
              try {
                 idxList[i].indexer.flush();
              }
              catch ( Exception e ) {
              }
           }
        }
     }
  
  
     /**
      * IndexerInfo
      */
  
     private class IndexerInfo {
        public String name;
        public String style;
        public IndexPattern pattern;
        public Indexer indexer;
        public int status;
  
        public IndexerInfo(String name, String style, IndexPattern pattern, Indexer indexer) {
           this.name = name;
           this.style = style;
           this.pattern = pattern;
           this.indexer = indexer;
        }
     }
  
  
     /**
      * SAXHandler actually performs the work of adding and removing Indexer
      * entries.
      */
  
     private class SAXHandler implements ContentHandler, CompressionHandler {
        private ObjectStack stack = new ObjectStack();
        private IndexerInfo[] list;
  
        public Key key;
        public Document doc;
        public int action;
  
        public StackInfo info; // Current State
  
        public SAXHandler(Key key, Document doc, int action, IndexerInfo[] list) {
           this.list = list;
           this.key = key;
           this.doc = doc;
           this.action = action;
  
           try {
              SAXEventGenerator events = new SAXEventGenerator(doc);
              events.setContentHandler(this);
              events.setProperty(HANDLER, this);
              events.start();
              
              if ( action == ACTION_CREATE || action == ACTION_UPDATE ) {
                 try {
                    collection.flushSymbolTable();
                 }
                 catch ( Exception e ) {
                 }
              }
           }
           catch ( Exception e ) {
              org.apache.xindice.Debug.printStackTrace(e);
           }
        }
        
        public SAXHandler(Key key, Document doc, int action) {
           this(key, doc, action, idxList);
        }
  
        // These are all NO-OPs
        public void setDocumentLocator(Locator locator) {}
        public void startDocument() {}
        public void endDocument() {}
        public void startPrefixMapping(String prefix, String uri) {}
        public void endPrefixMapping(String prefix) {}
        public void ignorableWhitespace(char ch[], int start, int length) {}
        public void processingInstruction(String target, String data) {}
        public void skippedEntity(String name) {}
        public void symbols(SymbolTable symbols) {}
        public void dataBytes(byte[] data) {}
  
        public void processEntry(IndexPattern pattern, String value, int pos, int len) {
           for ( int i = 0; i < list.length; i++ ) {
              if ( pattern.getMatchLevel(list[i].pattern) > 0 ) {
                 try {
                    switch ( action ) {
                       case ACTION_CREATE:
                       case ACTION_UPDATE:
                          list[i].indexer.add(value, key, pos, len, pattern.getElementID(), pattern.getAttributeID());
                          break;
                       case ACTION_DELETE:
                          list[i].indexer.remove(value, key, pos, len, pattern.getElementID(), pattern.getAttributeID());
                          break;
                    }
                 }
                 catch ( Exception e ) {
                    org.apache.xindice.Debug.printStackTrace(e);
                 }
              }
           }
        }
  
        public void startElement(String namespaceURI, String localName, String qName, Attributes atts) {
           // Modify the stack info to normalize the symbolID
           if ( namespaceURI != null && namespaceURI.length() > 0 ) {
              String elemNSID = SymbolTable.getNormalizedLocalName(localName, namespaceURI);
              info.symbolID = symbols.getSymbol(elemNSID, namespaceURI, true);
           }
           
           int size = atts.getLength();
           for ( int i = 0; i < size; i++ ) {
              String nsURI = atts.getURI(i);
              if ( nsURI != null && nsURI.length() > 0 ) {
                 String attrNSID = "ns"+Integer.toString(nsURI.hashCode())+":"+atts.getLocalName(i);
                 short id = symbols.getSymbol(attrNSID, nsURI, true);
                 processEntry(new IndexPattern(symbols, info.symbolID, id), atts.getValue(i), info.pos, info.len);
              }
              else {
                 short id = symbols.getSymbol(atts.getQName(i));
                 processEntry(new IndexPattern(symbols, info.symbolID, id), atts.getValue(i), info.pos, info.len);
              }
           }
        }
  
        public void endElement(String namespaceURI, String localName, String qName) {
           if ( info.sb != null )
              processEntry(new IndexPattern(symbols, info.symbolID), info.sb.toString(), info.pos, info.len);
           info = (StackInfo)stack.pop();
        }
  
        public void characters(char ch[], int start, int length) {
           String val = new String(ch).trim();
           if ( info.sb == null )
              info.sb = new StringBuffer(ch.length);
           else if ( info.sb.length() > 0 )
              info.sb.append(' ');
           info.sb.append(val);
        }
  
        public void symbolID(short symbolID) {
           if ( info != null )
              stack.push(info);
           info = new StackInfo(symbolID);
        }
  
        public void dataLocation(int pos, int len) {
           info.pos = pos;
           info.len = len;
        }
     }
  
  
     /**
      * StackInfo
      */
  
     private class StackInfo {
        public short symbolID;
        public StringBuffer sb = null;
        public int pos = -1;
        public int len = -1;
  
        public StackInfo(short symbolID) {
           this.symbolID = symbolID;
        }
     }
  
  
     /**
      * AutoIndexer
      */
     private static class AutoIndexer extends Thread {
        public Set mgrSet = new HashSet();
  
        public AutoIndexer() {
           setName("Automatic Indexer");
           start();
        }
  
        public void run() {
           while ( true ) {
              try {
                 sleep(5000);
              }
              catch ( Exception e ) {
              }
  
              if ( !mgrSet.isEmpty() ) {
                 // Use a copy of the IndexManager Set
                 Set set;
                 synchronized(this) {
                    set = new HashSet(mgrSet);
                 }
  
                 Iterator iter = set.iterator();
                 while ( iter.hasNext() ) {
                    IndexManager mgr = (IndexManager)iter.next();
  
                    // Remove from the Original IndexManager Set
                    synchronized(this) {
                       mgrSet.remove(mgr);
                    }
  
                    try {
                       mgr.populateNewIndexers();
                    }
                    catch ( Exception e ) {
                       org.apache.xindice.Debug.printStackTrace(e);
                    }
                 }
              }
           }
        }
  
        public synchronized void populateIndexers(IndexManager mgr) {
           mgrSet.add(mgr);
        }
     }
  }
  
  
  
  
  
  1.1                  xml-xindice/Xindice/java/src/org/apache/xindice/core/indexer/IndexMatch.java
  
  Index: IndexMatch.java
  ===================================================================
  package org.apache.xindice.core.indexer;
  
  /*
   * The Apache Software License, Version 1.1
   *
   *
   * Copyright (c) 1999 The Apache Software Foundation.  All rights
   * reserved.
   *
   * Redistribution and use in source and binary forms, with or without
   * modification, are permitted provided that the following conditions
   * are met:
   *
   * 1. Redistributions of source code must retain the above copyright
   *    notice, this list of conditions and the following disclaimer.
   *
   * 2. Redistributions in binary form must reproduce the above copyright
   *    notice, this list of conditions and the following disclaimer in
   *    the documentation and/or other materials provided with the
   *    distribution.
   *
   * 3. The end-user documentation included with the redistribution,
   *    if any, must include the following acknowledgment:
   *       "This product includes software developed by the
   *        Apache Software Foundation (http://www.apache.org/)."
   *    Alternately, this acknowledgment may appear in the software itself,
   *    if and wherever such third-party acknowledgments normally appear.
   *
   * 4. The names "Xindice" and "Apache Software Foundation" must
   *    not be used to endorse or promote products derived from this
   *    software without prior written permission. For written
   *    permission, please contact apache@apache.org.
   *
   * 5. Products derived from this software may not be called "Apache",
   *    nor may "Apache" appear in their name, without prior written
   *    permission of the Apache Software Foundation.
   *
   * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
   * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
   * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
   * DISCLAIMED.  IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
   * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
   * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
   * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
   * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
   * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
   * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
   * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
   * SUCH DAMAGE.
   * ====================================================================
   *
   * This software consists of voluntary contributions made by many
   * individuals on behalf of the Apache Software Foundation and was
   * originally based on software copyright (c) 1999-2001, The dbXML
   * Group, L.L.C., http://www.dbxmlgroup.com.  For more
   * information on the Apache Software Foundation, please see
   * <http://www.apache.org/>.
   *
   * $Id: IndexMatch.java,v 1.1 2001/12/06 21:00:12 bradford Exp $
   */
  
  import org.apache.xindice.core.data.*;
  import org.apache.xindice.core.filer.*;
  import java.io.*;
  
  /**
   * IndexMatch is used for representing match information.  IndexMatches
   * are the basic unit of information between Indexers and the IndexManager
   * for performing queries and query optimization.
   */
  
  public final class IndexMatch implements Comparable {
     private Key key;    // The Document Key
     private int pos;    // Offset into the stream
     private int len;    // Length of substream
     private short elem; // Element ID (for wildcards)
     private short attr; // Attribute ID (if any)
     
     public IndexMatch() {
        key = null;
        pos = -1;
        len = -1;
        elem = -1;
        attr = -1;
     }
  
     public IndexMatch(Key key, int pos, int len, short elem, short attr) {
        this.key = key;
        this.pos = pos;
        this.len = len;
        this.elem = elem;
        this.attr = attr;
     }
  
     public IndexMatch(Key key, int pos, int len) {
        this.key = key;
        this.pos = pos;
        this.len = len;
        elem = -1;
        attr = -1;
     }
     
     public IndexMatch(Key key, IndexPattern pattern) {
        this.key = key;
        pos = -1;
        len = -1;
        elem = pattern.getElementID();
        attr = pattern.getAttributeID();
     }
     
     /**
      * getKey returns the Document Key for the IndexMatch.
      *
      * @return The Key
      */
     public final Key getKey() {
        return key;
     }
  
     /**
      * getPosition returns the Document position for the Match.
      *
      * @return The Document position
      */
     public final int getPosition() {
        return pos;
     }
  
     /**
      * getLength returns the Node length for the Match.
      *
      * @return The Node length
      */
     public final int getLength() {
        return len;
     }
  
     /**
      * getElement returns the Element symbol ID for the Match.
      *
      * @return The Element Symbol ID
      */
     public final short getElement() {
        return elem;
     }
  
     /**
      * getAttribute returns the Attribute symbol ID for the Match.
      *
      * @return The Attribute Symbol ID
      */
     public final short getAttribute() {
        return attr;
     }
        
     public int compareTo(Object obj) {
        return key.compareTo(obj);
     }
     
     public String toString() {
        return key.toString();
     }
  }
  
  
  
  
  1.1                  xml-xindice/Xindice/java/src/org/apache/xindice/core/indexer/IndexPattern.java
  
  Index: IndexPattern.java
  ===================================================================
  package org.apache.xindice.core.indexer;
  
  /*
   * The Apache Software License, Version 1.1
   *
   *
   * Copyright (c) 1999 The Apache Software Foundation.  All rights
   * reserved.
   *
   * Redistribution and use in source and binary forms, with or without
   * modification, are permitted provided that the following conditions
   * are met:
   *
   * 1. Redistributions of source code must retain the above copyright
   *    notice, this list of conditions and the following disclaimer.
   *
   * 2. Redistributions in binary form must reproduce the above copyright
   *    notice, this list of conditions and the following disclaimer in
   *    the documentation and/or other materials provided with the
   *    distribution.
   *
   * 3. The end-user documentation included with the redistribution,
   *    if any, must include the following acknowledgment:
   *       "This product includes software developed by the
   *        Apache Software Foundation (http://www.apache.org/)."
   *    Alternately, this acknowledgment may appear in the software itself,
   *    if and wherever such third-party acknowledgments normally appear.
   *
   * 4. The names "Xindice" and "Apache Software Foundation" must
   *    not be used to endorse or promote products derived from this
   *    software without prior written permission. For written
   *    permission, please contact apache@apache.org.
   *
   * 5. Products derived from this software may not be called "Apache",
   *    nor may "Apache" appear in their name, without prior written
   *    permission of the Apache Software Foundation.
   *
   * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
   * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
   * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
   * DISCLAIMED.  IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
   * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
   * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
   * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
   * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
   * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
   * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
   * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
   * SUCH DAMAGE.
   * ====================================================================
   *
   * This software consists of voluntary contributions made by many
   * individuals on behalf of the Apache Software Foundation and was
   * originally based on software copyright (c) 1999-2001, The dbXML
   * Group, L.L.C., http://www.dbxmlgroup.com.  For more
   * information on the Apache Software Foundation, please see
   * <http://www.apache.org/>.
   *
   * $Id: IndexPattern.java,v 1.1 2001/12/06 21:00:12 bradford Exp $
   */
  
  import org.apache.xindice.core.filer.*;
  import org.apache.xindice.xml.*;
  
  import java.io.*;
  import java.util.*;
  
  /**
    * IndexPattern is the internal representation of a pattern for index
    * matching purposes.
    */
  
  public final class IndexPattern implements Streamable {
     public static final int PATTERN_NONE = -1;
     public static final int PATTERN_WILDCARD = -2;
     public static final int PATTERN_NAME = -3;
  
     public static final int SCORE_NONE = 0;
     public static final int SCORE_WILDCARD = 1;
     public static final int SCORE_NAME = 2;
     public static final int SCORE_NATURAL = 3;
  
     private SymbolTable symbols = null;
     private String elemName = null;
     private short elemID = PATTERN_NONE;
     private String attrName = null;
     private short attrID = PATTERN_NONE;
  
     public IndexPattern(SymbolTable symbols, String pattern, NamespaceMap nsMap) {
        this.symbols = symbols;
        StringTokenizer st = new StringTokenizer(pattern.trim(), "@");
        elemName = st.nextToken();
        if ( elemName.equals("*") )
           elemID = PATTERN_WILDCARD;
        else
           elemID = SymbolTable.getNormalizedSymbol(symbols, elemName, nsMap, true);
        if ( st.hasMoreTokens() ) {
           attrName = st.nextToken();
           if ( attrName.equals("*") )
              attrID = PATTERN_WILDCARD;
           else
              attrID = elemID == PATTERN_WILDCARD ? PATTERN_NAME
                                                  : SymbolTable.getNormalizedSymbol(symbols, attrName, nsMap, true);
        }
     }
  
     public IndexPattern(SymbolTable symbols, short elemID) {
        this.symbols = symbols;
        this.elemID = elemID;
     }
  
     public IndexPattern(SymbolTable symbols, short elemID, short attrID) {
        this.symbols = symbols;
        this.elemID = elemID;
        this.attrID = attrID;
     }
  
     public IndexPattern(SymbolTable symbols, short elemID, String attrName) {
        this.symbols = symbols;
        this.elemID = elemID;
        this.attrID = PATTERN_NAME;
        this.attrName = attrName;
     }
  
     /**
      * getMatchLevel compares this IndexPattern to p and returns the strength of
      * the match betwen the two patterns from 0 to 15.  (0 being no match at
      * all, 15 being perfect).  This method should be called by XPath and
      * SAX patterns to be matched against Indexer patterns.
      *
      * @param p The pattern to compare
      * @return The resulting IndexPattern strength
      */
     public int getMatchLevel(IndexPattern p) {
        int result = 0;
  
        switch ( p.elemID ) {
           case PATTERN_WILDCARD:
              result = (SCORE_WILDCARD << 2);
              break;
           case PATTERN_NAME:
              if ( elemName.equals(p.elemName) )
                 result = (SCORE_NAME << 2);
              break;
           default:
              if ( elemID == p.elemID )
                 result = (SCORE_NATURAL << 2);
        }
  
        if ( result != 0 ) {
           switch ( p.attrID ) {
              case PATTERN_WILDCARD:
                 return result + SCORE_WILDCARD;
              case PATTERN_NAME:
                 if ( attrName.equals(p.attrName) )
                    return result + SCORE_NAME;
                 break;
              default:
                 if ( attrID == p.attrID )
                    return result + SCORE_NATURAL;
           }
        }
  
        return 0;
     }
  
     /**
      * getElementID returns the Element Symbol ID for this pattern if
      * there is one, otherwise it returns a negative value.
      *
      * @return The Element Symbol ID
      */
     public short getElementID() {
        return elemID;
     }
  
     /**
      * getAttributeID returns the Attribute Symbol ID for this pattern
      * if there is one, otherwise it returns a negative value.
      *
      * @return The Attribute Symbol ID
      */
     public short getAttributeID() {
        return attrID;
     }
  
     /**
      * getElementName returns the Element Name for this pattern if
      * there is one, otherwise it returns null.
      *
      * @return The Element Name
      */
     public String getElementName() {
        return elemName;
     }
  
     /**
      * getAttributeName returns the Attribute Name for this pattern if
      * there is one, otherwise it returns null.
      *
      * @return The Attribute Name
      */
     public String getAttributeName() {
        return attrName;
     }
  
     public void read(DataInputStream dis) throws IOException {
        elemID = dis.readShort();
        if ( elemID == PATTERN_NAME ) {
           short len = dis.readShort();
           byte[] name = new byte[len];
           dis.read(name);
           elemName = new String(name);
        }
        attrID = dis.readShort();
        if ( attrID == PATTERN_NAME ) {
           short len = dis.readShort();
           byte[] name = new byte[len];
           dis.read(name);
           attrName = new String(name);
        }
     }
  
     public void write(DataOutputStream dos) throws IOException {
        dos.writeShort(elemID);
        if ( elemID == PATTERN_NAME ) {
           byte[] name = elemName.getBytes();
           dos.writeShort(name.length);
           dos.write(name);
        }
        dos.writeShort(attrID);
        if ( attrID == PATTERN_NAME ) {
           byte[] name = attrName.getBytes();
           dos.writeShort(name.length);
           dos.write(name);
        }
     }
  
     public int hashCode() {
        return new Integer((elemID << 16) + attrID).hashCode();
     }
  
     public boolean equals(Object obj) {
        if ( obj instanceof IndexPattern ) {
           IndexPattern p = (IndexPattern)obj;
           boolean eq = elemID == p.elemID && attrID == p.attrID;
           if ( eq && (elemName != null || p.elemName != null) )
              eq = elemName != null && p.elemName != null && elemName.equals(p.elemName);
           if ( eq && (attrName != null || p.attrName != null) )
              eq = attrName != null && p.attrName != null && attrName.equals(p.attrName);
           return eq;
        }
        else
           return false;
     }
  }
  
  
  
  
  1.1                  xml-xindice/Xindice/java/src/org/apache/xindice/core/indexer/IndexQuery.java
  
  Index: IndexQuery.java
  ===================================================================
  package org.apache.xindice.core.indexer;
  
  /*
   * The Apache Software License, Version 1.1
   *
   *
   * Copyright (c) 1999 The Apache Software Foundation.  All rights
   * reserved.
   *
   * Redistribution and use in source and binary forms, with or without
   * modification, are permitted provided that the following conditions
   * are met:
   *
   * 1. Redistributions of source code must retain the above copyright
   *    notice, this list of conditions and the following disclaimer.
   *
   * 2. Redistributions in binary form must reproduce the above copyright
   *    notice, this list of conditions and the following disclaimer in
   *    the documentation and/or other materials provided with the
   *    distribution.
   *
   * 3. The end-user documentation included with the redistribution,
   *    if any, must include the following acknowledgment:
   *       "This product includes software developed by the
   *        Apache Software Foundation (http://www.apache.org/)."
   *    Alternately, this acknowledgment may appear in the software itself,
   *    if and wherever such third-party acknowledgments normally appear.
   *
   * 4. The names "Xindice" and "Apache Software Foundation" must
   *    not be used to endorse or promote products derived from this
   *    software without prior written permission. For written
   *    permission, please contact apache@apache.org.
   *
   * 5. Products derived from this software may not be called "Apache",
   *    nor may "Apache" appear in their name, without prior written
   *    permission of the Apache Software Foundation.
   *
   * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
   * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
   * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
   * DISCLAIMED.  IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
   * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
   * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
   * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
   * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
   * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
   * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
   * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
   * SUCH DAMAGE.
   * ====================================================================
   *
   * This software consists of voluntary contributions made by many
   * individuals on behalf of the Apache Software Foundation and was
   * originally based on software copyright (c) 1999-2001, The dbXML
   * Group, L.L.C., http://www.dbxmlgroup.com.  For more
   * information on the Apache Software Foundation, please see
   * <http://www.apache.org/>.
   *
   * $Id: IndexQuery.java,v 1.1 2001/12/06 21:00:12 bradford Exp $
   */
  
  import org.apache.xindice.core.data.*;
  import java.util.*;
  
  /**
   * IndexQuery represents the most primitive form of index querying.
   * Instances of this object should be created by QueryResolvers and
   * cached in Query instances.
   */
  
  public class IndexQuery {
     // No Operator
     public static final int ANY = 0;   // Any And All Matches
     
     // Singleton Operators
     public static final int EQ = 1;    // Equal To
     public static final int NEQ = -1;  // Not Equal To
     public static final int GT = 2;    // Greater Than
     public static final int LEQ = -2;  // Less Than Or Equal To
     public static final int LT = 3;    // Less Than
     public static final int GEQ = -3;  // Greater Than Or Equal To
     
     // Range Operators
     public static final int BW = 4;    // Between (Inclusive)
     public static final int NBW = -4;  // Not Between (Inclusive)
     public static final int BWX = 5;   // Between (Exclusive)
     public static final int NBWX = -5; // Not Between (Exclusive)
     
     // Set Operators
     public static final int IN = 6;    // In The Set
     public static final int NIN = -6;  // Not In The Set
     
     // Other operators
     public static final int SW = 7;    // Starts-with
     public static final int NSW = -7;  // Not Starts-with
     
     protected IndexPattern pattern;
     protected int op;
     protected Value[] vals;
     
     public IndexQuery(IndexPattern pattern) {
        this.pattern = pattern;
        op = ANY;
     }
     
     public IndexQuery(IndexPattern pattern, int op, Value[] vals) {
        this.pattern = pattern;
        this.op = op;
        this.vals = vals;
     }
     
     public IndexQuery(IndexPattern pattern, Value[] vals) {
        this(pattern, IN, vals);
     }
  
     public IndexQuery(IndexPattern pattern, int op, Value val1) {
        this.pattern = pattern;
        this.op = op;
        if ( op == SW || op == NSW ) {
           byte[] b = new byte[val1.getLength()+1];
           System.arraycopy(val1.getData(), 0, b, 0, b.length-1);
           b[b.length-1] = 127; // TODO: Must fix this
           Value val2 = new Value(b);
           vals = new Value[] { val1, val2 };
        }
        else
           vals = new Value[] { val1 };
     }
        
     public IndexQuery(IndexPattern pattern, Value val1) {
        this(pattern, EQ, val1);
     }
     
     public IndexQuery(IndexPattern pattern, int op, Value val1, Value val2) {
        this.pattern = pattern;
        this.op = op;
        vals = new Value[] { val1, val2 };
     }
     
     public IndexQuery(IndexPattern pattern, Value val1, Value val2) {
        this(pattern, IN, val1, val2);
     }
     
     public IndexQuery(IndexPattern pattern, int op, String val1) {
        this(pattern, op, new Value(val1));
     }
     
     public IndexQuery(IndexPattern pattern, String val1) {
        this(pattern, new Value(val1));
     }
     
     public IndexQuery(IndexPattern pattern, int op, String val1, String val2) {
        this(pattern, op, new Value(val1), new Value(val2));
     }
     
     public IndexQuery(IndexPattern pattern, String val1, String val2) {
        this(pattern, new Value(val1), new Value(val2));
     }
     
     /**
      * getPattern returns the IndexPattern associated with this query.
      *
      * @return the IndexPattern
      */
     public IndexPattern getPattern() {
        return pattern;
     }
     
     /**
      * getOperator returns the operator associated with this query.
      *
      * @return The operator
      */
     public int getOperator() {
        return op;
     }
     
     /**
      * getValue returns one of the Values associated with this query.
      *
      * @param index The Value index
      * @return The request Value
      */
     public final Value getValue(int index) {
        return vals[index];
     }
  
     /**
      * getValues returns the Values associated with this query.
      *
      * @return The Value set
      */
     public Value[] getValues() {
        return vals;
     }
     
     /**
      * getLength returns the length of the Value set associated with
      * this query.
      *
      * @return The Value set length
      */
     public final int getLength() {
        return vals.length;
     }
     
     
     /**
      * testValue tests the specified value for validity against this
      * IndexQuery.  The helper classes in org.apache.xindice.core.indexer.helpers
      * should be used for optimized performance.
      *
      * @param value The Value to compare
      * @return Whether or not the value matches
      */
     public boolean testValue(Value value) {
        switch ( op ) {
           // No Comparison (Any)
           case ANY:
              return true;
              
           // Singleton Comparisons
           case EQ:
              return value.equals(vals[0]);
           case NEQ:
              return !value.equals(vals[0]);
           case GT:
              return value.compareTo(vals[0]) > 0;
           case LEQ:
              return value.compareTo(vals[0]) <= 0;
           case LT:
              return value.compareTo(vals[0]) < 0;
           case GEQ:
              return value.compareTo(vals[0]) >= 0;
              
           // Range Comparisons
           case BW:
              return value.compareTo(vals[0]) >= 0 && value.compareTo(vals[1]) <= 0;
           case NBW:
              return value.compareTo(vals[0]) <= 0 || value.compareTo(vals[1]) >= 0;
           case BWX:
              return value.compareTo(vals[0]) > 0 && value.compareTo(vals[1]) < 0;
           case NBWX:
              return value.compareTo(vals[0]) < 0 || value.compareTo(vals[1]) > 0;
              
           // Set Comparisons
           case IN:
           case NIN:
              return Arrays.binarySearch(vals, value)>= 0 ? op == IN
                                                          : op == NIN;
              
           // Other comparisons
           case SW:
           case NSW:
              return value.startsWith(vals[0]) ? op == SW
                                               : op == NSW;
           
        }
        return false;
     }
  
     /**
      * testValue tests the specified value for validity against this
      * IndexQuery.  The helper classes in org.apache.xindice.core.indexer.helpers
      * should be used for optimized performance.
      *
      * @param value The Value to compare
      * @return Whether or not the value matches
      */
     public final boolean testValue(String value) {
        return testValue(new Value(value));
     }
  }
  
  
  
  
  1.1                  xml-xindice/Xindice/java/src/org/apache/xindice/core/indexer/Indexer.java
  
  Index: Indexer.java
  ===================================================================
  package org.apache.xindice.core.indexer;
  
  /*
   * The Apache Software License, Version 1.1
   *
   *
   * Copyright (c) 1999 The Apache Software Foundation.  All rights
   * reserved.
   *
   * Redistribution and use in source and binary forms, with or without
   * modification, are permitted provided that the following conditions
   * are met:
   *
   * 1. Redistributions of source code must retain the above copyright
   *    notice, this list of conditions and the following disclaimer.
   *
   * 2. Redistributions in binary form must reproduce the above copyright
   *    notice, this list of conditions and the following disclaimer in
   *    the documentation and/or other materials provided with the
   *    distribution.
   *
   * 3. The end-user documentation included with the redistribution,
   *    if any, must include the following acknowledgment:
   *       "This product includes software developed by the
   *        Apache Software Foundation (http://www.apache.org/)."
   *    Alternately, this acknowledgment may appear in the software itself,
   *    if and wherever such third-party acknowledgments normally appear.
   *
   * 4. The names "Xindice" and "Apache Software Foundation" must
   *    not be used to endorse or promote products derived from this
   *    software without prior written permission. For written
   *    permission, please contact apache@apache.org.
   *
   * 5. Products derived from this software may not be called "Apache",
   *    nor may "Apache" appear in their name, without prior written
   *    permission of the Apache Software Foundation.
   *
   * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
   * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
   * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
   * DISCLAIMED.  IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
   * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
   * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
   * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
   * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
   * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
   * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
   * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
   * SUCH DAMAGE.
   * ====================================================================
   *
   * This software consists of voluntary contributions made by many
   * individuals on behalf of the Apache Software Foundation and was
   * originally based on software copyright (c) 1999-2001, The dbXML
   * Group, L.L.C., http://www.dbxmlgroup.com.  For more
   * information on the Apache Software Foundation, please see
   * <http://www.apache.org/>.
   *
   * $Id: Indexer.java,v 1.1 2001/12/06 21:00:12 bradford Exp $
   */
  
  import org.apache.xindice.core.*;
  import org.apache.xindice.core.data.*;
  import org.w3c.dom.*;
  import org.apache.xindice.util.*;
  
  /**
   * Indexer is the abstract indexing interface for Xindice.  An Indexer
   * object is implemented in order to retrieve and manage indexes.
   * <br><br>
   * Any number of Indexer instances may be associated with a single
   * Collection.  The type of Indexer utilized by a query depends on
   * the 'Style' of Indexer and the type of QueryResolver that is being
   * used to performt he query.  Currently, Xindice only internally
   * supports one kind of Indexer: 'XPath'.
   */
  
  public interface Indexer extends Named, DBObject, Configurable {
     static final String STYLE_NODENAME = "Node:Name";
     static final String STYLE_NODEVALUE = "Node:Value";
     static final String STYLE_FULLTEXT = "Node:FullText";
  
     /**
      * setCollection tells the Indexer who its parent is.
      *
      * @param collection The owner Collection
      */
     void setCollection(Collection collection);
     
     /**
      * getIndexStyle returns the Index style.  Different query languages
      * will need to draw from different indexing styles.  For example, A
      * query that is written in quilt will require XPath indexing.
      *
      * @return The index style
      */
     String getIndexStyle();
     
     /**
      * getPattern returns the pattern recognized by this Indexer.  Patterns
      * must be in the form of (elem|*)[@(attr|*)] to tell the IndexManager
      * which element types to send to it, so for example:
      * <pre>
      *    contact@name  Indexes all contacts by name attribute
      *    memo          Indexes the text of all memo elements
      *    contact@*     Indexes all contact attributes
      *    *@name        Indexes the name attribute for all elements
      *    *             Indexes the text of all elements
      *    *@*           Indexes all attributes of all elements
      * </pre>
      * These patterns are used by the IndexManager when handling SAX events.
      * All events that match the specified pattern will result in an add or
      * remove call to the Indexer.
      *
      * @return The Pattern used
      */
     String getPattern();
     
     /**
      * remove removes all references to the specified Key from the Indexer.
      *
      * @param value The value to remove
      * @param key The Object ID
      * @param pos The offset into the stream the Element occurs at
      * @param len The length of the substream for the Element
      * @param elemID The Element ID of the value
      * @param attrID The Attribute ID of the value (if any, else -1)
      */
     void remove(String value, Key key, int pos, int len, short elemID, short attrID) throws DBException;
  
     /**
      * add adds a Document to the Indexer.
      *
      * @param value The value to remove
      * @param key The Object ID
      * @param pos The offset into the stream the Element occurs at
      * @param len The length of the substream for the Element
      * @param elemID The Element ID of the value
      * @param attrID The Attribute ID of the value (if any, else -1)
      */
     void add(String value, Key key, int pos, int len, short elemID, short attrID) throws DBException;
        
     /**
      * queryMatches retrieves a set of MatchEntry instances that match
      * the supplied query.  The matches are then used by the  QueryEngine
      * in co-sequential processing.  If this indexer doesn't support the
      * passed value, it should return 'null'.  If no matches are found,
      * it should return an empty set.  queryMatches will typically be
      * used in XPath processing.
      *
      * @param query The IndexQuery to use
      * @return The resulting matches
      */
     IndexMatch[] queryMatches(IndexQuery query) throws DBException;
     
     /**
      * flush forcefully flushes any unwritten buffers to disk.
      */
     void flush() throws DBException;
  }
  
  
  
  
  1.1                  xml-xindice/Xindice/java/src/org/apache/xindice/core/indexer/IndexerException.java
  
  Index: IndexerException.java
  ===================================================================
  package org.apache.xindice.core.indexer;
  
  /*
   * The Apache Software License, Version 1.1
   *
   *
   * Copyright (c) 1999 The Apache Software Foundation.  All rights
   * reserved.
   *
   * Redistribution and use in source and binary forms, with or without
   * modification, are permitted provided that the following conditions
   * are met:
   *
   * 1. Redistributions of source code must retain the above copyright
   *    notice, this list of conditions and the following disclaimer.
   *
   * 2. Redistributions in binary form must reproduce the above copyright
   *    notice, this list of conditions and the following disclaimer in
   *    the documentation and/or other materials provided with the
   *    distribution.
   *
   * 3. The end-user documentation included with the redistribution,
   *    if any, must include the following acknowledgment:
   *       "This product includes software developed by the
   *        Apache Software Foundation (http://www.apache.org/)."
   *    Alternately, this acknowledgment may appear in the software itself,
   *    if and wherever such third-party acknowledgments normally appear.
   *
   * 4. The names "Xindice" and "Apache Software Foundation" must
   *    not be used to endorse or promote products derived from this
   *    software without prior written permission. For written
   *    permission, please contact apache@apache.org.
   *
   * 5. Products derived from this software may not be called "Apache",
   *    nor may "Apache" appear in their name, without prior written
   *    permission of the Apache Software Foundation.
   *
   * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
   * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
   * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
   * DISCLAIMED.  IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
   * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
   * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
   * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
   * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
   * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
   * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
   * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
   * SUCH DAMAGE.
   * ====================================================================
   *
   * This software consists of voluntary contributions made by many
   * individuals on behalf of the Apache Software Foundation and was
   * originally based on software copyright (c) 1999-2001, The dbXML
   * Group, L.L.C., http://www.dbxmlgroup.com.  For more
   * information on the Apache Software Foundation, please see
   * <http://www.apache.org/>.
   *
   * $Id: IndexerException.java,v 1.1 2001/12/06 21:00:12 bradford Exp $
   */
  
  import org.apache.xindice.core.*;
  
  /**
   * A IndexerException is thrown by an Indexer if an exception occurs
   * in the managing of the Indexer.
   */
  
  public class IndexerException extends DBException {
     public IndexerException(int faultCode) {
        super(faultCode);
     }
     
     public IndexerException(int faultCode, String message) {
        super(faultCode, message);
     }
  }
  
  
  
  1.1                  xml-xindice/Xindice/java/src/org/apache/xindice/core/indexer/NameIndexer.java
  
  Index: NameIndexer.java
  ===================================================================
  package org.apache.xindice.core.indexer;
  
  /*
   * The Apache Software License, Version 1.1
   *
   *
   * Copyright (c) 1999 The Apache Software Foundation.  All rights
   * reserved.
   *
   * Redistribution and use in source and binary forms, with or without
   * modification, are permitted provided that the following conditions
   * are met:
   *
   * 1. Redistributions of source code must retain the above copyright
   *    notice, this list of conditions and the following disclaimer.
   *
   * 2. Redistributions in binary form must reproduce the above copyright
   *    notice, this list of conditions and the following disclaimer in
   *    the documentation and/or other materials provided with the
   *    distribution.
   *
   * 3. The end-user documentation included with the redistribution,
   *    if any, must include the following acknowledgment:
   *       "This product includes software developed by the
   *        Apache Software Foundation (http://www.apache.org/)."
   *    Alternately, this acknowledgment may appear in the software itself,
   *    if and wherever such third-party acknowledgments normally appear.
   *
   * 4. The names "Xindice" and "Apache Software Foundation" must
   *    not be used to endorse or promote products derived from this
   *    software without prior written permission. For written
   *    permission, please contact apache@apache.org.
   *
   * 5. Products derived from this software may not be called "Apache",
   *    nor may "Apache" appear in their name, without prior written
   *    permission of the Apache Software Foundation.
   *
   * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
   * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
   * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
   * DISCLAIMED.  IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
   * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
   * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
   * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
   * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
   * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
   * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
   * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
   * SUCH DAMAGE.
   * ====================================================================
   *
   * This software consists of voluntary contributions made by many
   * individuals on behalf of the Apache Software Foundation and was
   * originally based on software copyright (c) 1999-2001, The dbXML
   * Group, L.L.C., http://www.dbxmlgroup.com.  For more
   * information on the Apache Software Foundation, please see
   * <http://www.apache.org/>.
   *
   * $Id: NameIndexer.java,v 1.1 2001/12/06 21:00:12 bradford Exp $
   */
  
  import org.apache.xindice.core.*;
  import org.apache.xindice.core.Collection;
  import org.apache.xindice.core.data.*;
  import org.apache.xindice.core.filer.*;
  import org.apache.xindice.core.query.*;
  import org.apache.xindice.util.*;
  import org.apache.xindice.xml.*;
  import org.apache.xindice.xml.dom.*;
  
  import java.io.*;
  import java.util.*;
  
  import org.w3c.dom.*;
  
  /**
   * NameIndexer is a basic implementation of the Indexer interface.
   * It is used for maintaining element and element@attribute unique
   * indexes.
   */
  
  public final class NameIndexer extends BTree implements Indexer {
     private static final IndexMatch[] EmptyMatches = new IndexMatch[0];
     private static final Value EmptyValue = new Value(new byte[0]);
     
     private static final byte MATCHES = 20;
  
     private static final String NAME = "name";
     private static final String PATTERN = "pattern";
     private static final String PAGESIZE = "pagesize";
     private static final String MAXKEYSIZE = "maxkeysize";
        
     private Configuration config;
     private Collection collection;
     private SymbolTable symbols;
  
     private String name;
     private String pattern;
     private boolean wildcard = false;
  
     private FileHeader fileHeader;
  
     public NameIndexer() {
        super();
        fileHeader = getFileHeader();
     }
  
     public void setConfig(Configuration config) {
        this.config = config;
        try {
           name = config.getAttribute(NAME);
  
           pattern = config.getAttribute(PATTERN);
           wildcard = pattern.indexOf('*') != -1;
           
           fileHeader.setPageSize(config.getIntAttribute(PAGESIZE, fileHeader.getPageSize()));
           fileHeader.setMaxKeySize(config.getShortAttribute(MAXKEYSIZE, fileHeader.getMaxKeySize()));
  
           setLocation(name);
        }
        catch ( Exception e ) {
           org.apache.xindice.Debug.printStackTrace(e);
        }
     }
  
     public Configuration getConfig() {
        return config;
     }
  
     public String getName() {
        return name;
     }
  
     public void setLocation(String location) {
        setFile(new File(collection.getCollectionRoot(), location+".idx"));
     }
  
     public void setCollection(Collection collection) {
        try {
           this.collection = collection;
           symbols = collection.getSymbols();
        }
        catch ( Exception e ) {
           org.apache.xindice.Debug.printStackTrace(e);
        }
     }
  
     public String getIndexStyle() {
        return STYLE_NODENAME;
     }
  
     public String getPattern() {
        return pattern;
     }
  
     public synchronized void remove(String value, Key key, int pos, int len, short elemID, short attrID) throws DBException {
        try {
           removeValue(key);
        }
        catch ( IOException e ) {
           throw new BTreeCorruptException("Corruption detected on remove");
        }
     }
  
     public synchronized void add(String value, Key key, int pos, int len, short elemID, short attrID) throws DBException {
        try {
           addValue(key, 0);
        }
        catch ( IOException e ) {
           throw new BTreeCorruptException("Corruption detected on add");
        }
     }
  
     public synchronized void flush() throws DBException {
        super.flush();
     }
     
     public synchronized IndexMatch[] queryMatches(final IndexQuery query) throws DBException {
        final List results = new ArrayList();
        final IndexPattern pattern = query.getPattern();
        
        try {
           query(query, new BTreeCallback() {
              public boolean indexInfo(Value value, long pos) {
                 results.add(new IndexMatch(new Key(value), pattern));
                 return true;
              }
           });
        }
        catch ( DBException d ) {
           throw d;
        }
        catch ( Exception e ) {
           org.apache.xindice.Debug.printStackTrace(e);
        }
        
        return (IndexMatch[])results.toArray(EmptyMatches);
     }
  }
  
  
  
  
  
  
  
  
  
  
  
  1.1                  xml-xindice/Xindice/java/src/org/apache/xindice/core/indexer/ValueIndexer.java
  
  Index: ValueIndexer.java
  ===================================================================
  package org.apache.xindice.core.indexer;
  
  /*
   * The Apache Software License, Version 1.1
   *
   *
   * Copyright (c) 1999 The Apache Software Foundation.  All rights
   * reserved.
   *
   * Redistribution and use in source and binary forms, with or without
   * modification, are permitted provided that the following conditions
   * are met:
   *
   * 1. Redistributions of source code must retain the above copyright
   *    notice, this list of conditions and the following disclaimer.
   *
   * 2. Redistributions in binary form must reproduce the above copyright
   *    notice, this list of conditions and the following disclaimer in
   *    the documentation and/or other materials provided with the
   *    distribution.
   *
   * 3. The end-user documentation included with the redistribution,
   *    if any, must include the following acknowledgment:
   *       "This product includes software developed by the
   *        Apache Software Foundation (http://www.apache.org/)."
   *    Alternately, this acknowledgment may appear in the software itself,
   *    if and wherever such third-party acknowledgments normally appear.
   *
   * 4. The names "Xindice" and "Apache Software Foundation" must
   *    not be used to endorse or promote products derived from this
   *    software without prior written permission. For written
   *    permission, please contact apache@apache.org.
   *
   * 5. Products derived from this software may not be called "Apache",
   *    nor may "Apache" appear in their name, without prior written
   *    permission of the Apache Software Foundation.
   *
   * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
   * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
   * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
   * DISCLAIMED.  IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
   * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
   * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
   * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
   * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
   * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
   * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
   * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
   * SUCH DAMAGE.
   * ====================================================================
   *
   * This software consists of voluntary contributions made by many
   * individuals on behalf of the Apache Software Foundation and was
   * originally based on software copyright (c) 1999-2001, The dbXML
   * Group, L.L.C., http://www.dbxmlgroup.com.  For more
   * information on the Apache Software Foundation, please see
   * <http://www.apache.org/>.
   *
   * $Id: ValueIndexer.java,v 1.1 2001/12/06 21:00:12 bradford Exp $
   */
  
  import org.apache.xindice.core.*;
  import org.apache.xindice.core.Collection;
  import org.apache.xindice.core.data.*;
  import org.apache.xindice.core.filer.*;
  import org.apache.xindice.core.query.*;
  import org.apache.xindice.util.*;
  import org.apache.xindice.xml.*;
  import org.apache.xindice.xml.dom.*;
  
  import java.io.*;
  import java.util.*;
  
  import org.w3c.dom.*;
  
  /**
   * ValueIndexer is a basic implementation of the Indexer interface.
   * It is used for maintaining element and element@attribute value
   * indexes.
   */
  
  public final class ValueIndexer extends BTree implements Indexer {
     private static final IndexMatch[] EmptyMatches = new IndexMatch[0];
     private static final Value EmptyValue = new Value(new byte[0]);
  
     private static final byte MATCHES = 20;
     private static final long MATCH_INFO = -1000;
  
     private static final String NAME = "name";
     private static final String PATTERN = "pattern";
     private static final String TYPE = "type";
     private static final String PAGESIZE = "pagesize";
     private static final String MAXKEYSIZE = "maxkeysize";
  
     private static final int STRING = 0;
     private static final int TRIMMED = 1;
     private static final int INTEGER = 2;
     private static final int FLOAT = 3;
     private static final int BYTE = 4;
     private static final int CHAR = 5;
     private static final int BOOLEAN = 6;
  
     private static final int[] sizes = { -1, -1, 8, 8, 1, 2, 1 };
  
     private static final String STRING_VAL = "string";
     private static final String TRIMMED_VAL = "trimmed";
     private static final String SHORT_VAL = "short";
     private static final String INT_VAL = "int";
     private static final String LONG_VAL = "long";
     private static final String FLOAT_VAL = "float";
     private static final String DOUBLE_VAL = "double";
     private static final String BYTE_VAL = "byte";
     private static final String CHAR_VAL = "char";
     private static final String BOOLEAN_VAL = "boolean";
  
     private Configuration config;
     private Collection collection;
     private SymbolTable symbols;
  
     private String name;
     private String pattern;
     private int type;
     private int typeSize = 32;
     private boolean wildcard = false;
  
     private FileHeader fileHeader;
  
     public ValueIndexer() {
        super();
        fileHeader = getFileHeader();
        fileHeader.setPageSize(1024);
     }
  
     public void setConfig(Configuration config) {
        this.config = config;
        try {
           name = config.getAttribute(NAME);
  
           pattern = config.getAttribute(PATTERN);
           wildcard = pattern.indexOf('*') != -1;
  
           // Determine the Index Type
           String tv = config.getAttribute(TYPE, STRING_VAL).toLowerCase();
           if ( tv.equals(STRING_VAL) )       type = STRING;
           else if ( tv.equals(TRIMMED_VAL) ) type = TRIMMED;
           else if ( tv.equals(SHORT_VAL) )   type = INTEGER;
           else if ( tv.equals(INT_VAL) )     type = INTEGER;
           else if ( tv.equals(LONG_VAL) )    type = INTEGER;
           else if ( tv.equals(FLOAT_VAL) )   type = FLOAT;
           else if ( tv.equals(DOUBLE_VAL) )  type = FLOAT;
           else if ( tv.equals(BYTE_VAL) )    type = BYTE;
           else if ( tv.equals(CHAR_VAL) )    type = CHAR;
           else if ( tv.equals(BOOLEAN_VAL) ) type = BOOLEAN;
           else {
              if ( pattern.indexOf('@') != -1 )
                 type = STRING;
              else
                 type = TRIMMED;
           }
  
           typeSize = sizes[type];
  
           fileHeader.setPageSize(config.getIntAttribute(PAGESIZE, fileHeader.getPageSize()));
           fileHeader.setMaxKeySize(config.getShortAttribute(MAXKEYSIZE, fileHeader.getMaxKeySize()));
  
           setLocation(name);
        }
        catch ( Exception e ) {
           org.apache.xindice.Debug.printStackTrace(e);
        }
     }
  
     public Configuration getConfig() {
        return config;
     }
  
     public String getName() {
        return name;
     }
  
     public void setLocation(String location) {
        setFile(new File(collection.getCollectionRoot(), location+".idx"));
     }
  
     public void setCollection(Collection collection) {
        try {
           this.collection = collection;
           symbols = collection.getSymbols();
        }
        catch ( Exception e ) {
           org.apache.xindice.Debug.printStackTrace(e);
        }
     }
  
     public String getIndexStyle() {
        return STYLE_NODEVALUE;
     }
  
     public String getPattern() {
        return pattern;
     }
  
     public Value getTypedValue(String value) {
        if ( type != STRING && type != TRIMMED ) {
           value = value.trim();
  
           if ( value.length() == 0 )
              return EmptyValue;
  
           byte[] b = new byte[typeSize];
           try {
              switch ( type ) {
                 case INTEGER:
                    long l = Long.parseLong(value);
                    b[0] = (byte)((l >>> 56) & 0xFF);
                    b[1] = (byte)((l >>> 48) & 0xFF);
                    b[2] = (byte)((l >>> 40) & 0xFF);
                    b[3] = (byte)((l >>> 32) & 0xFF);
                    b[4] = (byte)((l >>> 24) & 0xFF);
                    b[5] = (byte)((l >>> 16) & 0xFF);
                    b[6] = (byte)((l >>> 8) & 0xFF);
                    b[7] = (byte)((l >>> 0) & 0xFF);
                    break;
                 case FLOAT:
                    double d = Double.parseDouble(value);
                    int i1 = (int)Math.round(d);
                    int i2 = (int)Math.round((d-i1)*1000000000);
                    b[0] = (byte)((i1 >>> 24) & 0xFF);
                    b[1] = (byte)((i1 >>> 16) & 0xFF);
                    b[2] = (byte)((i1 >>> 8) & 0xFF);
                    b[3] = (byte)((i1 >>> 0) & 0xFF);
                    b[4] = (byte)((i2 >>> 24) & 0xFF);
                    b[5] = (byte)((i2 >>> 16) & 0xFF);
                    b[6] = (byte)((i2 >>> 8) & 0xFF);
                    b[7] = (byte)((i2 >>> 0) & 0xFF);
                    break;
                 case BYTE:
                    b[0] = Byte.parseByte(value);
                    break;
                 case CHAR:
                    char c = value.charAt(0);
                    b[0] = (byte)((c >>> 8) & 0xFF);
                    b[1] = (byte)((c >>> 0) & 0xFF);
                    break;
                 case BOOLEAN:
                    if ( "[true][yes][1][y][on]".indexOf("["+value.toString().toLowerCase()+"]") != -1 )
                       b[0] = 1;
                    else if ( "[false][no][0][n][off]".indexOf("["+value.toString().toLowerCase()+"]") != -1 )
                       b[0] = 0;
                    else
                       return EmptyValue;
                    break;
              }
              return new Value(b);
           }
           catch ( Exception e ) {
              return EmptyValue;
           }
        }
  
        if ( type == TRIMMED )
           value = QueryEngine.normalizeString(value);
  
        return new Value(value);
     }
  
     private Value getCombinedValue(Key key, int pos, int len, short elemID, short attrID) {
        Value result;
        try {
           int l = key.getLength();
           byte[] b = new byte[l+13];
           
           // Write the key
           System.arraycopy(key.getData(), 0, b, 0, l);
           b[l] = 0;
           
           // Write the pos
           b[l+1] = (byte)((pos >>> 24) & 0xFF);
           b[l+2] = (byte)((pos >>> 16) & 0xFF);
           b[l+3] = (byte)((pos >>> 8)  & 0xFF);
           b[l+4] = (byte)((pos >>> 0)  & 0xFF);
  
           // Write the len
           b[l+5] = (byte)((len >>> 24) & 0xFF);
           b[l+6] = (byte)((len >>> 16) & 0xFF);
           b[l+7] = (byte)((len >>> 8)  & 0xFF);
           b[l+8] = (byte)((len >>> 0)  & 0xFF);
  
           // Write the elemID
           b[l+9] = (byte)((elemID >>> 8)  & 0xFF);
           b[l+10] = (byte)((elemID >>> 0) & 0xFF);
           
           // Write the attrID
           b[l+11] = (byte)((attrID >>> 8) & 0xFF);
           b[l+12] = (byte)((attrID >>> 0) & 0xFF);
  
           result = new Value(b);
        }
        catch ( Exception e ) {
           result = null; // This will never happen
        }
        return result;
     }
     
     private IndexMatch getIndexMatch(Value v) {
        byte[] b = v.getData();
        int l = b.length-13;
        Key key = new Key(b, 0, b.length-13);
        
        int pos = ((b[l+1] << 24) | (b[l+2] << 16) | (b[l+3] << 8) | b[l+4]);
        int len = ((b[l+5] << 24) | (b[l+6] << 16) | (b[l+7] << 8) | b[l+8]);
        short elemID = (short)((b[l+9] << 8) | b[l+10]);
        short attrID = (short)((b[l+11] << 8) | b[l+12]);
  
        return new IndexMatch(key, pos, len, elemID, attrID);
     }
     
     public synchronized void remove(String value, Key key, int pos, int len, short elemID, short attrID) throws DBException {
        Value v = getTypedValue(value);
        if ( type != STRING && type != TRIMMED && v.getLength() == 0 )
           return;
  
        try {
           BTreeRootInfo root = findBTreeRoot(v);
           Value cv = getCombinedValue(key, pos, len, elemID, attrID);
           removeValue(root, cv);
        }
        catch ( DBException d ) {
           throw d;
        }
        catch ( Exception e ) {
           org.apache.xindice.Debug.printStackTrace(e);
        }
     }
  
     public synchronized void add(String value, Key key, int pos, int len, short elemID, short attrID) throws DBException {
        Value v = getTypedValue(value);
        if ( type != STRING && type != TRIMMED && v.getLength() == 0 )
           return;
    
        try {
           BTreeRootInfo root;
           
           try {
              root = findBTreeRoot(v);
           }
           catch ( BTreeNotFoundException e ) {
              root = createBTreeRoot(v);
           }
  
           Value cv = getCombinedValue(key, pos, len, elemID, attrID);
           addValue(root, cv, MATCH_INFO);
        }
        catch ( DBException d ) {
           throw d;
        }
        catch ( IOException e ) {
           throw new BTreeCorruptException("Corruption detected on add");
        }
        catch ( Exception e ) {
           org.apache.xindice.Debug.printStackTrace(e);
        }
     }
  
     public synchronized void flush() throws DBException {
        super.flush();
     }
     
     public synchronized IndexMatch[] queryMatches(final IndexQuery query) throws DBException {
        // Pre-process the value-set for typing and trimming
        if ( type != STRING ) {
           Value[] vals = query.getValues();
           for ( int i = 0; i < vals.length; i++ )
              vals[i] = getTypedValue(vals[i].toString());
        }
  
        // Now issue the query
        final List results = new ArrayList();
  
        try {
           query(query, new BTreeCallback() {
              public boolean indexInfo(Value value, long pos) {
                 try {
                    if ( pos == MATCH_INFO ) {
                       IndexMatch match = getIndexMatch(value);
                       if ( !wildcard )
                          results.add(match);
                       else {
                          IndexPattern pt = new IndexPattern(symbols, match.getElement(), match.getAttribute());
                          if ( pt.getMatchLevel(query.getPattern()) > 0 )
                             results.add(match);
                       }
                    }
                    else {
                       BTreeRootInfo root = new BTreeRootInfo(value, pos);
                       query(root, null, this);
                    }
                    return true;
                 }
                 catch ( Exception e ) {
                    org.apache.xindice.Debug.printStackTrace(e);
                 }
                 return true;
              }
           });
        }
        catch ( IOException e ) {
           throw new BTreeCorruptException("Corruption detected on query");
        }
        catch ( Exception e ) {
           org.apache.xindice.Debug.printStackTrace(e);
        }
  
        return (IndexMatch[])results.toArray(EmptyMatches);
     }
  }
  
  
  
  
  
  1.1                  xml-xindice/Xindice/java/src/org/apache/xindice/core/indexer/package.html
  
  Index: package.html
  ===================================================================
  <html>
    <title>Xindice Indexers.</title>
    <body>
      <p>Defines the Xindice Indexer interface and implements the
      IndexManager, and NodeIndexer classes.</p>
   </body>
  </html>
  
  
  
  
  
  1.1                  xml-xindice/Xindice/java/src/org/apache/xindice/core/indexer/helpers/IndexQueryANY.java
  
  Index: IndexQueryANY.java
  ===================================================================
  package org.apache.xindice.core.indexer.helpers;
  
  /*
   * The Apache Software License, Version 1.1
   *
   *
   * Copyright (c) 1999 The Apache Software Foundation.  All rights
   * reserved.
   *
   * Redistribution and use in source and binary forms, with or without
   * modification, are permitted provided that the following conditions
   * are met:
   *
   * 1. Redistributions of source code must retain the above copyright
   *    notice, this list of conditions and the following disclaimer.
   *
   * 2. Redistributions in binary form must reproduce the above copyright
   *    notice, this list of conditions and the following disclaimer in
   *    the documentation and/or other materials provided with the
   *    distribution.
   *
   * 3. The end-user documentation included with the redistribution,
   *    if any, must include the following acknowledgment:
   *       "This product includes software developed by the
   *        Apache Software Foundation (http://www.apache.org/)."
   *    Alternately, this acknowledgment may appear in the software itself,
   *    if and wherever such third-party acknowledgments normally appear.
   *
   * 4. The names "Xindice" and "Apache Software Foundation" must
   *    not be used to endorse or promote products derived from this
   *    software without prior written permission. For written
   *    permission, please contact apache@apache.org.
   *
   * 5. Products derived from this software may not be called "Apache",
   *    nor may "Apache" appear in their name, without prior written
   *    permission of the Apache Software Foundation.
   *
   * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
   * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
   * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
   * DISCLAIMED.  IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
   * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
   * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
   * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
   * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
   * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
   * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
   * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
   * SUCH DAMAGE.
   * ====================================================================
   *
   * This software consists of voluntary contributions made by many
   * individuals on behalf of the Apache Software Foundation and was
   * originally based on software copyright (c) 1999-2001, The dbXML
   * Group, L.L.C., http://www.dbxmlgroup.com.  For more
   * information on the Apache Software Foundation, please see
   * <http://www.apache.org/>.
   *
   * $Id: IndexQueryANY.java,v 1.1 2001/12/06 21:00:12 bradford Exp $
   */
  
  import org.apache.xindice.core.data.*;
  import org.apache.xindice.core.indexer.*;
  
  /**
   * IndexQueryANY
   */
  
  public final class IndexQueryANY extends IndexQuery {
     public IndexQueryANY(IndexPattern pattern) {
        super(pattern);
     }
  
     public int getOperator() {
        return ANY;
     }
  
     public boolean testValue(Value value) {
        return true;
     }
  }
  
  
  
  1.1                  xml-xindice/Xindice/java/src/org/apache/xindice/core/indexer/helpers/IndexQueryBW.java
  
  Index: IndexQueryBW.java
  ===================================================================
  package org.apache.xindice.core.indexer.helpers;
  
  /*
   * The Apache Software License, Version 1.1
   *
   *
   * Copyright (c) 1999 The Apache Software Foundation.  All rights
   * reserved.
   *
   * Redistribution and use in source and binary forms, with or without
   * modification, are permitted provided that the following conditions
   * are met:
   *
   * 1. Redistributions of source code must retain the above copyright
   *    notice, this list of conditions and the following disclaimer.
   *
   * 2. Redistributions in binary form must reproduce the above copyright
   *    notice, this list of conditions and the following disclaimer in
   *    the documentation and/or other materials provided with the
   *    distribution.
   *
   * 3. The end-user documentation included with the redistribution,
   *    if any, must include the following acknowledgment:
   *       "This product includes software developed by the
   *        Apache Software Foundation (http://www.apache.org/)."
   *    Alternately, this acknowledgment may appear in the software itself,
   *    if and wherever such third-party acknowledgments normally appear.
   *
   * 4. The names "Xindice" and "Apache Software Foundation" must
   *    not be used to endorse or promote products derived from this
   *    software without prior written permission. For written
   *    permission, please contact apache@apache.org.
   *
   * 5. Products derived from this software may not be called "Apache",
   *    nor may "Apache" appear in their name, without prior written
   *    permission of the Apache Software Foundation.
   *
   * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
   * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
   * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
   * DISCLAIMED.  IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
   * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
   * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
   * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
   * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
   * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
   * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
   * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
   * SUCH DAMAGE.
   * ====================================================================
   *
   * This software consists of voluntary contributions made by many
   * individuals on behalf of the Apache Software Foundation and was
   * originally based on software copyright (c) 1999-2001, The dbXML
   * Group, L.L.C., http://www.dbxmlgroup.com.  For more
   * information on the Apache Software Foundation, please see
   * <http://www.apache.org/>.
   *
   * $Id: IndexQueryBW.java,v 1.1 2001/12/06 21:00:12 bradford Exp $
   */
  
  import org.apache.xindice.core.data.*;
  import org.apache.xindice.core.indexer.*;
  
  /**
   * IndexQueryBW
   */
  
  public final class IndexQueryBW extends IndexQuery {
     public IndexQueryBW(IndexPattern pattern, Value val1, Value val2) {
        super(pattern, BW, val1, val2);
     }
  
     public IndexQueryBW(IndexPattern pattern, String val1, String val2) {
        super(pattern, BW, val1, val2);
     }
  
     public int getOperator() {
        return BW;
     }
  
     public boolean testValue(Value value) {
        return value.compareTo(vals[0]) >= 0 && value.compareTo(vals[1]) <= 0;
     }
  }
  
  
  
  
  1.1                  xml-xindice/Xindice/java/src/org/apache/xindice/core/indexer/helpers/IndexQueryBWX.java
  
  Index: IndexQueryBWX.java
  ===================================================================
  package org.apache.xindice.core.indexer.helpers;
  
  /*
   * The Apache Software License, Version 1.1
   *
   *
   * Copyright (c) 1999 The Apache Software Foundation.  All rights
   * reserved.
   *
   * Redistribution and use in source and binary forms, with or without
   * modification, are permitted provided that the following conditions
   * are met:
   *
   * 1. Redistributions of source code must retain the above copyright
   *    notice, this list of conditions and the following disclaimer.
   *
   * 2. Redistributions in binary form must reproduce the above copyright
   *    notice, this list of conditions and the following disclaimer in
   *    the documentation and/or other materials provided with the
   *    distribution.
   *
   * 3. The end-user documentation included with the redistribution,
   *    if any, must include the following acknowledgment:
   *       "This product includes software developed by the
   *        Apache Software Foundation (http://www.apache.org/)."
   *    Alternately, this acknowledgment may appear in the software itself,
   *    if and wherever such third-party acknowledgments normally appear.
   *
   * 4. The names "Xindice" and "Apache Software Foundation" must
   *    not be used to endorse or promote products derived from this
   *    software without prior written permission. For written
   *    permission, please contact apache@apache.org.
   *
   * 5. Products derived from this software may not be called "Apache",
   *    nor may "Apache" appear in their name, without prior written
   *    permission of the Apache Software Foundation.
   *
   * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
   * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
   * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
   * DISCLAIMED.  IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
   * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
   * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
   * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
   * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
   * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
   * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
   * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
   * SUCH DAMAGE.
   * ====================================================================
   *
   * This software consists of voluntary contributions made by many
   * individuals on behalf of the Apache Software Foundation and was
   * originally based on software copyright (c) 1999-2001, The dbXML
   * Group, L.L.C., http://www.dbxmlgroup.com.  For more
   * information on the Apache Software Foundation, please see
   * <http://www.apache.org/>.
   *
   * $Id: IndexQueryBWX.java,v 1.1 2001/12/06 21:00:12 bradford Exp $
   */
  
  import org.apache.xindice.core.data.*;
  import org.apache.xindice.core.indexer.*;
  
  /**
   * IndexQueryBWX
   */
  
  public final class IndexQueryBWX extends IndexQuery {
     public IndexQueryBWX(IndexPattern pattern, Value val1, Value val2) {
        super(pattern, BWX, val1, val2);
     }
  
     public IndexQueryBWX(IndexPattern pattern, String val1, String val2) {
        super(pattern, BWX, val1, val2);
     }
  
     public int getOperator() {
        return BWX;
     }
  
     public boolean testValue(Value value) {
        return value.compareTo(vals[0]) > 0 && value.compareTo(vals[1]) < 0;
     }
  }
  
  
  
  
  1.1                  xml-xindice/Xindice/java/src/org/apache/xindice/core/indexer/helpers/IndexQueryEQ.java
  
  Index: IndexQueryEQ.java
  ===================================================================
  package org.apache.xindice.core.indexer.helpers;
  
  /*
   * The Apache Software License, Version 1.1
   *
   *
   * Copyright (c) 1999 The Apache Software Foundation.  All rights
   * reserved.
   *
   * Redistribution and use in source and binary forms, with or without
   * modification, are permitted provided that the following conditions
   * are met:
   *
   * 1. Redistributions of source code must retain the above copyright
   *    notice, this list of conditions and the following disclaimer.
   *
   * 2. Redistributions in binary form must reproduce the above copyright
   *    notice, this list of conditions and the following disclaimer in
   *    the documentation and/or other materials provided with the
   *    distribution.
   *
   * 3. The end-user documentation included with the redistribution,
   *    if any, must include the following acknowledgment:
   *       "This product includes software developed by the
   *        Apache Software Foundation (http://www.apache.org/)."
   *    Alternately, this acknowledgment may appear in the software itself,
   *    if and wherever such third-party acknowledgments normally appear.
   *
   * 4. The names "Xindice" and "Apache Software Foundation" must
   *    not be used to endorse or promote products derived from this
   *    software without prior written permission. For written
   *    permission, please contact apache@apache.org.
   *
   * 5. Products derived from this software may not be called "Apache",
   *    nor may "Apache" appear in their name, without prior written
   *    permission of the Apache Software Foundation.
   *
   * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
   * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
   * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
   * DISCLAIMED.  IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
   * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
   * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
   * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
   * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
   * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
   * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
   * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
   * SUCH DAMAGE.
   * ====================================================================
   *
   * This software consists of voluntary contributions made by many
   * individuals on behalf of the Apache Software Foundation and was
   * originally based on software copyright (c) 1999-2001, The dbXML
   * Group, L.L.C., http://www.dbxmlgroup.com.  For more
   * information on the Apache Software Foundation, please see
   * <http://www.apache.org/>.
   *
   * $Id: IndexQueryEQ.java,v 1.1 2001/12/06 21:00:12 bradford Exp $
   */
  
  import org.apache.xindice.core.data.*;
  import org.apache.xindice.core.indexer.*;
  
  /**
   * IndexQueryEQ
   */
  
  public final class IndexQueryEQ extends IndexQuery {
     public IndexQueryEQ(IndexPattern pattern, Value val1) {
        super(pattern, EQ, val1);
     }
  
     public IndexQueryEQ(IndexPattern pattern, String val1) {
        super(pattern, EQ, val1);
     }
  
     public int getOperator() {
        return EQ;
     }
  
     public boolean testValue(Value value) {
        return value.equals(vals[0]);
     }
  }
  
  
  
  
  1.1                  xml-xindice/Xindice/java/src/org/apache/xindice/core/indexer/helpers/IndexQueryGEQ.java
  
  Index: IndexQueryGEQ.java
  ===================================================================
  package org.apache.xindice.core.indexer.helpers;
  
  /*
   * The Apache Software License, Version 1.1
   *
   *
   * Copyright (c) 1999 The Apache Software Foundation.  All rights
   * reserved.
   *
   * Redistribution and use in source and binary forms, with or without
   * modification, are permitted provided that the following conditions
   * are met:
   *
   * 1. Redistributions of source code must retain the above copyright
   *    notice, this list of conditions and the following disclaimer.
   *
   * 2. Redistributions in binary form must reproduce the above copyright
   *    notice, this list of conditions and the following disclaimer in
   *    the documentation and/or other materials provided with the
   *    distribution.
   *
   * 3. The end-user documentation included with the redistribution,
   *    if any, must include the following acknowledgment:
   *       "This product includes software developed by the
   *        Apache Software Foundation (http://www.apache.org/)."
   *    Alternately, this acknowledgment may appear in the software itself,
   *    if and wherever such third-party acknowledgments normally appear.
   *
   * 4. The names "Xindice" and "Apache Software Foundation" must
   *    not be used to endorse or promote products derived from this
   *    software without prior written permission. For written
   *    permission, please contact apache@apache.org.
   *
   * 5. Products derived from this software may not be called "Apache",
   *    nor may "Apache" appear in their name, without prior written
   *    permission of the Apache Software Foundation.
   *
   * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
   * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
   * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
   * DISCLAIMED.  IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
   * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
   * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
   * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
   * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
   * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
   * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
   * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
   * SUCH DAMAGE.
   * ====================================================================
   *
   * This software consists of voluntary contributions made by many
   * individuals on behalf of the Apache Software Foundation and was
   * originally based on software copyright (c) 1999-2001, The dbXML
   * Group, L.L.C., http://www.dbxmlgroup.com.  For more
   * information on the Apache Software Foundation, please see
   * <http://www.apache.org/>.
   *
   * $Id: IndexQueryGEQ.java,v 1.1 2001/12/06 21:00:12 bradford Exp $
   */
  
  import org.apache.xindice.core.data.*;
  import org.apache.xindice.core.indexer.*;
  
  /**
   * IndexQueryGEQ
   */
  
  public final class IndexQueryGEQ extends IndexQuery {
     public IndexQueryGEQ(IndexPattern pattern, Value val1) {
        super(pattern, GEQ, val1);
     }
  
     public IndexQueryGEQ(IndexPattern pattern, String val1) {
        super(pattern, GEQ, val1);
     }
  
     public int getOperator() {
        return GEQ;
     }
  
     public boolean testValue(Value value) {
        return value.compareTo(vals[0]) >= 0;
     }
  }
  
  
  
  
  1.1                  xml-xindice/Xindice/java/src/org/apache/xindice/core/indexer/helpers/IndexQueryGT.java
  
  Index: IndexQueryGT.java
  ===================================================================
  package org.apache.xindice.core.indexer.helpers;
  
  /*
   * The Apache Software License, Version 1.1
   *
   *
   * Copyright (c) 1999 The Apache Software Foundation.  All rights
   * reserved.
   *
   * Redistribution and use in source and binary forms, with or without
   * modification, are permitted provided that the following conditions
   * are met:
   *
   * 1. Redistributions of source code must retain the above copyright
   *    notice, this list of conditions and the following disclaimer.
   *
   * 2. Redistributions in binary form must reproduce the above copyright
   *    notice, this list of conditions and the following disclaimer in
   *    the documentation and/or other materials provided with the
   *    distribution.
   *
   * 3. The end-user documentation included with the redistribution,
   *    if any, must include the following acknowledgment:
   *       "This product includes software developed by the
   *        Apache Software Foundation (http://www.apache.org/)."
   *    Alternately, this acknowledgment may appear in the software itself,
   *    if and wherever such third-party acknowledgments normally appear.
   *
   * 4. The names "Xindice" and "Apache Software Foundation" must
   *    not be used to endorse or promote products derived from this
   *    software without prior written permission. For written
   *    permission, please contact apache@apache.org.
   *
   * 5. Products derived from this software may not be called "Apache",
   *    nor may "Apache" appear in their name, without prior written
   *    permission of the Apache Software Foundation.
   *
   * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
   * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
   * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
   * DISCLAIMED.  IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
   * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
   * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
   * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
   * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
   * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
   * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
   * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
   * SUCH DAMAGE.
   * ====================================================================
   *
   * This software consists of voluntary contributions made by many
   * individuals on behalf of the Apache Software Foundation and was
   * originally based on software copyright (c) 1999-2001, The dbXML
   * Group, L.L.C., http://www.dbxmlgroup.com.  For more
   * information on the Apache Software Foundation, please see
   * <http://www.apache.org/>.
   *
   * $Id: IndexQueryGT.java,v 1.1 2001/12/06 21:00:12 bradford Exp $
   */
  
  import org.apache.xindice.core.data.*;
  import org.apache.xindice.core.indexer.*;
  
  /**
   * IndexQueryGT
   */
  
  public final class IndexQueryGT extends IndexQuery {
     public IndexQueryGT(IndexPattern pattern, Value val1) {
        super(pattern, GT, val1);
     }
  
     public IndexQueryGT(IndexPattern pattern, String val1) {
        super(pattern, GT, val1);
     }
  
     public int getOperator() {
        return GT;
     }
  
     public boolean testValue(Value value) {
        return value.compareTo(vals[0]) > 0;
     }
  }
  
  
  
  
  1.1                  xml-xindice/Xindice/java/src/org/apache/xindice/core/indexer/helpers/IndexQueryIN.java
  
  Index: IndexQueryIN.java
  ===================================================================
  package org.apache.xindice.core.indexer.helpers;
  
  /*
   * The Apache Software License, Version 1.1
   *
   *
   * Copyright (c) 1999 The Apache Software Foundation.  All rights
   * reserved.
   *
   * Redistribution and use in source and binary forms, with or without
   * modification, are permitted provided that the following conditions
   * are met:
   *
   * 1. Redistributions of source code must retain the above copyright
   *    notice, this list of conditions and the following disclaimer.
   *
   * 2. Redistributions in binary form must reproduce the above copyright
   *    notice, this list of conditions and the following disclaimer in
   *    the documentation and/or other materials provided with the
   *    distribution.
   *
   * 3. The end-user documentation included with the redistribution,
   *    if any, must include the following acknowledgment:
   *       "This product includes software developed by the
   *        Apache Software Foundation (http://www.apache.org/)."
   *    Alternately, this acknowledgment may appear in the software itself,
   *    if and wherever such third-party acknowledgments normally appear.
   *
   * 4. The names "Xindice" and "Apache Software Foundation" must
   *    not be used to endorse or promote products derived from this
   *    software without prior written permission. For written
   *    permission, please contact apache@apache.org.
   *
   * 5. Products derived from this software may not be called "Apache",
   *    nor may "Apache" appear in their name, without prior written
   *    permission of the Apache Software Foundation.
   *
   * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
   * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
   * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
   * DISCLAIMED.  IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
   * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
   * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
   * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
   * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
   * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
   * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
   * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
   * SUCH DAMAGE.
   * ====================================================================
   *
   * This software consists of voluntary contributions made by many
   * individuals on behalf of the Apache Software Foundation and was
   * originally based on software copyright (c) 1999-2001, The dbXML
   * Group, L.L.C., http://www.dbxmlgroup.com.  For more
   * information on the Apache Software Foundation, please see
   * <http://www.apache.org/>.
   *
   * $Id: IndexQueryIN.java,v 1.1 2001/12/06 21:00:12 bradford Exp $
   */
  
  import org.apache.xindice.core.data.*;
  import org.apache.xindice.core.indexer.*;
  import java.util.*;
  
  /**
   * IndexQueryIN
   */
  
  public final class IndexQueryIN extends IndexQuery {
     public IndexQueryIN(IndexPattern pattern, Value[] vals) {
        super(pattern, IN, vals);
     }
  
     public int getOperator() {
        return IN;
     }
  
     public boolean testValue(Value value) {
        return Arrays.binarySearch(vals, value) >= 0;
     }
  }
  
  
  
  
  1.1                  xml-xindice/Xindice/java/src/org/apache/xindice/core/indexer/helpers/IndexQueryLEQ.java
  
  Index: IndexQueryLEQ.java
  ===================================================================
  package org.apache.xindice.core.indexer.helpers;
  
  /*
   * The Apache Software License, Version 1.1
   *
   *
   * Copyright (c) 1999 The Apache Software Foundation.  All rights
   * reserved.
   *
   * Redistribution and use in source and binary forms, with or without
   * modification, are permitted provided that the following conditions
   * are met:
   *
   * 1. Redistributions of source code must retain the above copyright
   *    notice, this list of conditions and the following disclaimer.
   *
   * 2. Redistributions in binary form must reproduce the above copyright
   *    notice, this list of conditions and the following disclaimer in
   *    the documentation and/or other materials provided with the
   *    distribution.
   *
   * 3. The end-user documentation included with the redistribution,
   *    if any, must include the following acknowledgment:
   *       "This product includes software developed by the
   *        Apache Software Foundation (http://www.apache.org/)."
   *    Alternately, this acknowledgment may appear in the software itself,
   *    if and wherever such third-party acknowledgments normally appear.
   *
   * 4. The names "Xindice" and "Apache Software Foundation" must
   *    not be used to endorse or promote products derived from this
   *    software without prior written permission. For written
   *    permission, please contact apache@apache.org.
   *
   * 5. Products derived from this software may not be called "Apache",
   *    nor may "Apache" appear in their name, without prior written
   *    permission of the Apache Software Foundation.
   *
   * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
   * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
   * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
   * DISCLAIMED.  IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
   * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
   * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
   * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
   * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
   * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
   * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
   * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
   * SUCH DAMAGE.
   * ====================================================================
   *
   * This software consists of voluntary contributions made by many
   * individuals on behalf of the Apache Software Foundation and was
   * originally based on software copyright (c) 1999-2001, The dbXML
   * Group, L.L.C., http://www.dbxmlgroup.com.  For more
   * information on the Apache Software Foundation, please see
   * <http://www.apache.org/>.
   *
   * $Id: IndexQueryLEQ.java,v 1.1 2001/12/06 21:00:12 bradford Exp $
   */
  
  import org.apache.xindice.core.data.*;
  import org.apache.xindice.core.indexer.*;
  
  /**
   * IndexQueryLEQ
   */
  
  public final class IndexQueryLEQ extends IndexQuery {
     public IndexQueryLEQ(IndexPattern pattern, Value val1) {
        super(pattern, LEQ, val1);
     }
  
     public IndexQueryLEQ(IndexPattern pattern, String val1) {
        super(pattern, LEQ, val1);
     }
  
     public int getOperator() {
        return LEQ;
     }
  
     public boolean testValue(Value value) {
        return value.compareTo(vals[0]) <= 0;
     }
  }
  
  
  
  
  1.1                  xml-xindice/Xindice/java/src/org/apache/xindice/core/indexer/helpers/IndexQueryLT.java
  
  Index: IndexQueryLT.java
  ===================================================================
  package org.apache.xindice.core.indexer.helpers;
  
  /*
   * The Apache Software License, Version 1.1
   *
   *
   * Copyright (c) 1999 The Apache Software Foundation.  All rights
   * reserved.
   *
   * Redistribution and use in source and binary forms, with or without
   * modification, are permitted provided that the following conditions
   * are met:
   *
   * 1. Redistributions of source code must retain the above copyright
   *    notice, this list of conditions and the following disclaimer.
   *
   * 2. Redistributions in binary form must reproduce the above copyright
   *    notice, this list of conditions and the following disclaimer in
   *    the documentation and/or other materials provided with the
   *    distribution.
   *
   * 3. The end-user documentation included with the redistribution,
   *    if any, must include the following acknowledgment:
   *       "This product includes software developed by the
   *        Apache Software Foundation (http://www.apache.org/)."
   *    Alternately, this acknowledgment may appear in the software itself,
   *    if and wherever such third-party acknowledgments normally appear.
   *
   * 4. The names "Xindice" and "Apache Software Foundation" must
   *    not be used to endorse or promote products derived from this
   *    software without prior written permission. For written
   *    permission, please contact apache@apache.org.
   *
   * 5. Products derived from this software may not be called "Apache",
   *    nor may "Apache" appear in their name, without prior written
   *    permission of the Apache Software Foundation.
   *
   * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
   * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
   * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
   * DISCLAIMED.  IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
   * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
   * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
   * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
   * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
   * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
   * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
   * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
   * SUCH DAMAGE.
   * ====================================================================
   *
   * This software consists of voluntary contributions made by many
   * individuals on behalf of the Apache Software Foundation and was
   * originally based on software copyright (c) 1999-2001, The dbXML
   * Group, L.L.C., http://www.dbxmlgroup.com.  For more
   * information on the Apache Software Foundation, please see
   * <http://www.apache.org/>.
   *
   * $Id: IndexQueryLT.java,v 1.1 2001/12/06 21:00:12 bradford Exp $
   */
  
  import org.apache.xindice.core.data.*;
  import org.apache.xindice.core.indexer.*;
  
  /**
   * IndexQueryLT
   */
  
  public final class IndexQueryLT extends IndexQuery {
     public IndexQueryLT(IndexPattern pattern, Value val1) {
        super(pattern, LT, val1);
     }
  
     public IndexQueryLT(IndexPattern pattern, String val1) {
        super(pattern, LT, val1);
     }
  
     public int getOperator() {
        return LT;
     }
  
     public boolean testValue(Value value) {
        return value.compareTo(vals[0]) < 0;
     }
  }
  
  
  
  
  1.1                  xml-xindice/Xindice/java/src/org/apache/xindice/core/indexer/helpers/IndexQueryNBW.java
  
  Index: IndexQueryNBW.java
  ===================================================================
  package org.apache.xindice.core.indexer.helpers;
  
  /*
   * The Apache Software License, Version 1.1
   *
   *
   * Copyright (c) 1999 The Apache Software Foundation.  All rights
   * reserved.
   *
   * Redistribution and use in source and binary forms, with or without
   * modification, are permitted provided that the following conditions
   * are met:
   *
   * 1. Redistributions of source code must retain the above copyright
   *    notice, this list of conditions and the following disclaimer.
   *
   * 2. Redistributions in binary form must reproduce the above copyright
   *    notice, this list of conditions and the following disclaimer in
   *    the documentation and/or other materials provided with the
   *    distribution.
   *
   * 3. The end-user documentation included with the redistribution,
   *    if any, must include the following acknowledgment:
   *       "This product includes software developed by the
   *        Apache Software Foundation (http://www.apache.org/)."
   *    Alternately, this acknowledgment may appear in the software itself,
   *    if and wherever such third-party acknowledgments normally appear.
   *
   * 4. The names "Xindice" and "Apache Software Foundation" must
   *    not be used to endorse or promote products derived from this
   *    software without prior written permission. For written
   *    permission, please contact apache@apache.org.
   *
   * 5. Products derived from this software may not be called "Apache",
   *    nor may "Apache" appear in their name, without prior written
   *    permission of the Apache Software Foundation.
   *
   * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
   * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
   * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
   * DISCLAIMED.  IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
   * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
   * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
   * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
   * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
   * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
   * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
   * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
   * SUCH DAMAGE.
   * ====================================================================
   *
   * This software consists of voluntary contributions made by many
   * individuals on behalf of the Apache Software Foundation and was
   * originally based on software copyright (c) 1999-2001, The dbXML
   * Group, L.L.C., http://www.dbxmlgroup.com.  For more
   * information on the Apache Software Foundation, please see
   * <http://www.apache.org/>.
   *
   * $Id: IndexQueryNBW.java,v 1.1 2001/12/06 21:00:12 bradford Exp $
   */
  
  import org.apache.xindice.core.data.*;
  import org.apache.xindice.core.indexer.*;
  
  /**
   * IndexQueryNBW
   */
  
  public final class IndexQueryNBW extends IndexQuery {
     public IndexQueryNBW(IndexPattern pattern, Value val1, Value val2) {
        super(pattern, NBW, val1, val2);
     }
  
     public IndexQueryNBW(IndexPattern pattern, String val1, String val2) {
        super(pattern, NBW, val1, val2);
     }
  
     public int getOperator() {
        return NBW;
     }
  
     public boolean testValue(Value value) {
        return value.compareTo(vals[0]) <= 0 || value.compareTo(vals[1]) >= 0;
     }
  }
  
  
  
  
  1.1                  xml-xindice/Xindice/java/src/org/apache/xindice/core/indexer/helpers/IndexQueryNBWX.java
  
  Index: IndexQueryNBWX.java
  ===================================================================
  package org.apache.xindice.core.indexer.helpers;
  
  /*
   * The Apache Software License, Version 1.1
   *
   *
   * Copyright (c) 1999 The Apache Software Foundation.  All rights
   * reserved.
   *
   * Redistribution and use in source and binary forms, with or without
   * modification, are permitted provided that the following conditions
   * are met:
   *
   * 1. Redistributions of source code must retain the above copyright
   *    notice, this list of conditions and the following disclaimer.
   *
   * 2. Redistributions in binary form must reproduce the above copyright
   *    notice, this list of conditions and the following disclaimer in
   *    the documentation and/or other materials provided with the
   *    distribution.
   *
   * 3. The end-user documentation included with the redistribution,
   *    if any, must include the following acknowledgment:
   *       "This product includes software developed by the
   *        Apache Software Foundation (http://www.apache.org/)."
   *    Alternately, this acknowledgment may appear in the software itself,
   *    if and wherever such third-party acknowledgments normally appear.
   *
   * 4. The names "Xindice" and "Apache Software Foundation" must
   *    not be used to endorse or promote products derived from this
   *    software without prior written permission. For written
   *    permission, please contact apache@apache.org.
   *
   * 5. Products derived from this software may not be called "Apache",
   *    nor may "Apache" appear in their name, without prior written
   *    permission of the Apache Software Foundation.
   *
   * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
   * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
   * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
   * DISCLAIMED.  IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
   * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
   * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
   * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
   * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
   * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
   * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
   * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
   * SUCH DAMAGE.
   * ====================================================================
   *
   * This software consists of voluntary contributions made by many
   * individuals on behalf of the Apache Software Foundation and was
   * originally based on software copyright (c) 1999-2001, The dbXML
   * Group, L.L.C., http://www.dbxmlgroup.com.  For more
   * information on the Apache Software Foundation, please see
   * <http://www.apache.org/>.
   *
   * $Id: IndexQueryNBWX.java,v 1.1 2001/12/06 21:00:13 bradford Exp $
   */
  
  import org.apache.xindice.core.data.*;
  import org.apache.xindice.core.indexer.*;
  
  /**
   * IndexQueryNBWX
   */
  
  public final class IndexQueryNBWX extends IndexQuery {
     public IndexQueryNBWX(IndexPattern pattern, Value val1, Value val2) {
        super(pattern, NBWX, val1, val2);
     }
  
     public IndexQueryNBWX(IndexPattern pattern, String val1, String val2) {
        super(pattern, NBWX, val1, val2);
     }
  
     public int getOperator() {
        return NBWX;
     }
  
     public boolean testValue(Value value) {
        return value.compareTo(vals[0]) < 0 || value.compareTo(vals[1]) > 0;
     }
  }
  
  
  
  
  1.1                  xml-xindice/Xindice/java/src/org/apache/xindice/core/indexer/helpers/IndexQueryNEQ.java
  
  Index: IndexQueryNEQ.java
  ===================================================================
  package org.apache.xindice.core.indexer.helpers;
  
  /*
   * The Apache Software License, Version 1.1
   *
   *
   * Copyright (c) 1999 The Apache Software Foundation.  All rights
   * reserved.
   *
   * Redistribution and use in source and binary forms, with or without
   * modification, are permitted provided that the following conditions
   * are met:
   *
   * 1. Redistributions of source code must retain the above copyright
   *    notice, this list of conditions and the following disclaimer.
   *
   * 2. Redistributions in binary form must reproduce the above copyright
   *    notice, this list of conditions and the following disclaimer in
   *    the documentation and/or other materials provided with the
   *    distribution.
   *
   * 3. The end-user documentation included with the redistribution,
   *    if any, must include the following acknowledgment:
   *       "This product includes software developed by the
   *        Apache Software Foundation (http://www.apache.org/)."
   *    Alternately, this acknowledgment may appear in the software itself,
   *    if and wherever such third-party acknowledgments normally appear.
   *
   * 4. The names "Xindice" and "Apache Software Foundation" must
   *    not be used to endorse or promote products derived from this
   *    software without prior written permission. For written
   *    permission, please contact apache@apache.org.
   *
   * 5. Products derived from this software may not be called "Apache",
   *    nor may "Apache" appear in their name, without prior written
   *    permission of the Apache Software Foundation.
   *
   * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
   * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
   * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
   * DISCLAIMED.  IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
   * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
   * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
   * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
   * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
   * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
   * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
   * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
   * SUCH DAMAGE.
   * ====================================================================
   *
   * This software consists of voluntary contributions made by many
   * individuals on behalf of the Apache Software Foundation and was
   * originally based on software copyright (c) 1999-2001, The dbXML
   * Group, L.L.C., http://www.dbxmlgroup.com.  For more
   * information on the Apache Software Foundation, please see
   * <http://www.apache.org/>.
   *
   * $Id: IndexQueryNEQ.java,v 1.1 2001/12/06 21:00:13 bradford Exp $
   */
  
  import org.apache.xindice.core.data.*;
  import org.apache.xindice.core.indexer.*;
  
  /**
   * IndexQueryNEQ
   */
  
  public final class IndexQueryNEQ extends IndexQuery {
     public IndexQueryNEQ(IndexPattern pattern, Value val1) {
        super(pattern, NEQ, val1);
     }
  
     public IndexQueryNEQ(IndexPattern pattern, String val1) {
        super(pattern, NEQ, val1);
     }
  
     public int getOperator() {
        return NEQ;
     }
  
     public boolean testValue(Value value) {
        return !value.equals(vals[0]);
     }
  }
  
  
  
  
  1.1                  xml-xindice/Xindice/java/src/org/apache/xindice/core/indexer/helpers/IndexQueryNIN.java
  
  Index: IndexQueryNIN.java
  ===================================================================
  package org.apache.xindice.core.indexer.helpers;
  
  /*
   * The Apache Software License, Version 1.1
   *
   *
   * Copyright (c) 1999 The Apache Software Foundation.  All rights
   * reserved.
   *
   * Redistribution and use in source and binary forms, with or without
   * modification, are permitted provided that the following conditions
   * are met:
   *
   * 1. Redistributions of source code must retain the above copyright
   *    notice, this list of conditions and the following disclaimer.
   *
   * 2. Redistributions in binary form must reproduce the above copyright
   *    notice, this list of conditions and the following disclaimer in
   *    the documentation and/or other materials provided with the
   *    distribution.
   *
   * 3. The end-user documentation included with the redistribution,
   *    if any, must include the following acknowledgment:
   *       "This product includes software developed by the
   *        Apache Software Foundation (http://www.apache.org/)."
   *    Alternately, this acknowledgment may appear in the software itself,
   *    if and wherever such third-party acknowledgments normally appear.
   *
   * 4. The names "Xindice" and "Apache Software Foundation" must
   *    not be used to endorse or promote products derived from this
   *    software without prior written permission. For written
   *    permission, please contact apache@apache.org.
   *
   * 5. Products derived from this software may not be called "Apache",
   *    nor may "Apache" appear in their name, without prior written
   *    permission of the Apache Software Foundation.
   *
   * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
   * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
   * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
   * DISCLAIMED.  IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
   * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
   * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
   * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
   * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
   * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
   * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
   * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
   * SUCH DAMAGE.
   * ====================================================================
   *
   * This software consists of voluntary contributions made by many
   * individuals on behalf of the Apache Software Foundation and was
   * originally based on software copyright (c) 1999-2001, The dbXML
   * Group, L.L.C., http://www.dbxmlgroup.com.  For more
   * information on the Apache Software Foundation, please see
   * <http://www.apache.org/>.
   *
   * $Id: IndexQueryNIN.java,v 1.1 2001/12/06 21:00:13 bradford Exp $
   */
  
  import org.apache.xindice.core.data.*;
  import org.apache.xindice.core.indexer.*;
  import java.util.*;
  
  /**
   * IndexQueryNIN
   */
  
  public final class IndexQueryNIN extends IndexQuery {
     public IndexQueryNIN(IndexPattern pattern, Value[] vals) {
        super(pattern, NIN, vals);
     }
  
     public int getOperator() {
        return NIN;
     }
  
     public boolean testValue(Value value) {
        return Arrays.binarySearch(vals, value) < 0;
     }
  }
  
  
  
  
  1.1                  xml-xindice/Xindice/java/src/org/apache/xindice/core/indexer/helpers/IndexQueryNSW.java
  
  Index: IndexQueryNSW.java
  ===================================================================
  package org.apache.xindice.core.indexer.helpers;
  
  /*
   * The Apache Software License, Version 1.1
   *
   *
   * Copyright (c) 1999 The Apache Software Foundation.  All rights
   * reserved.
   *
   * Redistribution and use in source and binary forms, with or without
   * modification, are permitted provided that the following conditions
   * are met:
   *
   * 1. Redistributions of source code must retain the above copyright
   *    notice, this list of conditions and the following disclaimer.
   *
   * 2. Redistributions in binary form must reproduce the above copyright
   *    notice, this list of conditions and the following disclaimer in
   *    the documentation and/or other materials provided with the
   *    distribution.
   *
   * 3. The end-user documentation included with the redistribution,
   *    if any, must include the following acknowledgment:
   *       "This product includes software developed by the
   *        Apache Software Foundation (http://www.apache.org/)."
   *    Alternately, this acknowledgment may appear in the software itself,
   *    if and wherever such third-party acknowledgments normally appear.
   *
   * 4. The names "Xindice" and "Apache Software Foundation" must
   *    not be used to endorse or promote products derived from this
   *    software without prior written permission. For written
   *    permission, please contact apache@apache.org.
   *
   * 5. Products derived from this software may not be called "Apache",
   *    nor may "Apache" appear in their name, without prior written
   *    permission of the Apache Software Foundation.
   *
   * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
   * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
   * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
   * DISCLAIMED.  IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
   * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
   * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
   * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
   * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
   * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
   * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
   * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
   * SUCH DAMAGE.
   * ====================================================================
   *
   * This software consists of voluntary contributions made by many
   * individuals on behalf of the Apache Software Foundation and was
   * originally based on software copyright (c) 1999-2001, The dbXML
   * Group, L.L.C., http://www.dbxmlgroup.com.  For more
   * information on the Apache Software Foundation, please see
   * <http://www.apache.org/>.
   *
   * $Id: IndexQueryNSW.java,v 1.1 2001/12/06 21:00:13 bradford Exp $
   */
  
  import org.apache.xindice.core.data.*;
  import org.apache.xindice.core.indexer.*;
  
  /**
   * IndexQueryNSW
   */
  
  public final class IndexQueryNSW extends IndexQuery {
     public IndexQueryNSW(IndexPattern pattern, Value val1) {
        super(pattern, NSW, val1);
     }
  
     public IndexQueryNSW(IndexPattern pattern, String val1) {
        super(pattern, NSW, val1);
     }
  
     public int getOperator() {
        return NSW;
     }
  
     public boolean testValue(Value value) {
        return !value.startsWith(vals[0]);
     }
  }
  
  
  
  
  1.1                  xml-xindice/Xindice/java/src/org/apache/xindice/core/indexer/helpers/IndexQuerySW.java
  
  Index: IndexQuerySW.java
  ===================================================================
  package org.apache.xindice.core.indexer.helpers;
  
  /*
   * The Apache Software License, Version 1.1
   *
   *
   * Copyright (c) 1999 The Apache Software Foundation.  All rights
   * reserved.
   *
   * Redistribution and use in source and binary forms, with or without
   * modification, are permitted provided that the following conditions
   * are met:
   *
   * 1. Redistributions of source code must retain the above copyright
   *    notice, this list of conditions and the following disclaimer.
   *
   * 2. Redistributions in binary form must reproduce the above copyright
   *    notice, this list of conditions and the following disclaimer in
   *    the documentation and/or other materials provided with the
   *    distribution.
   *
   * 3. The end-user documentation included with the redistribution,
   *    if any, must include the following acknowledgment:
   *       "This product includes software developed by the
   *        Apache Software Foundation (http://www.apache.org/)."
   *    Alternately, this acknowledgment may appear in the software itself,
   *    if and wherever such third-party acknowledgments normally appear.
   *
   * 4. The names "Xindice" and "Apache Software Foundation" must
   *    not be used to endorse or promote products derived from this
   *    software without prior written permission. For written
   *    permission, please contact apache@apache.org.
   *
   * 5. Products derived from this software may not be called "Apache",
   *    nor may "Apache" appear in their name, without prior written
   *    permission of the Apache Software Foundation.
   *
   * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
   * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
   * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
   * DISCLAIMED.  IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
   * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
   * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
   * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
   * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
   * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
   * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
   * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
   * SUCH DAMAGE.
   * ====================================================================
   *
   * This software consists of voluntary contributions made by many
   * individuals on behalf of the Apache Software Foundation and was
   * originally based on software copyright (c) 1999-2001, The dbXML
   * Group, L.L.C., http://www.dbxmlgroup.com.  For more
   * information on the Apache Software Foundation, please see
   * <http://www.apache.org/>.
   *
   * $Id: IndexQuerySW.java,v 1.1 2001/12/06 21:00:13 bradford Exp $
   */
  
  import org.apache.xindice.core.data.*;
  import org.apache.xindice.core.indexer.*;
  
  /**
   * IndexQuerySW
   */
  
  public final class IndexQuerySW extends IndexQuery {
     public IndexQuerySW(IndexPattern pattern, Value val1) {
        super(pattern, SW, val1);
     }
  
     public IndexQuerySW(IndexPattern pattern, String val1) {
        super(pattern, SW, val1);
     }
  
     public int getOperator() {
        return SW;
     }
  
     public boolean testValue(Value value) {
        return value.startsWith(vals[0]);
     }
  }
  
  
  
  
  1.1                  xml-xindice/Xindice/java/src/org/apache/xindice/core/indexer/helpers/package.html
  
  Index: package.html
  ===================================================================
  <html>
    <title>Xindice Indexer Helpers.</title>
    <body>
      <p>Implements several optimized Helper classes for Xindice IndexQuery
      usage.</p>
   </body>
  </html>
  
  
  
  
  
  1.1                  xml-xindice/Xindice/java/src/org/apache/xindice/core/objects/Args.java
  
  Index: Args.java
  ===================================================================
  package org.apache.xindice.core.objects;
  
  /*
   * The Apache Software License, Version 1.1
   *
   *
   * Copyright (c) 1999 The Apache Software Foundation.  All rights
   * reserved.
   *
   * Redistribution and use in source and binary forms, with or without
   * modification, are permitted provided that the following conditions
   * are met:
   *
   * 1. Redistributions of source code must retain the above copyright
   *    notice, this list of conditions and the following disclaimer.
   *
   * 2. Redistributions in binary form must reproduce the above copyright
   *    notice, this list of conditions and the following disclaimer in
   *    the documentation and/or other materials provided with the
   *    distribution.
   *
   * 3. The end-user documentation included with the redistribution,
   *    if any, must include the following acknowledgment:
   *       "This product includes software developed by the
   *        Apache Software Foundation (http://www.apache.org/)."
   *    Alternately, this acknowledgment may appear in the software itself,
   *    if and wherever such third-party acknowledgments normally appear.
   *
   * 4. The names "Xindice" and "Apache Software Foundation" must
   *    not be used to endorse or promote products derived from this
   *    software without prior written permission. For written
   *    permission, please contact apache@apache.org.
   *
   * 5. Products derived from this software may not be called "Apache",
   *    nor may "Apache" appear in their name, without prior written
   *    permission of the Apache Software Foundation.
   *
   * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
   * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
   * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
   * DISCLAIMED.  IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
   * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
   * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
   * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
   * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
   * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
   * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
   * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
   * SUCH DAMAGE.
   * ====================================================================
   *
   * This software consists of voluntary contributions made by many
   * individuals on behalf of the Apache Software Foundation and was
   * originally based on software copyright (c) 1999-2001, The dbXML
   * Group, L.L.C., http://www.dbxmlgroup.com.  For more
   * information on the Apache Software Foundation, please see
   * <http://www.apache.org/>.
   *
   * $Id: Args.java,v 1.1 2001/12/06 21:00:13 bradford Exp $
   */
  
  /**
   * Args exposes a set of named Variants.  Args is useful in defining
   * XMLObject methods that have a variable number of arguments.  An
   * Args instance is read-only.
   */
  
  public interface Args {
     /**
      * list returns a String array containing the names of the arguments
      * being stored by the args instance.
      *
      * @return The argument names
      */
     String[] list();
  
     /**
      * get returns a Variant argument by name, or null of the argumnet
      * doesn't exist.
      *
      * @param name The argument name
      * @return The argument value
      */
     Variant get(String name);
  }
  
  
  
  
  1.1                  xml-xindice/Xindice/java/src/org/apache/xindice/core/objects/CannotCreateException.java
  
  Index: CannotCreateException.java
  ===================================================================
  package org.apache.xindice.core.objects;
  
  /*
   * The Apache Software License, Version 1.1
   *
   *
   * Copyright (c) 1999 The Apache Software Foundation.  All rights
   * reserved.
   *
   * Redistribution and use in source and binary forms, with or without
   * modification, are permitted provided that the following conditions
   * are met:
   *
   * 1. Redistributions of source code must retain the above copyright
   *    notice, this list of conditions and the following disclaimer.
   *
   * 2. Redistributions in binary form must reproduce the above copyright
   *    notice, this list of conditions and the following disclaimer in
   *    the documentation and/or other materials provided with the
   *    distribution.
   *
   * 3. The end-user documentation included with the redistribution,
   *    if any, must include the following acknowledgment:
   *       "This product includes software developed by the
   *        Apache Software Foundation (http://www.apache.org/)."
   *    Alternately, this acknowledgment may appear in the software itself,
   *    if and wherever such third-party acknowledgments normally appear.
   *
   * 4. The names "Xindice" and "Apache Software Foundation" must
   *    not be used to endorse or promote products derived from this
   *    software without prior written permission. For written
   *    permission, please contact apache@apache.org.
   *
   * 5. Products derived from this software may not be called "Apache",
   *    nor may "Apache" appear in their name, without prior written
   *    permission of the Apache Software Foundation.
   *
   * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
   * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
   * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
   * DISCLAIMED.  IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
   * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
   * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
   * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
   * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
   * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
   * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
   * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
   * SUCH DAMAGE.
   * ====================================================================
   *
   * This software consists of voluntary contributions made by many
   * individuals on behalf of the Apache Software Foundation and was
   * originally based on software copyright (c) 1999-2001, The dbXML
   * Group, L.L.C., http://www.dbxmlgroup.com.  For more
   * information on the Apache Software Foundation, please see
   * <http://www.apache.org/>.
   *
   * $Id: CannotCreateException.java,v 1.1 2001/12/06 21:00:13 bradford Exp $
   */
  
  import org.apache.xindice.core.*;
  
  /**
   * A CannotCreateException is thrown if an XMLObject cannot
   * be properly created in the server context for some reason.
   */
  
  public final class CannotCreateException extends XMLObjectException {
     public CannotCreateException() {
        super(FaultCodes.OBJ_CANNOT_CREATE);
     }
     
     public CannotCreateException(String message) {
        super(FaultCodes.OBJ_CANNOT_CREATE, message);
     }
  }
  
  
  
  1.1                  xml-xindice/Xindice/java/src/org/apache/xindice/core/objects/ClassFormatException.java
  
  Index: ClassFormatException.java
  ===================================================================
  package org.apache.xindice.core.objects;
  
  /*
   * The Apache Software License, Version 1.1
   *
   *
   * Copyright (c) 1999 The Apache Software Foundation.  All rights
   * reserved.
   *
   * Redistribution and use in source and binary forms, with or without
   * modification, are permitted provided that the following conditions
   * are met:
   *
   * 1. Redistributions of source code must retain the above copyright
   *    notice, this list of conditions and the following disclaimer.
   *
   * 2. Redistributions in binary form must reproduce the above copyright
   *    notice, this list of conditions and the following disclaimer in
   *    the documentation and/or other materials provided with the
   *    distribution.
   *
   * 3. The end-user documentation included with the redistribution,
   *    if any, must include the following acknowledgment:
   *       "This product includes software developed by the
   *        Apache Software Foundation (http://www.apache.org/)."
   *    Alternately, this acknowledgment may appear in the software itself,
   *    if and wherever such third-party acknowledgments normally appear.
   *
   * 4. The names "Xindice" and "Apache Software Foundation" must
   *    not be used to endorse or promote products derived from this
   *    software without prior written permission. For written
   *    permission, please contact apache@apache.org.
   *
   * 5. Products derived from this software may not be called "Apache",
   *    nor may "Apache" appear in their name, without prior written
   *    permission of the Apache Software Foundation.
   *
   * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
   * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
   * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
   * DISCLAIMED.  IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
   * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
   * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
   * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
   * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
   * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
   * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
   * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
   * SUCH DAMAGE.
   * ====================================================================
   *
   * This software consists of voluntary contributions made by many
   * individuals on behalf of the Apache Software Foundation and was
   * originally based on software copyright (c) 1999-2001, The dbXML
   * Group, L.L.C., http://www.dbxmlgroup.com.  For more
   * information on the Apache Software Foundation, please see
   * <http://www.apache.org/>.
   *
   * $Id: ClassFormatException.java,v 1.1 2001/12/06 21:00:13 bradford Exp $
   */
  
  import org.apache.xindice.core.*;
  
  /**
   * A ClassFormatException is thrown if an XMLObject exposes
   * overloaded methods or other non-supported signatures.
   */
  
  public final class ClassFormatException extends XMLObjectException {
     public ClassFormatException() {
        super(FaultCodes.OBJ_CLASS_FORMAT_ERROR);
     }
     
     public ClassFormatException(String message) {
        super(FaultCodes.OBJ_CLASS_FORMAT_ERROR, message);
     }
  }
  
  
  
  1.1                  xml-xindice/Xindice/java/src/org/apache/xindice/core/objects/DuplicateObjectException.java
  
  Index: DuplicateObjectException.java
  ===================================================================
  package org.apache.xindice.core.objects;
  
  /*
   * The Apache Software License, Version 1.1
   *
   *
   * Copyright (c) 1999 The Apache Software Foundation.  All rights
   * reserved.
   *
   * Redistribution and use in source and binary forms, with or without
   * modification, are permitted provided that the following conditions
   * are met:
   *
   * 1. Redistributions of source code must retain the above copyright
   *    notice, this list of conditions and the following disclaimer.
   *
   * 2. Redistributions in binary form must reproduce the above copyright
   *    notice, this list of conditions and the following disclaimer in
   *    the documentation and/or other materials provided with the
   *    distribution.
   *
   * 3. The end-user documentation included with the redistribution,
   *    if any, must include the following acknowledgment:
   *       "This product includes software developed by the
   *        Apache Software Foundation (http://www.apache.org/)."
   *    Alternately, this acknowledgment may appear in the software itself,
   *    if and wherever such third-party acknowledgments normally appear.
   *
   * 4. The names "Xindice" and "Apache Software Foundation" must
   *    not be used to endorse or promote products derived from this
   *    software without prior written permission. For written
   *    permission, please contact apache@apache.org.
   *
   * 5. Products derived from this software may not be called "Apache",
   *    nor may "Apache" appear in their name, without prior written
   *    permission of the Apache Software Foundation.
   *
   * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
   * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
   * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
   * DISCLAIMED.  IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
   * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
   * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
   * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
   * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
   * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
   * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
   * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
   * SUCH DAMAGE.
   * ====================================================================
   *
   * This software consists of voluntary contributions made by many
   * individuals on behalf of the Apache Software Foundation and was
   * originally based on software copyright (c) 1999-2001, The dbXML
   * Group, L.L.C., http://www.dbxmlgroup.com.  For more
   * information on the Apache Software Foundation, please see
   * <http://www.apache.org/>.
   *
   * $Id: DuplicateObjectException.java,v 1.1 2001/12/06 21:00:13 bradford Exp $
   */
  
  import org.apache.xindice.core.*;
  
  /**
   * A DuplicateObjectException is thrown if an XMLObject create
   * attempt duplicates an existing XMLObject.
   */
  
  public final class DuplicateObjectException extends XMLObjectException {
     public DuplicateObjectException() {
        super(FaultCodes.OBJ_DUPLICATE_OBJECT);
     }
     
     public DuplicateObjectException(String message) {
        super(FaultCodes.OBJ_DUPLICATE_OBJECT, message);
     }
  }
  
  
  
  1.1                  xml-xindice/Xindice/java/src/org/apache/xindice/core/objects/ElementArgs.java
  
  Index: ElementArgs.java
  ===================================================================
  package org.apache.xindice.core.objects;
  
  /*
   * The Apache Software License, Version 1.1
   *
   *
   * Copyright (c) 1999 The Apache Software Foundation.  All rights
   * reserved.
   *
   * Redistribution and use in source and binary forms, with or without
   * modification, are permitted provided that the following conditions
   * are met:
   *
   * 1. Redistributions of source code must retain the above copyright
   *    notice, this list of conditions and the following disclaimer.
   *
   * 2. Redistributions in binary form must reproduce the above copyright
   *    notice, this list of conditions and the following disclaimer in
   *    the documentation and/or other materials provided with the
   *    distribution.
   *
   * 3. The end-user documentation included with the redistribution,
   *    if any, must include the following acknowledgment:
   *       "This product includes software developed by the
   *        Apache Software Foundation (http://www.apache.org/)."
   *    Alternately, this acknowledgment may appear in the software itself,
   *    if and wherever such third-party acknowledgments normally appear.
   *
   * 4. The names "Xindice" and "Apache Software Foundation" must
   *    not be used to endorse or promote products derived from this
   *    software without prior written permission. For written
   *    permission, please contact apache@apache.org.
   *
   * 5. Products derived from this software may not be called "Apache",
   *    nor may "Apache" appear in their name, without prior written
   *    permission of the Apache Software Foundation.
   *
   * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
   * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
   * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
   * DISCLAIMED.  IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
   * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
   * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
   * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
   * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
   * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
   * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
   * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
   * SUCH DAMAGE.
   * ====================================================================
   *
   * This software consists of voluntary contributions made by many
   * individuals on behalf of the Apache Software Foundation and was
   * originally based on software copyright (c) 1999-2001, The dbXML
   * Group, L.L.C., http://www.dbxmlgroup.com.  For more
   * information on the Apache Software Foundation, please see
   * <http://www.apache.org/>.
   *
   * $Id: ElementArgs.java,v 1.1 2001/12/06 21:00:13 bradford Exp $
   */
  
  import org.w3c.dom.*;
  
  /**
   * ElementArgs
   */
  
  public final class ElementArgs implements Args {
     private NamedNodeMap map;
  
     public ElementArgs(Element elem) {
        this.map = elem.getAttributes();
     }
  
     public String[] list() {
        int size = map.getLength();
        String[] l = new String[size];
        for ( int i = 0; i < size; i++ )
           l[i] = map.item(i).getNodeName();
        return l;
     }
  
     public Variant get(String name) {
        return new Variant(map.getNamedItem(name));
     }
  }
  
  
  
  
  1.1                  xml-xindice/Xindice/java/src/org/apache/xindice/core/objects/InvalidContextException.java
  
  Index: InvalidContextException.java
  ===================================================================
  package org.apache.xindice.core.objects;
  
  /*
   * The Apache Software License, Version 1.1
   *
   *
   * Copyright (c) 1999 The Apache Software Foundation.  All rights
   * reserved.
   *
   * Redistribution and use in source and binary forms, with or without
   * modification, are permitted provided that the following conditions
   * are met:
   *
   * 1. Redistributions of source code must retain the above copyright
   *    notice, this list of conditions and the following disclaimer.
   *
   * 2. Redistributions in binary form must reproduce the above copyright
   *    notice, this list of conditions and the following disclaimer in
   *    the documentation and/or other materials provided with the
   *    distribution.
   *
   * 3. The end-user documentation included with the redistribution,
   *    if any, must include the following acknowledgment:
   *       "This product includes software developed by the
   *        Apache Software Foundation (http://www.apache.org/)."
   *    Alternately, this acknowledgment may appear in the software itself,
   *    if and wherever such third-party acknowledgments normally appear.
   *
   * 4. The names "Xindice" and "Apache Software Foundation" must
   *    not be used to endorse or promote products derived from this
   *    software without prior written permission. For written
   *    permission, please contact apache@apache.org.
   *
   * 5. Products derived from this software may not be called "Apache",
   *    nor may "Apache" appear in their name, without prior written
   *    permission of the Apache Software Foundation.
   *
   * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
   * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
   * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
   * DISCLAIMED.  IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
   * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
   * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
   * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
   * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
   * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
   * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
   * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
   * SUCH DAMAGE.
   * ====================================================================
   *
   * This software consists of voluntary contributions made by many
   * individuals on behalf of the Apache Software Foundation and was
   * originally based on software copyright (c) 1999-2001, The dbXML
   * Group, L.L.C., http://www.dbxmlgroup.com.  For more
   * information on the Apache Software Foundation, please see
   * <http://www.apache.org/>.
   *
   * $Id: InvalidContextException.java,v 1.1 2001/12/06 21:00:13 bradford Exp $
   */
  
  import org.apache.xindice.core.*;
  
  /**
   * A InvalidContextException is thrown if an XMLObject does not belong
   * to a specified context.
   */
  
  public final class InvalidContextException extends XMLObjectException {
     public InvalidContextException() {
        super(FaultCodes.OBJ_INVALID_CONTEXT);
     }
     
     public InvalidContextException(String message) {
        super(FaultCodes.OBJ_INVALID_CONTEXT, message);
     }
  }
  
  
  
  
  1.1                  xml-xindice/Xindice/java/src/org/apache/xindice/core/objects/MapArgs.java
  
  Index: MapArgs.java
  ===================================================================
  package org.apache.xindice.core.objects;
  
  /*
   * The Apache Software License, Version 1.1
   *
   *
   * Copyright (c) 1999 The Apache Software Foundation.  All rights
   * reserved.
   *
   * Redistribution and use in source and binary forms, with or without
   * modification, are permitted provided that the following conditions
   * are met:
   *
   * 1. Redistributions of source code must retain the above copyright
   *    notice, this list of conditions and the following disclaimer.
   *
   * 2. Redistributions in binary form must reproduce the above copyright
   *    notice, this list of conditions and the following disclaimer in
   *    the documentation and/or other materials provided with the
   *    distribution.
   *
   * 3. The end-user documentation included with the redistribution,
   *    if any, must include the following acknowledgment:
   *       "This product includes software developed by the
   *        Apache Software Foundation (http://www.apache.org/)."
   *    Alternately, this acknowledgment may appear in the software itself,
   *    if and wherever such third-party acknowledgments normally appear.
   *
   * 4. The names "Xindice" and "Apache Software Foundation" must
   *    not be used to endorse or promote products derived from this
   *    software without prior written permission. For written
   *    permission, please contact apache@apache.org.
   *
   * 5. Products derived from this software may not be called "Apache",
   *    nor may "Apache" appear in their name, without prior written
   *    permission of the Apache Software Foundation.
   *
   * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
   * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
   * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
   * DISCLAIMED.  IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
   * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
   * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
   * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
   * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
   * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
   * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
   * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
   * SUCH DAMAGE.
   * ====================================================================
   *
   * This software consists of voluntary contributions made by many
   * individuals on behalf of the Apache Software Foundation and was
   * originally based on software copyright (c) 1999-2001, The dbXML
   * Group, L.L.C., http://www.dbxmlgroup.com.  For more
   * information on the Apache Software Foundation, please see
   * <http://www.apache.org/>.
   *
   * $Id: MapArgs.java,v 1.1 2001/12/06 21:00:13 bradford Exp $
   */
  
  import java.util.*;
  
  /**
   * MapArgs
   */
  
  public final class MapArgs implements Args {
     private static final String[] EmptyStrings = new String[0];
  
     private Map map;
  
     public MapArgs(Map map) {
        this.map = map;
     }
  
     public String[] list() {
        return (String[])map.keySet().toArray(EmptyStrings);
     }
  
     public Variant get(String name) {
        return new Variant(map.get(name));
     }
  }
  
  
  
  
  1.1                  xml-xindice/Xindice/java/src/org/apache/xindice/core/objects/MethodNotFoundException.java
  
  Index: MethodNotFoundException.java
  ===================================================================
  package org.apache.xindice.core.objects;
  
  /*
   * The Apache Software License, Version 1.1
   *
   *
   * Copyright (c) 1999 The Apache Software Foundation.  All rights
   * reserved.
   *
   * Redistribution and use in source and binary forms, with or without
   * modification, are permitted provided that the following conditions
   * are met:
   *
   * 1. Redistributions of source code must retain the above copyright
   *    notice, this list of conditions and the following disclaimer.
   *
   * 2. Redistributions in binary form must reproduce the above copyright
   *    notice, this list of conditions and the following disclaimer in
   *    the documentation and/or other materials provided with the
   *    distribution.
   *
   * 3. The end-user documentation included with the redistribution,
   *    if any, must include the following acknowledgment:
   *       "This product includes software developed by the
   *        Apache Software Foundation (http://www.apache.org/)."
   *    Alternately, this acknowledgment may appear in the software itself,
   *    if and wherever such third-party acknowledgments normally appear.
   *
   * 4. The names "Xindice" and "Apache Software Foundation" must
   *    not be used to endorse or promote products derived from this
   *    software without prior written permission. For written
   *    permission, please contact apache@apache.org.
   *
   * 5. Products derived from this software may not be called "Apache",
   *    nor may "Apache" appear in their name, without prior written
   *    permission of the Apache Software Foundation.
   *
   * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
   * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
   * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
   * DISCLAIMED.  IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
   * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
   * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
   * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
   * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
   * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
   * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
   * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
   * SUCH DAMAGE.
   * ====================================================================
   *
   * This software consists of voluntary contributions made by many
   * individuals on behalf of the Apache Software Foundation and was
   * originally based on software copyright (c) 1999-2001, The dbXML
   * Group, L.L.C., http://www.dbxmlgroup.com.  For more
   * information on the Apache Software Foundation, please see
   * <http://www.apache.org/>.
   *
   * $Id: MethodNotFoundException.java,v 1.1 2001/12/06 21:00:13 bradford Exp $
   */
  
  import org.apache.xindice.core.*;
  
  /**
   * A MethodNotFoundException is thrown by the Reflector if a
   * method lookup failes on an XMLObject.
   */
  
  public final class MethodNotFoundException extends XMLObjectException {
     public MethodNotFoundException() {
        super(FaultCodes.OBJ_METHOD_NOT_FOUND);
     }
     
     public MethodNotFoundException(String message) {
        super(FaultCodes.OBJ_METHOD_NOT_FOUND, message);
     }
  }
  
  
  
  1.1                  xml-xindice/Xindice/java/src/org/apache/xindice/core/objects/Reflectable.java
  
  Index: Reflectable.java
  ===================================================================
  package org.apache.xindice.core.objects;
  
  /*
   * The Apache Software License, Version 1.1
   *
   *
   * Copyright (c) 1999 The Apache Software Foundation.  All rights
   * reserved.
   *
   * Redistribution and use in source and binary forms, with or without
   * modification, are permitted provided that the following conditions
   * are met:
   *
   * 1. Redistributions of source code must retain the above copyright
   *    notice, this list of conditions and the following disclaimer.
   *
   * 2. Redistributions in binary form must reproduce the above copyright
   *    notice, this list of conditions and the following disclaimer in
   *    the documentation and/or other materials provided with the
   *    distribution.
   *
   * 3. The end-user documentation included with the redistribution,
   *    if any, must include the following acknowledgment:
   *       "This product includes software developed by the
   *        Apache Software Foundation (http://www.apache.org/)."
   *    Alternately, this acknowledgment may appear in the software itself,
   *    if and wherever such third-party acknowledgments normally appear.
   *
   * 4. The names "Xindice" and "Apache Software Foundation" must
   *    not be used to endorse or promote products derived from this
   *    software without prior written permission. For written
   *    permission, please contact apache@apache.org.
   *
   * 5. Products derived from this software may not be called "Apache",
   *    nor may "Apache" appear in their name, without prior written
   *    permission of the Apache Software Foundation.
   *
   * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
   * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
   * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
   * DISCLAIMED.  IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
   * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
   * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
   * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
   * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
   * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
   * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
   * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
   * SUCH DAMAGE.
   * ====================================================================
   *
   * This software consists of voluntary contributions made by many
   * individuals on behalf of the Apache Software Foundation and was
   * originally based on software copyright (c) 1999-2001, The dbXML
   * Group, L.L.C., http://www.dbxmlgroup.com.  For more
   * information on the Apache Software Foundation, please see
   * <http://www.apache.org/>.
   *
   * $Id: Reflectable.java,v 1.1 2001/12/06 21:00:13 bradford Exp $
   */
  
  import org.w3c.dom.*;
  
  /**
   * Reflectable is the base interface for XMLObjects, allowing them to expose a
   * Reflector for performing method introspection and execution against the
   * Object.
   * <br><br>
   * Xindice will expose all public methods that match a valid signature.
   * The rules of this signature follow:
   * <pre>
   *    Result/Params: void                              (result only)
   *                   org.w3c.dom.Element               (result only)
   *                   org.w3c.dom.Document              (result only)
   *                   org.w3c.dom.DocumentFragment      (result only)
   *                   native types (long, int, etc...)
   *                   java.lang.String
   *                   org.apache.xindice.core.objects.Variant
   *
   *    *NOTE: String, Variant, and all of the Java native types (long,
   *           int, etc...) can also be passed as arrays of those types.
   * </pre>
   * XMLObjects need to expose meta data so that a URI Query String (or any
   * other type of parameter set can be mapped to a method's arguments.  This
   * is accomplished through the getReflector() method.
   * <br><br>
   * A typical URI for an Reflectable might be:
   * <pre>
   *    /Database/Collection/1234567/XMLObject/Method(Blah, Blah)
   *    /Database/Collection/1234567/XMLObject/Method?red=Blah&green=Blah
   * </pre>
   * Both forms will create a new Reflectable if neccessary, set any
   * required context information, and call a method in that object.  The
   * first form passes the two arguments as-is, and the second maps the 'red'
   * parameter to the red argument, and the blue parameter to the blue
   * argument (regardless of method ordering).
   */
  
  public interface Reflectable {
     static final String[] NO_PARAMS = new String[0];
  
     /**
      * getReflector returns the Reflectable Object's Reflector instance.
      *
      * @return The Object's Reflector
      */
     Reflector getReflector();
  
     /**
      * queryInterface allows a client to query the Reflectable Object for
      * exposed methods.
      *
      * @return The Object's interface
      */
     Document queryInterface();
  }
  
  
  
  1.1                  xml-xindice/Xindice/java/src/org/apache/xindice/core/objects/Reflector.java
  
  Index: Reflector.java
  ===================================================================
  package org.apache.xindice.core.objects;
  
  /*
   * The Apache Software License, Version 1.1
   *
   *
   * Copyright (c) 1999 The Apache Software Foundation.  All rights
   * reserved.
   *
   * Redistribution and use in source and binary forms, with or without
   * modification, are permitted provided that the following conditions
   * are met:
   *
   * 1. Redistributions of source code must retain the above copyright
   *    notice, this list of conditions and the following disclaimer.
   *
   * 2. Redistributions in binary form must reproduce the above copyright
   *    notice, this list of conditions and the following disclaimer in
   *    the documentation and/or other materials provided with the
   *    distribution.
   *
   * 3. The end-user documentation included with the redistribution,
   *    if any, must include the following acknowledgment:
   *       "This product includes software developed by the
   *        Apache Software Foundation (http://www.apache.org/)."
   *    Alternately, this acknowledgment may appear in the software itself,
   *    if and wherever such third-party acknowledgments normally appear.
   *
   * 4. The names "Xindice" and "Apache Software Foundation" must
   *    not be used to endorse or promote products derived from this
   *    software without prior written permission. For written
   *    permission, please contact apache@apache.org.
   *
   * 5. Products derived from this software may not be called "Apache",
   *    nor may "Apache" appear in their name, without prior written
   *    permission of the Apache Software Foundation.
   *
   * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
   * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
   * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
   * DISCLAIMED.  IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
   * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
   * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
   * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
   * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
   * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
   * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
   * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
   * SUCH DAMAGE.
   * ====================================================================
   *
   * This software consists of voluntary contributions made by many
   * individuals on behalf of the Apache Software Foundation and was
   * originally based on software copyright (c) 1999-2001, The dbXML
   * Group, L.L.C., http://www.dbxmlgroup.com.  For more
   * information on the Apache Software Foundation, please see
   * <http://www.apache.org/>.
   *
   * $Id: Reflector.java,v 1.1 2001/12/06 21:00:13 bradford Exp $
   */
  
  import org.apache.xindice.core.*;
  import org.apache.xindice.xml.dom.*;
  import org.apache.xindice.util.*;
  
  import org.w3c.dom.*;
  import java.lang.reflect.*;
  import java.util.*;
  
  /**
   * Reflector is an Object reflection and method invocation utility for Xindice
   * Reflectable implementations (XMLObjects).
   */
  
  public final class Reflector {
     private static final String[] EmptyStrings = new String[0];
  
     private static final String PARAMS_PREFIX = "PARAMS_";
     private static final String DEFAULTS_PREFIX = "DEFAULTS_";
     private static final String ERRORS_PREFIX = "ERRORS_";
  
     private Map methods = new HashMap(); // MethodInfo
  
     public Reflector() {
     }
  
     public Reflector(Class c) throws XMLObjectException {
        reflect(c);
     }
  
     /**
      * reflect performs an initial reflection against the Class that this
      * Reflector will support.  This method will not be capable of reflecting
      * parameter names because the Java compiler throws them away.  In order to
      * create parameter name mappings, you must call addMethod.
      */
     public void reflect(Class c) throws XMLObjectException {
        // Short-curcuit on this class
        if ( c == SimpleXMLObject.class )
           return;
  
        // Only add queryInterface on this class
        if ( c == SimpleReflectable.class ) {
           try {
              String qi = "queryInterface";
              Method m = c.getMethod(qi, new Class[0]);
              MethodInfo mi = new MethodInfo(Types.VOID, qi, m, new ParamInfo[0]);
              methods.put(qi, mi);
           }
           catch ( Exception e ) {
              org.apache.xindice.Debug.printStackTrace(e);
           }
           return;
        }
  
        Method[] m = c.getDeclaredMethods();
        Set defined = new HashSet();
        for ( int i = 0; i < m.length; i++ ) {
           String name = m[i].getName();
  
           // Check Modifiers
           int mod = m[i].getModifiers();
           if ( !Modifier.isPublic(mod) || Modifier.isStatic(mod) )
              continue;
  
           // Check Valid Return Types
           Class ret = m[i].getReturnType();
           int retType = Types.typeOf(ret);
           if ( retType == Types.UNKNOWN || ret.isArray() )
              continue;
  
           // Ignore Special Methods from the various Context interfaces
           // This has to be the ugliest piece of shit I've ever written
           if ( ( (     name.startsWith("get")
                     || name.startsWith("set") )
                  &&
                  (     name.equals("getReflector")
                     || name.equals("getName")
                     || name.equals("setDatabase")
                     || name.equals("getDatabase")
                     || name.equals("setDatabase")
                     || name.equals("getDatabase")
                     || name.equals("setCollection")
                     || name.equals("getCollection")
                     || name.equals("setContainer")
                     || name.equals("getContainer")
                     || name.equals("setDocument")
                     || name.equals("getDocument")
                     || name.equals("setConfig")
                     || name.equals("getConfig")
                     || name.equals("setPool") )
                )
                || name.equals("reclaim")
                   // Java Stuff
                || name.equals("equals")
                || name.equals("finalize")
                || name.equals("hashCode")
                || name.equals("notify")
                || name.equals("notifyAll")
                || name.equals("wait") )
              continue;
  
           if ( defined.contains(name) )
              throw new ClassFormatException("Duplicate Exposed Method '"+name+"'");
  
           // Check Valid Parameter Types
           Class[] p = m[i].getParameterTypes();
           ParamInfo[] params = new ParamInfo[p.length];
  
           String[] names = getFieldVals(c, p.length, PARAMS_PREFIX+name);
           String[] defaults = getFieldVals(c, p.length, DEFAULTS_PREFIX+name);
           String[] errors = getFieldVals(c, p.length, ERRORS_PREFIX+name);
  
           boolean good = true;
           for ( int j = 0; j < p.length && good; j++ ) {
              String pname = names != null ? names[j]
                                           : "arg"+(j+1);
  
              int parmType = Types.typeOf(p[j]);
              good = parmType != Types.UNKNOWN;
  
              if ( p[j].isArray() )
                 params[j] = new ParamInfo(pname, parmType, p[j].getComponentType());
              else
                 params[j] = new ParamInfo(pname, parmType);
  
              if ( defaults != null )
                 params[j].defValue = defaults[j];
  
              if ( errors != null )
                 params[j].errValue = errors[j];
           }
           if ( !good )
              continue;
  
           methods.put(name, new MethodInfo(retType, name, m[i], params));
  
           defined.add(name);
        }
     }
  
     private String[] getFieldVals(Class c, int len, String name) {
        try {
           Field f = c.getDeclaredField(name);
           int mod = f.getModifiers();
           if ( Modifier.isStatic(mod) && Modifier.isFinal(mod)
             && f.getType().isArray() && f.getType().getComponentType() == String.class ) {
              String[] res = (String[])f.get(null);
              if ( res.length == len )
                 return res;
           }
        }
        catch ( Exception e ) {
        }
        return null;
     }
  
     /**
      * addMethod adds method meta data to the reflected Class definition.
      * The params that are passed in do not absolutely need to match the
      * parameter names that are in the source code, but because they establish a
      * contract between a set of named parameters and the parameter ordering for
      * the method, it is your safest bet to match mapping parameters to source
      * code parameters.
      * <br>
      * A method without parameter name mappings will not be accessible for
      * invocation.
      *
      * @param name The method name
      * @param params The parameter names
      * @param defaults Default values for the parameters
      * @param errors Errors values on conversion failure
      * @throws XMLObjectException If a mapping error occurs
      */
     public void addMethod(String name, String[] params, String[] defaults, String[] errors) throws XMLObjectException {
        MethodInfo info = (MethodInfo)methods.get(name);
        if ( info != null ) {
           if ( info.params.length == params.length )
              for ( int i = 0; i < params.length; i++ ) {
                 info.params[i].name = params[i];
                 if ( defaults != null )
                    info.params[i].defValue = defaults[i];
                 if ( errors != null )
                    info.params[i].errValue = errors[i];
              }
           else
              throw new ClassFormatException("Param Count For '"+name+"' Does Not Match Reflector");
        }
        else
           throw new MethodNotFoundException("Method '"+name+"' Not Found");
     }
  
     public void addMethod(String name, String[] params) throws XMLObjectException {
        addMethod(name, params, null, null);
     }
  
     public void addMethod(String name, String[] params, String[] defaults) throws XMLObjectException {
        addMethod(name, params, defaults, null);
     }
  
     /**
      * getMethods returns the names of the publicly accessible methods for the
      * reflected class.
      *
      * @return The method names
      */
     public String[] listMethods() {
        return (String[])methods.keySet().toArray(EmptyStrings);
     }
  
     /**
      * getMethodParams returns the names of the parameters that a method would
      * require to be invoked.  These names will be returned in the order by
      * which they're specified upon invocation.
      *
      * @param name The method name
      * @return The parameter names
      */
     public String[] listMethodParams(String name) {
        MethodInfo info = (MethodInfo)methods.get(name);
        String[] params = null;
        if ( info != null ) {
           params = new String[info.params.length];
           for ( int i = 0; i < params.length; i++ ) {
              params[i] = info.params[i].name;
              if ( params[i] == null )
                 return null;
           }
        }
        return params;
     }
  
     /**
      * getReturnType returns the return type for the specified method..
      *
      * @see org.apache.xindice.core.objects.Types
      *
      * @param method The Method name
      * @return The Result Class
      */
     public int getReturnType(String method) {
        MethodInfo info = (MethodInfo)methods.get(method);
        if ( info != null )
           return info.result;
        return Types.UNKNOWN;
     }
  
     /**
      * getParamType returns the parameter type for the specified parameter in
      * the specified method.
      *
      * @see org.apache.xindice.core.objects.Types
      *
      * @param method The Method name
      * @param param The Parameter name
      * @return The Parameter Class
      */
     public int getParamType(String method, String param) {
        MethodInfo info = (MethodInfo)methods.get(method);
        if ( info != null ) {
           for ( int i = 0; i < info.params.length; i++ )
              if ( info.params[i].name.equals(param) )
                 return info.params[i].type;
        }
        return Types.UNKNOWN;
     }
  
     /**
      * getParamDefault returns the default value (String) for the specified
      * parameter in the specified method.
      *
      * @param method The Method name
      * @param param The Parameter name
      * @return The default value
      */
     public String getParamDefault(String method, String param) {
        MethodInfo info = (MethodInfo)methods.get(method);
        if ( info != null ) {
           for ( int i = 0; i < info.params.length; i++ )
              if ( info.params[i].name.equals(param) )
                 return info.params[i].defValue;
        }
        return null;
     }
  
     /**
      * isParamArray returns whether or not the parameter type for the specified
      * parameter is an array type..
      *
      * @param method The Method name
      * @param param The Parameter name
      * @return Whether or not the parameter is an array
      */
     public boolean isParamArray(String method, String param) {
        MethodInfo info = (MethodInfo)methods.get(method);
        if ( info != null ) {
           for ( int i = 0; i < info.params.length; i++ )
              if ( info.params[i].name.equals(param) )
                 return info.params[i].array;
        }
        return false;
     }
  
     // Invocation Methods
  
     /**
      * invoke invokes the named method against the specified Reflectable
      * Object, passing to the method the set of specified parameters.
      *
      * @param obj The target Reflectable
      * @param name The method name
      * @param params The parameter values
      * @return The result of the method
      * @throws XMLObjectException if an invocation error occurs
      */
     public Object invoke(Reflectable obj, String name, Object[] params) throws XMLObjectException {
        MethodInfo info = (MethodInfo)methods.get(name);
        if ( info != null ) {
           try {
              return info.method.invoke(obj, params);
           }
           catch ( Exception e ) {
              throw new XMLObjectRuntimeException("Error Invoking Method '"+name+"'");
           }
        }
        else
           throw new MethodNotFoundException("Method '"+name+"' Not Found");
     }
  
     private boolean isTrue(String value) {
        return "[true][yes][1][y][on]".indexOf("["+value.toLowerCase()+"]") != -1;
     }
  
     /**
      * invoke invokes the named method against the specified Reflectable Object,
      * passing to the method the set of specified parameters.  This method will
      * convert the String array in args to the appropriate Object types before
      * invoking the method.
      *
      * @param obj The target Reflectable
      * @param name The method name
      * @param args The parameter values
      * @return The result of the method
      * @throws XMLObjectException if an invocation error occurs
      */
     public Object invoke(Reflectable obj, String name, Variant[] args) throws XMLObjectException {
        MethodInfo info = (MethodInfo)methods.get(name);
        if ( info != null ) {
           Object[] params = new Object[info.params.length];
           for ( int i = 0; i < info.params.length; i++ ) {
              ParamInfo p = info.params[i];
              if ( args[i] == null )
                 args[i] = new Variant(p.defValue);
              if ( !p.array ) {
                 switch ( p.type ) {
  
                    case Types.STRING:
                       params[i] = args[i].getString();
                       break;
  
                    case Types.LONG:
                       params[i] = new Long(args[i].getLong());
                       break;
  
                    case Types.INT:
                       params[i] = new Integer(args[i].getInt());
                       break;
  
                    case Types.SHORT:
                       params[i] = new Short(args[i].getShort());
                       break;
  
                    case Types.BYTE:
                       params[i] = new Byte(args[i].getByte());
                       break;
  
                    case Types.CHAR:
                       params[i] = new Character(args[i].getChar());
                       break;
  
                    case Types.FLOAT:
                       params[i] = new Float(args[i].getFloat());
                       break;
  
                    case Types.DOUBLE:
                       params[i] = new Double(args[i].getDouble());
                       break;
  
                    case Types.BOOLEAN:
                       params[i] = new Boolean(args[i].getBoolean());
                       break;
  
                    case Types.ARGS:
                       params[i] = args[i].getObject();
                       break;
  
                    case Types.VARIANT:
                       params[i] = args[i];
                       break;
  
                 }
              }
              else {
                 Class compType = p.component;
                 StringTokenizer st = new StringTokenizer(args[i].getString(), "\u0001");
                 int len = st.countTokens();
                 Object arr = Array.newInstance(compType, len);
  
                 switch ( p.type ) {
  
                    case Types.STRING:
                       for ( int j = 0; j < len; j++ )
                          Array.set(arr, j, st.nextToken());
                       break;
  
                    case Types.LONG:
                       for ( int j = 0; j < len; j++ )
                          Array.setLong(arr, j, Long.parseLong(st.nextToken()));
                       break;
  
                    case Types.INT:
                       for ( int j = 0; j < len; j++ )
                          Array.setInt(arr, j, Integer.parseInt(st.nextToken()));
                       break;
  
                    case Types.SHORT:
                       for ( int j = 0; j < len; j++ )
                          Array.setShort(arr, j, Short.parseShort(st.nextToken()));
                       break;
  
                    case Types.BYTE:
                       for ( int j = 0; j < len; j++ )
                          Array.setByte(arr, j, Byte.parseByte(st.nextToken()));
                       break;
  
                    case Types.CHAR:
                       for ( int j = 0; j < len; j++ )
                          Array.setChar(arr, j, st.nextToken().charAt(0));
                       break;
  
                    case Types.FLOAT:
                       for ( int j = 0; j < len; j++ )
                          Array.setFloat(arr, j, Float.parseFloat(st.nextToken()));
                       break;
  
                    case Types.DOUBLE:
                       for ( int j = 0; j < len; j++ )
                          Array.setDouble(arr, j, Double.parseDouble(st.nextToken()));
                       break;
  
                    case Types.BOOLEAN:
                       for ( int j = 0; j < len; j++ )
                          Array.setBoolean(arr, j, isTrue(st.nextToken()));
                       break;
  
                    case Types.VARIANT:
                       for ( int j = 0; j < len; j++ )
                          Array.set(arr, j, new Variant(st.nextToken()));
                       break;
  
                 }
                 params[i] = arr;
              }
           }
           try {
              return info.method.invoke(obj, params);
           }
           catch ( Exception e ) {
              throw new XMLObjectRuntimeException("Error Invoking Method '"+name+"'");
           }
        }
        else
           throw new MethodNotFoundException("Method '"+name+"' Not Found");
     }
  
     /**
      * invoke invokes the named method against the specified Reflectable Object,
      * passing to the method the set of specified parameters.  This method will
      * retrieve parameters by name from the Properties set, and convert them to
      * a String array before invoking.
      *
      * @param obj The target Reflectable
      * @param name The method name
      * @param params The parameter values
      * @return The result of the method
      * @throws XMLObjectException if an invocation error occurs
      */
     public Object invoke(Reflectable obj, String name, Args params) throws XMLObjectException {
        MethodInfo info = (MethodInfo)methods.get(name);
        if ( info != null ) {
           Variant[] args = new Variant[info.params.length];
           for ( int i = 0; i < info.params.length; i++ ) {
              if ( info.params[i].type == Types.ARGS )
                 args[i] = new Variant(params);
              else
                 args[i] = params.get(info.params[i].name);
           }
           return invoke(obj, name, args);
        }
        else
           throw new MethodNotFoundException("Method '"+name+"' Not Found");
     }
  
     /**
      * invoke invokes the named method against the specified Reflectable Object,
      * passing to the method the set of specified parameters.  This method will
      * retrieve parameters by name from the element's attribute set, and convert
      * them to a String array before invoking.
      *
      * @param obj The target Reflectable
      * @param name The method name
      * @param element The Element to use for Attributes
      * @return The result of the method
      * @throws XMLObjectException if an invocation error occurs
      */
     public Object invoke(Reflectable obj, String name, Element element) throws XMLObjectException  {
        return invoke(obj, name, new ElementArgs(element));
     }
  
     /**
      * ParamInfo encapsulates parameter type and name information
      */
  
     private class ParamInfo {
        public Class component;
        public int type;
        public boolean array;
        public String name = null;
        public String defValue = null;
        public String errValue = null;
  
        public ParamInfo(String name, int type, Class component) {
           this.name = name;
           this.type = type;
           this.component = component;
           array = true;
        }
  
        public ParamInfo(String name, int type) {
           this.name = name;
           this.type = type;
           component = null;
           array = false;
        }
     }
  
  
     /**
      * MethodInfo encapsulates Method result, name, and parameter information
      */
  
     private class MethodInfo {
        public int result;
        public String name;
        public Method method;
        public ParamInfo[] params;
  
        public MethodInfo(int result, String name, Method method, ParamInfo[] params) {
           this.result = result;
           this.name = name;
           this.method = method;
           this.params = params;
        }
     }
  }
  
  
  
  
  1.1                  xml-xindice/Xindice/java/src/org/apache/xindice/core/objects/SimpleReflectable.java
  
  Index: SimpleReflectable.java
  ===================================================================
  package org.apache.xindice.core.objects;
  
  /*
   * The Apache Software License, Version 1.1
   *
   *
   * Copyright (c) 1999 The Apache Software Foundation.  All rights
   * reserved.
   *
   * Redistribution and use in source and binary forms, with or without
   * modification, are permitted provided that the following conditions
   * are met:
   *
   * 1. Redistributions of source code must retain the above copyright
   *    notice, this list of conditions and the following disclaimer.
   *
   * 2. Redistributions in binary form must reproduce the above copyright
   *    notice, this list of conditions and the following disclaimer in
   *    the documentation and/or other materials provided with the
   *    distribution.
   *
   * 3. The end-user documentation included with the redistribution,
   *    if any, must include the following acknowledgment:
   *       "This product includes software developed by the
   *        Apache Software Foundation (http://www.apache.org/)."
   *    Alternately, this acknowledgment may appear in the software itself,
   *    if and wherever such third-party acknowledgments normally appear.
   *
   * 4. The names "Xindice" and "Apache Software Foundation" must
   *    not be used to endorse or promote products derived from this
   *    software without prior written permission. For written
   *    permission, please contact apache@apache.org.
   *
   * 5. Products derived from this software may not be called "Apache",
   *    nor may "Apache" appear in their name, without prior written
   *    permission of the Apache Software Foundation.
   *
   * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
   * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
   * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
   * DISCLAIMED.  IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
   * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
   * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
   * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
   * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
   * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
   * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
   * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
   * SUCH DAMAGE.
   * ====================================================================
   *
   * This software consists of voluntary contributions made by many
   * individuals on behalf of the Apache Software Foundation and was
   * originally based on software copyright (c) 1999-2001, The dbXML
   * Group, L.L.C., http://www.dbxmlgroup.com.  For more
   * information on the Apache Software Foundation, please see
   * <http://www.apache.org/>.
   *
   * $Id: SimpleReflectable.java,v 1.1 2001/12/06 21:00:13 bradford Exp $
   */
  
  import org.apache.xindice.core.*;
  import org.apache.xindice.xml.dom.*;
  import org.apache.xindice.util.*;
  
  import java.io.*;
  import java.util.*;
  
  import org.w3c.dom.*;
  
  /**
   * SimpleReflectable
   */
  
  public class SimpleReflectable extends SimpleConfigurable implements Reflectable, Poolable {
     private static final String NAME = "name";
     private static final String PACKAGE = "package";
     private static final String CLASS = "class";
     private static final String METHOD = "method";
     private static final String PARAM = "param";
     private static final String TYPE = "type";
     private static final String DEFAULT = "default";
  
     private static Map metaCache = new HashMap();
  
     private Document intf = null;
     protected ObjectPool pool = null;
     protected Reflector meta = null;
     protected String name = null;
  
     public SimpleReflectable() {
        try {
           Class c = this.getClass();
           meta = (Reflector)metaCache.get(c);
           if ( meta == null ) {
              meta = new Reflector();
              reflect(this.getClass());
              metaCache.put(c, meta);
           }
        }
        catch ( Exception e ) {
           org.apache.xindice.Debug.printStackTrace(e);
        }
     }
  
     private void reflect(Class c) throws Exception {
        // Reflect the parents first.
        // Short-curcuit at SimpleReflectable
        if ( c != SimpleReflectable.class )
           reflect(c.getSuperclass());
        meta.reflect(c);
     }
  
     private String trimClassName(String name) {
        int i = name.lastIndexOf('.');
        if ( i != -1 )
           name = name.substring(i+1);
        return name;
     }
  
     public void setConfig(Configuration config) throws XindiceException {
        super.setConfig(config);
        name = config.getAttribute(NAME);
     }
  
     public Reflector getReflector() {
        return meta;
     }
  
     public void setPool(ObjectPool pool) {
        this.pool = pool;
     }
  
     public void reclaim() {
        if ( pool != null )
           pool.putObject(this);
     }
  
     public String getName() {
        return name;
     }
  
     public Document queryInterface() {
        if ( intf == null ) {
           intf = new DocumentImpl();
           String[] methods = meta.listMethods();
           String cname;
           if ( name != null )
              cname = name;
           else
              cname = trimClassName(this.getClass().getName());
  
           Element root = intf.createElement(CLASS);
           root.setAttribute(NAME, cname);
           root.setAttribute(PACKAGE, this.getClass().getPackage().getName().replace('.', '/'));
           intf.appendChild(root);
  
           for ( int i = 0; i < methods.length; i++ ) {
              String type = Types.typeName(meta.getReturnType(methods[i]));
              Element method = intf.createElement(METHOD);
              method.setAttribute(NAME, methods[i]);
              method.setAttribute(TYPE, type);
              root.appendChild(method);
  
              String[] params = meta.listMethodParams(methods[i]);
              for ( int j = 0; params != null && j < params.length; j++ ) {
                 type = Types.typeName(meta.getParamType(methods[i], params[j]));
                 String defValue = meta.getParamDefault(methods[i], params[j]);
                 if ( meta.isParamArray(methods[i], params[j]) )
                    type = type + "[]";
                 Element param = intf.createElement(PARAM);
                 param.setAttribute(NAME, params[j]);
                 param.setAttribute(TYPE, type);
                 if ( defValue != null )
                    param.setAttribute(DEFAULT, defValue);
                 method.appendChild(param);
              }
           }
        }
        return intf;
     }
  }
  
  
  
  
  
  
  1.1                  xml-xindice/Xindice/java/src/org/apache/xindice/core/objects/SimpleXMLObject.java
  
  Index: SimpleXMLObject.java
  ===================================================================
  package org.apache.xindice.core.objects;
  
  /*
   * The Apache Software License, Version 1.1
   *
   *
   * Copyright (c) 1999 The Apache Software Foundation.  All rights
   * reserved.
   *
   * Redistribution and use in source and binary forms, with or without
   * modification, are permitted provided that the following conditions
   * are met:
   *
   * 1. Redistributions of source code must retain the above copyright
   *    notice, this list of conditions and the following disclaimer.
   *
   * 2. Redistributions in binary form must reproduce the above copyright
   *    notice, this list of conditions and the following disclaimer in
   *    the documentation and/or other materials provided with the
   *    distribution.
   *
   * 3. The end-user documentation included with the redistribution,
   *    if any, must include the following acknowledgment:
   *       "This product includes software developed by the
   *        Apache Software Foundation (http://www.apache.org/)."
   *    Alternately, this acknowledgment may appear in the software itself,
   *    if and wherever such third-party acknowledgments normally appear.
   *
   * 4. The names "Xindice" and "Apache Software Foundation" must
   *    not be used to endorse or promote products derived from this
   *    software without prior written permission. For written
   *    permission, please contact apache@apache.org.
   *
   * 5. Products derived from this software may not be called "Apache",
   *    nor may "Apache" appear in their name, without prior written
   *    permission of the Apache Software Foundation.
   *
   * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
   * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
   * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
   * DISCLAIMED.  IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
   * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
   * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
   * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
   * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
   * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
   * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
   * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
   * SUCH DAMAGE.
   * ====================================================================
   *
   * This software consists of voluntary contributions made by many
   * individuals on behalf of the Apache Software Foundation and was
   * originally based on software copyright (c) 1999-2001, The dbXML
   * Group, L.L.C., http://www.dbxmlgroup.com.  For more
   * information on the Apache Software Foundation, please see
   * <http://www.apache.org/>.
   *
   * $Id: SimpleXMLObject.java,v 1.1 2001/12/06 21:00:13 bradford Exp $
   */
  
  import org.apache.xindice.core.*;
  import org.apache.xindice.util.*;
  
  import org.w3c.dom.*;
  import java.io.*;
  
  /**
   * SimpleXMLObject
   */
  
  public class SimpleXMLObject extends SimpleReflectable implements XMLObject {
     protected Collection collection = null;
  
     public void setCollection(Collection collection) {
        if ( this.collection == null )
           this.collection = collection;
     }
  
     public Collection getCollection() {
        return collection;
     }
  }
  
  
  
  1.1                  xml-xindice/Xindice/java/src/org/apache/xindice/core/objects/ThreadPolicy.java
  
  Index: ThreadPolicy.java
  ===================================================================
  package org.apache.xindice.core.objects;
  
  /*
   * The Apache Software License, Version 1.1
   *
   *
   * Copyright (c) 1999 The Apache Software Foundation.  All rights
   * reserved.
   *
   * Redistribution and use in source and binary forms, with or without
   * modification, are permitted provided that the following conditions
   * are met:
   *
   * 1. Redistributions of source code must retain the above copyright
   *    notice, this list of conditions and the following disclaimer.
   *
   * 2. Redistributions in binary form must reproduce the above copyright
   *    notice, this list of conditions and the following disclaimer in
   *    the documentation and/or other materials provided with the
   *    distribution.
   *
   * 3. The end-user documentation included with the redistribution,
   *    if any, must include the following acknowledgment:
   *       "This product includes software developed by the
   *        Apache Software Foundation (http://www.apache.org/)."
   *    Alternately, this acknowledgment may appear in the software itself,
   *    if and wherever such third-party acknowledgments normally appear.
   *
   * 4. The names "Xindice" and "Apache Software Foundation" must
   *    not be used to endorse or promote products derived from this
   *    software without prior written permission. For written
   *    permission, please contact apache@apache.org.
   *
   * 5. Products derived from this software may not be called "Apache",
   *    nor may "Apache" appear in their name, without prior written
   *    permission of the Apache Software Foundation.
   *
   * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
   * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
   * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
   * DISCLAIMED.  IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
   * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
   * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
   * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
   * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
   * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
   * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
   * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
   * SUCH DAMAGE.
   * ====================================================================
   *
   * This software consists of voluntary contributions made by many
   * individuals on behalf of the Apache Software Foundation and was
   * originally based on software copyright (c) 1999-2001, The dbXML
   * Group, L.L.C., http://www.dbxmlgroup.com.  For more
   * information on the Apache Software Foundation, please see
   * <http://www.apache.org/>.
   *
   * $Id: ThreadPolicy.java,v 1.1 2001/12/06 21:00:13 bradford Exp $
   */
  
  import org.apache.xindice.core.*;
  
  /**
   * ThreadPolicy is used by the XMLObjectManager in order to determine
   * whether or not an XMLObject needs a new or can expose a shared
   * instance.  As a marker interface, an XMLObject implementation needn't
   * implement ThreadPolicy if it wants to defer that control to the
   * default behavior of the XMLObject manager.
   */
  
  public interface ThreadPolicy {
     /**
      * SHARED_INSTANCE marks the object as capable of being shared by multiple
      * requesting threads.
      */
     static final int SHARED_INSTANCE = 0;
  
     /**
      * POOLED_INSTANCE marks the object as not being sharable, but capable of
      * being reused in a pooled fashion.  These objects must also implement the
      * Poolable interface.  SimpleReflectable, the base class for the generic
      * XMLObject implementations implements Poolable for you.
      */
     static final int POOLED_INSTANCE = 1;
  
     /**
      * NEW_INSTANCE marks the object as being neither sharable nor poolable.
      * All requests for this object will generate a new instance.
      */
     static final int NEW_INSTANCE = 2;
  
     /**
      * getThreadPolicy returns the Thread policy for the object instance.
      */
     int getThreadPolicy();
  }
  
  
  
  1.1                  xml-xindice/Xindice/java/src/org/apache/xindice/core/objects/Types.java
  
  Index: Types.java
  ===================================================================
  package org.apache.xindice.core.objects;
  
  /*
   * The Apache Software License, Version 1.1
   *
   *
   * Copyright (c) 1999 The Apache Software Foundation.  All rights
   * reserved.
   *
   * Redistribution and use in source and binary forms, with or without
   * modification, are permitted provided that the following conditions
   * are met:
   *
   * 1. Redistributions of source code must retain the above copyright
   *    notice, this list of conditions and the following disclaimer.
   *
   * 2. Redistributions in binary form must reproduce the above copyright
   *    notice, this list of conditions and the following disclaimer in
   *    the documentation and/or other materials provided with the
   *    distribution.
   *
   * 3. The end-user documentation included with the redistribution,
   *    if any, must include the following acknowledgment:
   *       "This product includes software developed by the
   *        Apache Software Foundation (http://www.apache.org/)."
   *    Alternately, this acknowledgment may appear in the software itself,
   *    if and wherever such third-party acknowledgments normally appear.
   *
   * 4. The names "Xindice" and "Apache Software Foundation" must
   *    not be used to endorse or promote products derived from this
   *    software without prior written permission. For written
   *    permission, please contact apache@apache.org.
   *
   * 5. Products derived from this software may not be called "Apache",
   *    nor may "Apache" appear in their name, without prior written
   *    permission of the Apache Software Foundation.
   *
   * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
   * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
   * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
   * DISCLAIMED.  IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
   * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
   * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
   * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
   * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
   * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
   * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
   * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
   * SUCH DAMAGE.
   * ====================================================================
   *
   * This software consists of voluntary contributions made by many
   * individuals on behalf of the Apache Software Foundation and was
   * originally based on software copyright (c) 1999-2001, The dbXML
   * Group, L.L.C., http://www.dbxmlgroup.com.  For more
   * information on the Apache Software Foundation, please see
   * <http://www.apache.org/>.
   *
   * $Id: Types.java,v 1.1 2001/12/06 21:00:13 bradford Exp $
   */
  
  import org.w3c.dom.*;
  import org.apache.xindice.core.*;
  
  /**
   * Types defines identifying values for the types that Xindice Reflectable
   * methods support.
   */
  
  public final class Types {
     public final static int EMPTY = -1;
     public final static int UNKNOWN = -1;
     public final static int VOID = 0;
     public final static int BOOLEAN = 1;
     public final static int BYTE = 2;
     public final static int CHAR = 3;
     public final static int SHORT = 4;
     public final static int INT = 5;
     public final static int LONG = 6;
     public final static int FLOAT = 7;
     public final static int DOUBLE = 8;
     public final static int OBJECT = 10;
     public final static int STRING = 11;
     public final static int ELEMENT = 12;
     public final static int DOCUMENT = 13;
     public final static int DOCUMENTFRAGMENT = 14;
     public final static int ARGS = 15;
     public final static int VARIANT = 20;
  
     private Types() {
     }
  
     /**
      * TypeOf inspects the Class, and returns the type value for that Class
      * or UNKNOWN, if the Class is not an acceptable signature type.
      *
      * @param c The Class to check
      * @return The type value
      */
     public static int typeOf(Class c) {
        if( c.isArray() )
           c = c.getComponentType();
  
        if ( c == void.class )
           return VOID;
  
        if ( c.isPrimitive() ) {
           if ( c == Boolean.TYPE )
              return BOOLEAN;
           else if ( c == Byte.TYPE )
              return BYTE;
           else if ( c == Character.TYPE )
              return CHAR;
           else if ( c  == Short.TYPE )
              return SHORT;
           else if ( c == Integer.TYPE )
              return INT;
           else if ( c == Long.TYPE )
              return LONG;
           else if ( c == Float.TYPE )
              return FLOAT;
           else if ( c == Double.TYPE )
              return DOUBLE;
        }
        else {
           if ( c == String.class )
              return STRING;
           else if ( c == Variant.class )
              return VARIANT;
           else if ( Element.class.isAssignableFrom(c) )
              return ELEMENT;
           else if ( Document.class.isAssignableFrom(c) )
              return DOCUMENT;
           else if ( DocumentFragment.class.isAssignableFrom(c) )
              return DOCUMENTFRAGMENT;
           else if ( Args.class.isAssignableFrom(c) )
              return ARGS;
        }
        return UNKNOWN;
     }
  
     public static int typeOf(Object object) {
        return object != null ? typeOf(object.getClass())
                              : EMPTY;
     }
  
     public static String typeName(int type) {
        switch ( type ) {
  
           case UNKNOWN          : return "Unknown";
           case VOID             : return "void";
           case BOOLEAN          : return "boolean";
           case BYTE             : return "byte";
           case CHAR             : return "char";
           case SHORT            : return "short";
           case INT              : return "int";
           case LONG             : return "long";
           case FLOAT            : return "float";
           case DOUBLE           : return "double";
           case OBJECT           : return "Object";
           case STRING           : return "String";
           case ELEMENT          : return "Element";
           case DOCUMENT         : return "Document";
           case DOCUMENTFRAGMENT : return "DocumentFragment";
           case ARGS             : return "Args";
           case VARIANT          : return "Variant";
  
        }
        return "Invalid";
     }
  }
  
  
  
  
  1.1                  xml-xindice/Xindice/java/src/org/apache/xindice/core/objects/Variant.java
  
  Index: Variant.java
  ===================================================================
  package org.apache.xindice.core.objects;
  
  /*
   * The Apache Software License, Version 1.1
   *
   *
   * Copyright (c) 1999 The Apache Software Foundation.  All rights
   * reserved.
   *
   * Redistribution and use in source and binary forms, with or without
   * modification, are permitted provided that the following conditions
   * are met:
   *
   * 1. Redistributions of source code must retain the above copyright
   *    notice, this list of conditions and the following disclaimer.
   *
   * 2. Redistributions in binary form must reproduce the above copyright
   *    notice, this list of conditions and the following disclaimer in
   *    the documentation and/or other materials provided with the
   *    distribution.
   *
   * 3. The end-user documentation included with the redistribution,
   *    if any, must include the following acknowledgment:
   *       "This product includes software developed by the
   *        Apache Software Foundation (http://www.apache.org/)."
   *    Alternately, this acknowledgment may appear in the software itself,
   *    if and wherever such third-party acknowledgments normally appear.
   *
   * 4. The names "Xindice" and "Apache Software Foundation" must
   *    not be used to endorse or promote products derived from this
   *    software without prior written permission. For written
   *    permission, please contact apache@apache.org.
   *
   * 5. Products derived from this software may not be called "Apache",
   *    nor may "Apache" appear in their name, without prior written
   *    permission of the Apache Software Foundation.
   *
   * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
   * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
   * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
   * DISCLAIMED.  IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
   * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
   * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
   * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
   * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
   * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
   * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
   * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
   * SUCH DAMAGE.
   * ====================================================================
   *
   * This software consists of voluntary contributions made by many
   * individuals on behalf of the Apache Software Foundation and was
   * originally based on software copyright (c) 1999-2001, The dbXML
   * Group, L.L.C., http://www.dbxmlgroup.com.  For more
   * information on the Apache Software Foundation, please see
   * <http://www.apache.org/>.
   *
   * $Id: Variant.java,v 1.1 2001/12/06 21:00:13 bradford Exp $
   */
  
  import org.apache.xindice.core.*;
  import org.apache.xindice.xml.*;
  import org.apache.xindice.util.*;
  
  import org.w3c.dom.*;
  
  /**
   * Variant is a generic type that can be used to store any type of Xindice
   * variable.  Variants will do their best to convert the value that they
   * store to any requested type.
   */
  
  public final class Variant {
     private Object value = null;
     private int type = -1;
  
     public Variant() {
     }
  
     public Variant(Variant value) {
        this.value = value.value;
        type = value.type;
     }
  
     public Variant(String value) {
        this.value = value;
        type = Types.STRING;
     }
  
     public Variant(boolean value) {
        this.value = new Boolean(value);
        type = Types.BOOLEAN;
     }
  
     public Variant(byte value) {
        this.value = new Byte(value);
        type = Types.BYTE;
     }
  
     public Variant(char value) {
        this.value = new Character(value);
        type = Types.CHAR;
     }
  
     public Variant(short value) {
        this.value = new Short(value);
        type = Types.SHORT;
     }
  
     public Variant(int value) {
        this.value = new Integer(value);
        type = Types.INT;
     }
  
     public Variant(long value) {
        this.value = new Long(value);
        type = Types.LONG;
     }
  
     public Variant(float value) {
        this.value = new Float(value);
        type = Types.FLOAT;
     }
  
     public Variant(double value) {
        this.value = new Double(value);
        type = Types.DOUBLE;
     }
  
     public Variant(Element value) {
        this.value = value;
        type = Types.ELEMENT;
     }
  
     public Variant(Document value) {
        this.value = value;
        type = Types.DOCUMENT;
     }
  
     public Variant(DocumentFragment value) {
        this.value = value;
        type = Types.DOCUMENTFRAGMENT;
     }
  
     public Variant(Args value) {
        this.value = value;
        type = Types.ARGS;
     }
  
     public Variant(Object value) {
        this.value = value;
        type = Types.OBJECT;
     }
  
     /**
      * getType returns the type of the variable being stored in the Variant.
      *
      * @return The variable type
      */
     public int getType() {
        return type;
     }
  
     /**
      * isNull returns whether or not the variable is storing a null value.
      */
     public boolean isNull() {
        return value == null;
     }
  
     /**
      * set sets the value as a String.
      *
      * @param value The value
      */
     public void set(String value) {
        this.value = value;
        type = Types.STRING;
     }
  
     /**
      * set sets the value as a boolean.
      *
      * @param value The value
      */
     public void set(boolean value) {
        this.value = new Boolean(value);
        type = Types.BOOLEAN;
     }
  
     /**
      * set sets the value as a byte.
      *
      * @param value The value
      */
     public void set(byte value) {
        this.value = new Byte(value);
        type = Types.BYTE;
     }
  
     /**
      * set sets the value as a char.
      *
      * @param value The value
      */
     public void set(char value) {
        this.value = new Character(value);
        type = Types.CHAR;
     }
  
     /**
      * set sets the value as a short
      *
      * @param value The value
      */
     public void set(short value) {
        this.value = new Short(value);
        type = Types.SHORT;
     }
  
     /**
      * set sets the value as an int.
      *
      * @param value The value
      */
     public void set(int value) {
        this.value = new Integer(value);
        type = Types.INT;
     }
  
     /**
      * set sets the value as a long.
      *
      * @param value The value
      */
     public void set(long value) {
        this.value = new Long(value);
        type = Types.LONG;
     }
  
     /**
      * set sets the value as a float.
      *
      * @param value The value
      */
     public void set(float value) {
        this.value = new Float(value);
        type = Types.FLOAT;
     }
  
     /**
      * set sets the value as a double.
      *
      * @param value The value
      */
     public void set(double value) {
        this.value = new Double(value);
        type = Types.DOUBLE;
     }
  
     /**
      * set sets the value as an Element.
      *
      * @param value The value
      */
     public void set(Element value) {
        this.value = value;
        type = Types.ELEMENT;
     }
  
     /**
      * set sets the value as a Document.
      *
      * @param value The value
      */
     public void set(Document value) {
        this.value = value;
        type = Types.DOCUMENT;
     }
  
     /**
      * set sets the value as a DocumentFragment.
      *
      * @param value The value
      */
     public void set(DocumentFragment value) {
        this.value = value;
        type = Types.DOCUMENTFRAGMENT;
     }
  
     /**
      * set sets the value as an Args instance.
      *
      * @param value The value
      */
     public void set(Args value) {
        this.value = value;
        type = Types.ARGS;
     }
  
     /**
      * set sets the value as an Object.
      *
      * @param value The value
      */
     public void set(Object object) {
        this.value = value;
        type = value != null ? Types.OBJECT
                             : Types.EMPTY;
     }
  
     /**
      * getString returns the value as a String.
      *
      * @return The value
      */
     public String getString() {
        if ( type == Types.STRING )
           return (String)value;
        else
           return value.toString();
     }
  
     /**
      * getBoolean returns the value as a boolean.
      *
      * @return The value
      */
     public boolean getBoolean() {
        if ( type == Types.BOOLEAN )
           return ((Boolean)value).booleanValue();
        else
           return "[true][yes][1][y][on]".indexOf("["+value.toString().toLowerCase()+"]") != -1;
     }
  
     /**
      * getByte returns the value as a byte.
      *
      * @return The value
      */
     public byte getByte() {
        if ( type == Types.BYTE )
           return ((Byte)value).byteValue();
        else
           return Byte.parseByte(value.toString());
     }
  
     /**
      * getChar returns the value as a char.
      *
      * @return The value
      */
     public char getChar() {
        if ( type == Types.CHAR )
           return ((Character)value).charValue();
        else
           return value.toString().charAt(0);
     }
  
     /**
      * getShort returns the value as a short.
      *
      * @return The value
      */
     public short getShort() {
        if ( type == Types.SHORT )
           return ((Short)value).shortValue();
        else
           return Short.parseShort(value.toString());
     }
  
     /**
      * getInt returns the value as an int.
      *
      * @return The value
      */
     public int getInt() {
        if ( type == Types.INT )
           return ((Integer)value).intValue();
        else
           return Integer.parseInt(value.toString());
     }
  
     /**
      * getLong returns the value as a long.
      *
      * @return The value
      */
     public long getLong() {
        if ( type == Types.LONG )
           return ((Long)value).longValue();
        else
           return Long.parseLong(value.toString());
     }
  
     /**
      * getFloat returns the value as a float.
      *
      * @return The value
      */
     public float getFloat() {
        if ( type == Types.FLOAT )
           return ((Float)value).floatValue();
        else
           return Float.parseFloat(value.toString());
     }
  
     /**
      * getDouble returns the value as a double.
      *
      * @return The value
      */
     public double getDouble() {
        if ( type == Types.DOUBLE )
           return ((Double)value).doubleValue();
        else
           return Double.parseDouble(value.toString());
     }
  
     /**
      * getElement returns the value as an Element.
      *
      * @return The value
      */
     public Element getElement() {
        if ( type == Types.ELEMENT )
           return (Element)value;
        else
           return null;
     }
  
     /**
      * getDocument returns the value as a Document.
      *
      * @return The value
      */
     public Document getDocument() {
        if ( type == Types.DOCUMENT )
           return (Document)value;
        else
           return null;
     }
  
     /**
      * getDocumentFragment returns the value as a DocumentFragment.
      *
      * @return The value
      */
     public DocumentFragment getDocumentFragment() {
        if ( type == Types.DOCUMENTFRAGMENT )
           return (DocumentFragment)value;
        else
           return null;
     }
  
     /**
      * getArgs returns the value as an Args instance.
      *
      * @return The value
      */
     public Args getArgs() {
        if ( type == Types.ARGS )
           return (Args)value;
        else
           return null;
     }
  
     /**
      * getObject returns the value as an Object.
      *
      * @return The value
      */
     public Object getObject() {
        return value;
     }
  
     /**
      * toString returns the value as a Stringified representation.
      *
      * @return The stringified value
      */
     public String toString() {
        switch ( type ) {
  
           case Types.ELEMENT:
           case Types.DOCUMENT:
           case Types.DOCUMENTFRAGMENT:
              return TextWriter.toString((Node)value);
  
           default:
              return value.toString();
  
        }
     }
  }
  
  
  
  
  1.1                  xml-xindice/Xindice/java/src/org/apache/xindice/core/objects/XMLObject.java
  
  Index: XMLObject.java
  ===================================================================
  package org.apache.xindice.core.objects;
  
  /*
   * The Apache Software License, Version 1.1
   *
   *
   * Copyright (c) 1999 The Apache Software Foundation.  All rights
   * reserved.
   *
   * Redistribution and use in source and binary forms, with or without
   * modification, are permitted provided that the following conditions
   * are met:
   *
   * 1. Redistributions of source code must retain the above copyright
   *    notice, this list of conditions and the following disclaimer.
   *
   * 2. Redistributions in binary form must reproduce the above copyright
   *    notice, this list of conditions and the following disclaimer in
   *    the documentation and/or other materials provided with the
   *    distribution.
   *
   * 3. The end-user documentation included with the redistribution,
   *    if any, must include the following acknowledgment:
   *       "This product includes software developed by the
   *        Apache Software Foundation (http://www.apache.org/)."
   *    Alternately, this acknowledgment may appear in the software itself,
   *    if and wherever such third-party acknowledgments normally appear.
   *
   * 4. The names "Xindice" and "Apache Software Foundation" must
   *    not be used to endorse or promote products derived from this
   *    software without prior written permission. For written
   *    permission, please contact apache@apache.org.
   *
   * 5. Products derived from this software may not be called "Apache",
   *    nor may "Apache" appear in their name, without prior written
   *    permission of the Apache Software Foundation.
   *
   * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
   * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
   * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
   * DISCLAIMED.  IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
   * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
   * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
   * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
   * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
   * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
   * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
   * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
   * SUCH DAMAGE.
   * ====================================================================
   *
   * This software consists of voluntary contributions made by many
   * individuals on behalf of the Apache Software Foundation and was
   * originally based on software copyright (c) 1999-2001, The dbXML
   * Group, L.L.C., http://www.dbxmlgroup.com.  For more
   * information on the Apache Software Foundation, please see
   * <http://www.apache.org/>.
   *
   * $Id: XMLObject.java,v 1.1 2001/12/06 21:00:13 bradford Exp $
   */
  
  import org.apache.xindice.core.*;
  import org.apache.xindice.util.*;
  
  import org.w3c.dom.*;
  
  /**
   * XMLObject is an interface used to identify a class as a being a Xindice
   * XML Object.  An XML Object is an object that is designed specifically
   * to extend or refine access to a Xindice Collection.
   */
  
  public interface XMLObject extends Reflectable, Named, Configurable {
     void setCollection(Collection collection);
     Collection getCollection();
  }
  
  
  
  
  1.1                  xml-xindice/Xindice/java/src/org/apache/xindice/core/objects/XMLObjectException.java
  
  Index: XMLObjectException.java
  ===================================================================
  package org.apache.xindice.core.objects;
  
  /*
   * The Apache Software License, Version 1.1
   *
   *
   * Copyright (c) 1999 The Apache Software Foundation.  All rights
   * reserved.
   *
   * Redistribution and use in source and binary forms, with or without
   * modification, are permitted provided that the following conditions
   * are met:
   *
   * 1. Redistributions of source code must retain the above copyright
   *    notice, this list of conditions and the following disclaimer.
   *
   * 2. Redistributions in binary form must reproduce the above copyright
   *    notice, this list of conditions and the following disclaimer in
   *    the documentation and/or other materials provided with the
   *    distribution.
   *
   * 3. The end-user documentation included with the redistribution,
   *    if any, must include the following acknowledgment:
   *       "This product includes software developed by the
   *        Apache Software Foundation (http://www.apache.org/)."
   *    Alternately, this acknowledgment may appear in the software itself,
   *    if and wherever such third-party acknowledgments normally appear.
   *
   * 4. The names "Xindice" and "Apache Software Foundation" must
   *    not be used to endorse or promote products derived from this
   *    software without prior written permission. For written
   *    permission, please contact apache@apache.org.
   *
   * 5. Products derived from this software may not be called "Apache",
   *    nor may "Apache" appear in their name, without prior written
   *    permission of the Apache Software Foundation.
   *
   * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
   * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
   * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
   * DISCLAIMED.  IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
   * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
   * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
   * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
   * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
   * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
   * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
   * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
   * SUCH DAMAGE.
   * ====================================================================
   *
   * This software consists of voluntary contributions made by many
   * individuals on behalf of the Apache Software Foundation and was
   * originally based on software copyright (c) 1999-2001, The dbXML
   * Group, L.L.C., http://www.dbxmlgroup.com.  For more
   * information on the Apache Software Foundation, please see
   * <http://www.apache.org/>.
   *
   * $Id: XMLObjectException.java,v 1.1 2001/12/06 21:00:13 bradford Exp $
   */
  
  import org.apache.xindice.core.*;
  
  /**
   * A XMLObjectException is thrown by the Reflector if an exception occurs in the
   * reflection, lookup, or execution of an XMLObject's method.
   */
  
  public class XMLObjectException extends DBException {
     public XMLObjectException(int faultCode) {
        super(faultCode);
     }
     
     public XMLObjectException(int faultCode, String message) {
        super(faultCode, message);
     }
  }
  
  
  
  1.1                  xml-xindice/Xindice/java/src/org/apache/xindice/core/objects/XMLObjectManager.java
  
  Index: XMLObjectManager.java
  ===================================================================
  package org.apache.xindice.core.objects;
  
  /*
   * The Apache Software License, Version 1.1
   *
   *
   * Copyright (c) 1999 The Apache Software Foundation.  All rights
   * reserved.
   *
   * Redistribution and use in source and binary forms, with or without
   * modification, are permitted provided that the following conditions
   * are met:
   *
   * 1. Redistributions of source code must retain the above copyright
   *    notice, this list of conditions and the following disclaimer.
   *
   * 2. Redistributions in binary form must reproduce the above copyright
   *    notice, this list of conditions and the following disclaimer in
   *    the documentation and/or other materials provided with the
   *    distribution.
   *
   * 3. The end-user documentation included with the redistribution,
   *    if any, must include the following acknowledgment:
   *       "This product includes software developed by the
   *        Apache Software Foundation (http://www.apache.org/)."
   *    Alternately, this acknowledgment may appear in the software itself,
   *    if and wherever such third-party acknowledgments normally appear.
   *
   * 4. The names "Xindice" and "Apache Software Foundation" must
   *    not be used to endorse or promote products derived from this
   *    software without prior written permission. For written
   *    permission, please contact apache@apache.org.
   *
   * 5. Products derived from this software may not be called "Apache",
   *    nor may "Apache" appear in their name, without prior written
   *    permission of the Apache Software Foundation.
   *
   * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
   * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
   * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
   * DISCLAIMED.  IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
   * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
   * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
   * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
   * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
   * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
   * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
   * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
   * SUCH DAMAGE.
   * ====================================================================
   *
   * This software consists of voluntary contributions made by many
   * individuals on behalf of the Apache Software Foundation and was
   * originally based on software copyright (c) 1999-2001, The dbXML
   * Group, L.L.C., http://www.dbxmlgroup.com.  For more
   * information on the Apache Software Foundation, please see
   * <http://www.apache.org/>.
   *
   * $Id: XMLObjectManager.java,v 1.1 2001/12/06 21:00:13 bradford Exp $
   */
  
  import org.apache.xindice.core.*;
  import org.apache.xindice.core.Collection;
  import org.apache.xindice.util.*;
  
  import java.util.*;
  
  /**
   * XMLObjectManager manages XMLObject instances.
   */
  
  public final class XMLObjectManager extends SimpleConfigurable {
     private static final String XMLOBJECTS = "xmlobjects";
     private static final String XMLOBJECT = "xmlobject";
     private static final String NAME = "name";
     private static final String CLASS = "class";
  
     private static final String[] EmptyStrings = new String[0];
  
     private Map objects = new HashMap(); // String to XMLObjectInfo
     private Collection collection;
  
     public XMLObjectManager(Collection collection) {
        this.collection = collection;
     }
  
     public void setConfig(Configuration config) throws XindiceException {
        super.setConfig(config);
        config.processChildren(XMLOBJECT,
           new ConfigurationCallback() {
              public void process(Configuration cfg) {
                 String className = cfg.getAttribute(CLASS);
                 try {
                    register(Class.forName(className), cfg);
                 }
                 catch ( Exception e ) {
                    org.apache.xindice.Debug.printStackTrace(e);
                 }
              }
        });
     }
  
     /**
      * list returns a list of the XMLObjects that this XMLObjectManager has
      * registered.
      *
      * @return An array containing the XMLObject names
      */
     public String[] list() {
        return (String[])objects.keySet().toArray(EmptyStrings);
     }
  
     /**
      * drop physically removes the specified XMLObject and any
      * associated system resources that the XMLObject uses.
      *
      * @param name The XMLObject to drop
      * @return Whether or not the XMLObject was dropped
      */
     public boolean drop(final String name) {
        unregister(name);
        config.processChildren(XMLOBJECT,
           new ConfigurationCallback() {
              public void process(Configuration cfg) {
                 try {
                    if ( cfg.getAttribute(NAME).equals(name) )
                       cfg.delete();
                 }
                 catch ( Exception e ) {
                    org.apache.xindice.Debug.printStackTrace(e);
                 }
              }
        });
        return true;
     }
  
     /**
      * create creates a new XMLObject object and any associated
      * system resources that the XMLObject will need.
      *
      * @param cfg The XMLObject's configuration
      * @return The XMLObject that was created
      */
     public XMLObject create(Configuration cfg) throws DBException {
        String className = cfg.getAttribute(CLASS);
        try {
           // Check for duplicates
           String name = cfg.getAttribute(NAME);
           Configuration[] cfgs = config.getChildren();
           for ( int i = 0; i < cfgs.length; i++ )
              if ( cfgs[i].getAttribute(NAME).equals(name) )
                 throw new DuplicateObjectException("Duplicate XMLObject '"+name+"'");
  
           config.add(cfg);
           
           Class c = Class.forName(className);
           XMLObject obj = register(c, cfg);
           
           return obj;
        }
        catch ( DBException d ) {
           throw d;
        }
        catch ( Exception e ) {
           throw new CannotCreateException("Cannot create XMLObject");
        }
     }
  
     public XMLObject register(Class c, Configuration cfg) throws DBException {
        String name = null;
        try {
           XMLObject obj = (XMLObject)c.newInstance();
           initialize(obj, cfg);
           name = obj.getName();
           
           if ( name == null || name.trim().equals("") )
              throw new CannotCreateException("No name specified");
           
           int policy = ThreadPolicy.SHARED_INSTANCE;
  
           if ( obj instanceof ThreadPolicy )
              policy = ((ThreadPolicy)obj).getThreadPolicy();
  
           objects.put(name, new XMLObjectInfo(name, obj, cfg, policy));
           
           return obj;
        }
        catch ( DBException d ) {
           throw d;
        }
        catch ( Exception e ) {
           throw new InvalidContextException("'"+name+"' is not a valid XMLObject");
        }
     }
  
     public void unregister(String name) {
        objects.remove(name);
     }
  
     private void initialize(XMLObject obj, Configuration cfg) throws XindiceException {
        obj.setConfig(cfg);
        obj.setCollection(collection);
     }
  
     /**
      * get retrieves an XMLObject by name, and will also do the work of
      * instantiation and pool-retrieval.
      *
      * @name The XMLObject name
      * @return The XMLObject
      */
     public XMLObject get(String name) {
        XMLObject obj = null;
        try {
           XMLObjectInfo info = (XMLObjectInfo)objects.get(name);
  
           switch ( info.policy ) {
  
              case ThreadPolicy.NEW_INSTANCE:
                 obj = (XMLObject)info.c.newInstance();
                 initialize(obj, info.cfg);
                 break;
  
              case ThreadPolicy.POOLED_INSTANCE:
                 obj = (XMLObject)info.getObject();
                 break;
  
              case ThreadPolicy.SHARED_INSTANCE:
                 obj = info.instance;
                 break;
  
           }
        }
        catch ( Exception e ) {
        }
        return obj;
     }
  
     public String getCanonicalName(String name) {
        return collection.getCanonicalName()+"/"+name;
     }
  
     private class XMLObjectInfo extends ObjectPool {
        public String name;
        public Class c;
        public int policy;
        public XMLObject instance;
        public Configuration cfg;
  
        public XMLObjectInfo(String name, XMLObject instance, Configuration cfg, int policy) {
           this.name = name;
           this.policy = policy;
           this.cfg = cfg;
           switch ( policy ) {
  
              case ThreadPolicy.POOLED_INSTANCE:
                 if ( ! (instance instanceof Poolable) )
                     policy = ThreadPolicy.NEW_INSTANCE;
  
              case ThreadPolicy.NEW_INSTANCE:
                 c = instance.getClass();
                 break;
  
              case ThreadPolicy.SHARED_INSTANCE:
                 this.instance = instance;
                 break;
           }
        }
  
        public Poolable createObject() {
           try {
              Poolable obj = (Poolable)c.newInstance();
              XMLObject xobj = (XMLObject)obj;
              initialize(xobj, cfg);
              return obj;
           }
           catch ( Exception e ) {
              org.apache.xindice.Debug.printStackTrace(e);
           }
           return null;
        }
     }
  }
  
  
  
  
  
  1.1                  xml-xindice/Xindice/java/src/org/apache/xindice/core/objects/XMLObjectRuntimeException.java
  
  Index: XMLObjectRuntimeException.java
  ===================================================================
  package org.apache.xindice.core.objects;
  
  /*
   * The Apache Software License, Version 1.1
   *
   *
   * Copyright (c) 1999 The Apache Software Foundation.  All rights
   * reserved.
   *
   * Redistribution and use in source and binary forms, with or without
   * modification, are permitted provided that the following conditions
   * are met:
   *
   * 1. Redistributions of source code must retain the above copyright
   *    notice, this list of conditions and the following disclaimer.
   *
   * 2. Redistributions in binary form must reproduce the above copyright
   *    notice, this list of conditions and the following disclaimer in
   *    the documentation and/or other materials provided with the
   *    distribution.
   *
   * 3. The end-user documentation included with the redistribution,
   *    if any, must include the following acknowledgment:
   *       "This product includes software developed by the
   *        Apache Software Foundation (http://www.apache.org/)."
   *    Alternately, this acknowledgment may appear in the software itself,
   *    if and wherever such third-party acknowledgments normally appear.
   *
   * 4. The names "Xindice" and "Apache Software Foundation" must
   *    not be used to endorse or promote products derived from this
   *    software without prior written permission. For written
   *    permission, please contact apache@apache.org.
   *
   * 5. Products derived from this software may not be called "Apache",
   *    nor may "Apache" appear in their name, without prior written
   *    permission of the Apache Software Foundation.
   *
   * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
   * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
   * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
   * DISCLAIMED.  IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
   * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
   * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
   * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
   * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
   * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
   * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
   * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
   * SUCH DAMAGE.
   * ====================================================================
   *
   * This software consists of voluntary contributions made by many
   * individuals on behalf of the Apache Software Foundation and was
   * originally based on software copyright (c) 1999-2001, The dbXML
   * Group, L.L.C., http://www.dbxmlgroup.com.  For more
   * information on the Apache Software Foundation, please see
   * <http://www.apache.org/>.
   *
   * $Id: XMLObjectRuntimeException.java,v 1.1 2001/12/06 21:00:13 bradford Exp $
   */
  
  import org.apache.xindice.core.*;
  
  /**
   * A XMLObjectRuntimeException is thrown if an uncaught Exception
   * occurs while executing an XMLObject's method.
   */
  
  public final class XMLObjectRuntimeException extends XMLObjectException {
     public XMLObjectRuntimeException() {
        super(FaultCodes.OBJ_RUNTIME_EXCEPTION);
     }
     
     public XMLObjectRuntimeException(String message) {
        super(FaultCodes.OBJ_RUNTIME_EXCEPTION, message);
     }
  }
  
  
  
  1.1                  xml-xindice/Xindice/java/src/org/apache/xindice/core/objects/package.html
  
  Index: package.html
  ===================================================================
  <html>
    <title>Xindice XML Object System.</title>
    <body>
      <p>Defines the Xindice XMLObject interface and implements XMLObjectManager,
      a reflection/invokation system and a Simple XMLObject implementation.</p>
   </body>
  </html>
  
  
  
  
  
  1.1                  xml-xindice/Xindice/java/src/org/apache/xindice/core/query/CompilationException.java
  
  Index: CompilationException.java
  ===================================================================
  package org.apache.xindice.core.query;
  
  /*
   * The Apache Software License, Version 1.1
   *
   *
   * Copyright (c) 1999 The Apache Software Foundation.  All rights
   * reserved.
   *
   * Redistribution and use in source and binary forms, with or without
   * modification, are permitted provided that the following conditions
   * are met:
   *
   * 1. Redistributions of source code must retain the above copyright
   *    notice, this list of conditions and the following disclaimer.
   *
   * 2. Redistributions in binary form must reproduce the above copyright
   *    notice, this list of conditions and the following disclaimer in
   *    the documentation and/or other materials provided with the
   *    distribution.
   *
   * 3. The end-user documentation included with the redistribution,
   *    if any, must include the following acknowledgment:
   *       "This product includes software developed by the
   *        Apache Software Foundation (http://www.apache.org/)."
   *    Alternately, this acknowledgment may appear in the software itself,
   *    if and wherever such third-party acknowledgments normally appear.
   *
   * 4. The names "Xindice" and "Apache Software Foundation" must
   *    not be used to endorse or promote products derived from this
   *    software without prior written permission. For written
   *    permission, please contact apache@apache.org.
   *
   * 5. Products derived from this software may not be called "Apache",
   *    nor may "Apache" appear in their name, without prior written
   *    permission of the Apache Software Foundation.
   *
   * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
   * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
   * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
   * DISCLAIMED.  IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
   * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
   * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
   * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
   * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
   * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
   * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
   * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
   * SUCH DAMAGE.
   * ====================================================================
   *
   * This software consists of voluntary contributions made by many
   * individuals on behalf of the Apache Software Foundation and was
   * originally based on software copyright (c) 1999-2001, The dbXML
   * Group, L.L.C., http://www.dbxmlgroup.com.  For more
   * information on the Apache Software Foundation, please see
   * <http://www.apache.org/>.
   *
   * $Id: CompilationException.java,v 1.1 2001/12/06 21:00:14 bradford Exp $
   */
  
  import org.apache.xindice.core.*;
  
  /**
   * A CompilationException is thrown by a Query if for some reason,
   * it can't compile the query being processed.
   */
  
  public final class CompilationException extends QueryException {
     public CompilationException() {
        super(FaultCodes.QRY_COMPILATION_ERROR);
     }
     
     public CompilationException(String message) {
        super(FaultCodes.QRY_COMPILATION_ERROR, message);
     }
  }
  
  
  
  1.1                  xml-xindice/Xindice/java/src/org/apache/xindice/core/query/NodeListSet.java
  
  Index: NodeListSet.java
  ===================================================================
  package org.apache.xindice.core.query;
  
  /*
   * The Apache Software License, Version 1.1
   *
   *
   * Copyright (c) 1999 The Apache Software Foundation.  All rights
   * reserved.
   *
   * Redistribution and use in source and binary forms, with or without
   * modification, are permitted provided that the following conditions
   * are met:
   *
   * 1. Redistributions of source code must retain the above copyright
   *    notice, this list of conditions and the following disclaimer.
   *
   * 2. Redistributions in binary form must reproduce the above copyright
   *    notice, this list of conditions and the following disclaimer in
   *    the documentation and/or other materials provided with the
   *    distribution.
   *
   * 3. The end-user documentation included with the redistribution,
   *    if any, must include the following acknowledgment:
   *       "This product includes software developed by the
   *        Apache Software Foundation (http://www.apache.org/)."
   *    Alternately, this acknowledgment may appear in the software itself,
   *    if and wherever such third-party acknowledgments normally appear.
   *
   * 4. The names "Xindice" and "Apache Software Foundation" must
   *    not be used to endorse or promote products derived from this
   *    software without prior written permission. For written
   *    permission, please contact apache@apache.org.
   *
   * 5. Products derived from this software may not be called "Apache",
   *    nor may "Apache" appear in their name, without prior written
   *    permission of the Apache Software Foundation.
   *
   * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
   * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
   * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
   * DISCLAIMED.  IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
   * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
   * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
   * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
   * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
   * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
   * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
   * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
   * SUCH DAMAGE.
   * ====================================================================
   *
   * This software consists of voluntary contributions made by many
   * individuals on behalf of the Apache Software Foundation and was
   * originally based on software copyright (c) 1999-2001, The dbXML
   * Group, L.L.C., http://www.dbxmlgroup.com.  For more
   * information on the Apache Software Foundation, please see
   * <http://www.apache.org/>.
   *
   * $Id: NodeListSet.java,v 1.1 2001/12/06 21:00:14 bradford Exp $
   */
  
  import org.apache.xindice.core.data.*;
  import org.apache.xindice.xml.dom.*;
  
  import org.w3c.dom.*;
  
  /**
   * NodeListSet is a simple NodeList wrapper
   */
  
  public final class NodeListSet implements NodeSet {
     public NodeList list;
     public int idx = 0;
  
     public NodeListSet(NodeList list) {
        this.list = list;
     }
  
     public boolean hasMoreNodes() {
        return ( idx < list.getLength() );
     }
  
     public Node getNextNode() {
        DBNode n = (DBNode)list.item(idx++);
        if ( n != null )
           n.expandSource();
        return n;
     }
  }
  
  
  
  1.1                  xml-xindice/Xindice/java/src/org/apache/xindice/core/query/ProcessingException.java
  
  Index: ProcessingException.java
  ===================================================================
  package org.apache.xindice.core.query;
  
  /*
   * The Apache Software License, Version 1.1
   *
   *
   * Copyright (c) 1999 The Apache Software Foundation.  All rights
   * reserved.
   *
   * Redistribution and use in source and binary forms, with or without
   * modification, are permitted provided that the following conditions
   * are met:
   *
   * 1. Redistributions of source code must retain the above copyright
   *    notice, this list of conditions and the following disclaimer.
   *
   * 2. Redistributions in binary form must reproduce the above copyright
   *    notice, this list of conditions and the following disclaimer in
   *    the documentation and/or other materials provided with the
   *    distribution.
   *
   * 3. The end-user documentation included with the redistribution,
   *    if any, must include the following acknowledgment:
   *       "This product includes software developed by the
   *        Apache Software Foundation (http://www.apache.org/)."
   *    Alternately, this acknowledgment may appear in the software itself,
   *    if and wherever such third-party acknowledgments normally appear.
   *
   * 4. The names "Xindice" and "Apache Software Foundation" must
   *    not be used to endorse or promote products derived from this
   *    software without prior written permission. For written
   *    permission, please contact apache@apache.org.
   *
   * 5. Products derived from this software may not be called "Apache",
   *    nor may "Apache" appear in their name, without prior written
   *    permission of the Apache Software Foundation.
   *
   * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
   * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
   * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
   * DISCLAIMED.  IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
   * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
   * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
   * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
   * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
   * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
   * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
   * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
   * SUCH DAMAGE.
   * ====================================================================
   *
   * This software consists of voluntary contributions made by many
   * individuals on behalf of the Apache Software Foundation and was
   * originally based on software copyright (c) 1999-2001, The dbXML
   * Group, L.L.C., http://www.dbxmlgroup.com.  For more
   * information on the Apache Software Foundation, please see
   * <http://www.apache.org/>.
   *
   * $Id: ProcessingException.java,v 1.1 2001/12/06 21:00:14 bradford Exp $
   */
  
  import org.apache.xindice.core.*;
  
  /**
   * A ProcessingException is thrown by a Query if for some reason,
   * it fails to actually process the query request.
   */
  
  public final class ProcessingException extends QueryException {
     public ProcessingException() {
        super(FaultCodes.QRY_PROCESSING_ERROR);
     }
     
     public ProcessingException(String message) {
        super(FaultCodes.QRY_PROCESSING_ERROR, message);
     }
  }
  
  
  
  1.1                  xml-xindice/Xindice/java/src/org/apache/xindice/core/query/Query.java
  
  Index: Query.java
  ===================================================================
  package org.apache.xindice.core.query;
  
  /*
   * The Apache Software License, Version 1.1
   *
   *
   * Copyright (c) 1999 The Apache Software Foundation.  All rights
   * reserved.
   *
   * Redistribution and use in source and binary forms, with or without
   * modification, are permitted provided that the following conditions
   * are met:
   *
   * 1. Redistributions of source code must retain the above copyright
   *    notice, this list of conditions and the following disclaimer.
   *
   * 2. Redistributions in binary form must reproduce the above copyright
   *    notice, this list of conditions and the following disclaimer in
   *    the documentation and/or other materials provided with the
   *    distribution.
   *
   * 3. The end-user documentation included with the redistribution,
   *    if any, must include the following acknowledgment:
   *       "This product includes software developed by the
   *        Apache Software Foundation (http://www.apache.org/)."
   *    Alternately, this acknowledgment may appear in the software itself,
   *    if and wherever such third-party acknowledgments normally appear.
   *
   * 4. The names "Xindice" and "Apache Software Foundation" must
   *    not be used to endorse or promote products derived from this
   *    software without prior written permission. For written
   *    permission, please contact apache@apache.org.
   *
   * 5. Products derived from this software may not be called "Apache",
   *    nor may "Apache" appear in their name, without prior written
   *    permission of the Apache Software Foundation.
   *
   * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
   * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
   * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
   * DISCLAIMED.  IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
   * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
   * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
   * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
   * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
   * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
   * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
   * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
   * SUCH DAMAGE.
   * ====================================================================
   *
   * This software consists of voluntary contributions made by many
   * individuals on behalf of the Apache Software Foundation and was
   * originally based on software copyright (c) 1999-2001, The dbXML
   * Group, L.L.C., http://www.dbxmlgroup.com.  For more
   * information on the Apache Software Foundation, please see
   * <http://www.apache.org/>.
   *
   * $Id: Query.java,v 1.1 2001/12/06 21:00:14 bradford Exp $
   */
  
  import org.apache.xindice.core.*;
  import org.apache.xindice.core.data.*;
  import org.apache.xindice.xml.*;
  
  import org.w3c.dom.*;
  
  /**
   * Query represents a compiled (parsed and primed) query.
   */
  
  public interface Query {
     /**
      * getQueryStyle returns the QueryStyle (ex: XPath) for this Query
      * instance.
      *
      * @return The Query style
      */
     String getQueryStyle();
  
     /**
      * getQueryContext returns the Collection context for this query.
      *
      * @return The Collection context
      */
     Collection getQueryContext();
  
     /**
      * getQueryString returns the String that was used to create the
      * Query instance.
      *
      * @return The Query String
      */
     String getQueryString();
  
     /**
      * getNamespaceMap returns the Map for prefixed namespace
      * resolution in relation to this Query.
      *
      * @return The namespace Map (if any)
      */
     NamespaceMap getNamespaceMap();
  
     /**
      * getKeySet returns the initial set of Keys for this Query.
      *
      * @return The initial Key set (if any)
      */
     Key[] getKeySet();
     
     /**
      * execute actually Executes the query and returns the resulting
      * NodeSet.
      *
      * @return The NodeSet
      */
     NodeSet execute() throws QueryException;
     
  
  }
  
  
  
  1.1                  xml-xindice/Xindice/java/src/org/apache/xindice/core/query/QueryEngine.java
  
  Index: QueryEngine.java
  ===================================================================
  package org.apache.xindice.core.query;
  
  /*
   * The Apache Software License, Version 1.1
   *
   *
   * Copyright (c) 1999 The Apache Software Foundation.  All rights
   * reserved.
   *
   * Redistribution and use in source and binary forms, with or without
   * modification, are permitted provided that the following conditions
   * are met:
   *
   * 1. Redistributions of source code must retain the above copyright
   *    notice, this list of conditions and the following disclaimer.
   *
   * 2. Redistributions in binary form must reproduce the above copyright
   *    notice, this list of conditions and the following disclaimer in
   *    the documentation and/or other materials provided with the
   *    distribution.
   *
   * 3. The end-user documentation included with the redistribution,
   *    if any, must include the following acknowledgment:
   *       "This product includes software developed by the
   *        Apache Software Foundation (http://www.apache.org/)."
   *    Alternately, this acknowledgment may appear in the software itself,
   *    if and wherever such third-party acknowledgments normally appear.
   *
   * 4. The names "Xindice" and "Apache Software Foundation" must
   *    not be used to endorse or promote products derived from this
   *    software without prior written permission. For written
   *    permission, please contact apache@apache.org.
   *
   * 5. Products derived from this software may not be called "Apache",
   *    nor may "Apache" appear in their name, without prior written
   *    permission of the Apache Software Foundation.
   *
   * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
   * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
   * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
   * DISCLAIMED.  IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
   * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
   * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
   * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
   * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
   * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
   * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
   * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
   * SUCH DAMAGE.
   * ====================================================================
   *
   * This software consists of voluntary contributions made by many
   * individuals on behalf of the Apache Software Foundation and was
   * originally based on software copyright (c) 1999-2001, The dbXML
   * Group, L.L.C., http://www.dbxmlgroup.com.  For more
   * information on the Apache Software Foundation, please see
   * <http://www.apache.org/>.
   *
   * $Id: QueryEngine.java,v 1.1 2001/12/06 21:00:14 bradford Exp $
   */
  
  import org.apache.xindice.core.*;
  import org.apache.xindice.core.Collection;
  import org.apache.xindice.core.data.*;
  import org.apache.xindice.core.indexer.*;
  import org.apache.xindice.xml.*;
  import org.apache.xindice.util.*;
  
  import org.w3c.dom.*;
  import java.util.*;
  
  /**
   * QueryEngine is the Xindice Query Engine.  Its purpose is to orchestrate
   * query operations against the Xindice repository.  The QueryEngine
   * basically just manages a set of QueryResolvers that actually perform
   * the work.
   */
  
  public class QueryEngine extends SimpleConfigurable {
     private static final String[] EmptyStrings = new String[0];
     private static final Key[] EmptyKeys = new Key[0];
  
     private static final String RESOLVER = "resolver";
     private static final String CLASS = "class";
  
     private Database db;
     private Map resolvers = new HashMap();
  
     public QueryEngine(Database db) {
        this.db = db;
     }
  
     public void setConfig(Configuration config) throws XindiceException {
        super.setConfig(config);
        config.processChildren(RESOLVER,
           new ConfigurationCallback() {
              public void process(Configuration cfg) {
                 String className = cfg.getAttribute(CLASS);
                 try {
                    QueryResolver res = (QueryResolver)Class.forName(className).newInstance();
                    res.setConfig(cfg);
                    res.setQueryEngine(QueryEngine.this);
                    resolvers.put(res.getQueryStyle(), res);
                 }
                 catch ( Exception e ) {
                    org.apache.xindice.Debug.printStackTrace(e);
                 }
              }
        });
     }
  
     public Database getDatabase() {
        return db;
     }
  
     /**
      * listStyles returns a list of styles supported by the
      * QueryEngine (ex: XPath, XUpdate)
      *
      * @return The supported styles
      */
     public String[] listStyles() {
        return (String[])resolvers.keySet().toArray(EmptyStrings);
     }
  
     private QueryResolver getResolver(String style) throws QueryException {
        QueryResolver res = (QueryResolver)resolvers.get(style);
        if ( res == null )
           throw new StyleNotFoundException("No Resolver available for '"+style+"' queries");
        return res;
     }
     
     /**
      * query performs the specified query and returns a NodeSet with
      * any possible results from that query.  The query is performed
      * in the context of a Collection.
      *
      * @param col The Collection context
      * @param style The query style (XPath, Fulltext, etc...)
      * @param query The Query
      * @param nsMap The namespace Map (if any)
      * @param keys The initial Key set to use (if any)
      * @return A NodeSet with the query results
      */
     public NodeSet query(Collection col, String style, String query, NamespaceMap nsMap, Key[] keys) throws DBException, QueryException {
        QueryResolver res = getResolver(style);
        return res.query(col, query, nsMap, keys);
     }
  
     /**
      * compileQuery compiles a Query against the specified Collection
      * context and returns the compiled Query.  This DOES NOT actually
      * run the query, merely just parses it and primes any possible
      * Indexers that the query might need.
      *
      * @param col The Collection context
      * @param style The query style (XPath, Fulltext, etc...)
      * @param query The Query
      * @param nsMap The namespace Map (if any)
      * @param keys The initial Key set to use (if any)
      * @return The compiled Query
      */
     public Query compileQuery(Collection col, String style, String query, NamespaceMap nsMap, Key[] keys) throws DBException, QueryException {
        QueryResolver res = getResolver(style);
        return res.compileQuery(col, query, nsMap, keys);
     }
     
  
     // Utility methods
  
     /**
      * getUniqueKeys takes a set of IndexMatch objects and extracts
      * all of its unique Keys in sorted order.
      *
      * @param matches The Match Set
      * @return The unique Keys in order
      */
     public static Key[] getUniqueKeys(IndexMatch[] matches) {
        SortedSet set = new TreeSet();
        for ( int i = 0; i < matches.length; i++ )
           set.add(matches[i].getKey());
        return (Key[])set.toArray(EmptyKeys);
     }
  
     /**
      * andKeySets takes several sets of unique Keys and returns the
      * ANDed set (elements that exist in all sets).  The first dimension
      * of the array holds the individual sets, the second holds the
      * actual Keys.
      *
      * @param keySets 2-dimensional set of Keys
      * @return The ANDed set of Keys in order
      */
     public static Key[] andKeySets(Key[][] keySets) {
        int[] ptrs;
        
        if ( keySets.length == 0 )
           return EmptyKeys;
        else if ( keySets.length == 1 )
           return keySets[0];
        else {
           ptrs = new int[keySets.length];
           for ( int i = 0; i < keySets.length; i++ )
              if ( keySets[i].length == 0 )
                 return EmptyKeys;
              else
                 ptrs[i] = 0;
        }
  
        SortedSet set = new TreeSet();
        boolean done = false;
        List highs = new ArrayList();
        Key highest = null;
        while ( !done ) {
           boolean eq = true;
  
           for ( int i = 0; i < ptrs.length; i++ ) {
              Key comp = keySets[i][ptrs[i]];
              if ( highest == null ) {
                 highest = comp;
                 highs.add(new Integer(i));
              }
              else {
                 int c = highest.compareTo(comp);
                 if ( c != 0 )
                    eq = false;
                 if ( c < 0 ) {
                    highest = comp;
                    highs.clear();
                    highs.add(new Integer(i));
                 }
                 else if ( c == 0 )
                    highs.add(new Integer(i));
              }
           }
           if ( eq ) {
              set.add(highest);
              highs.clear();
              highest = null;
           }
           for ( int i = 0; i < ptrs.length; i++ ) {
              if ( !highs.contains(new Integer(i)) )
                 ptrs[i]++;
              if ( ptrs[i] >= keySets[i].length )
                 done = true;
           }
           if ( !eq )
              highs.clear();
        }
  
        return (Key[])set.toArray(EmptyKeys);
     }
  
     /**
      * orKeySets takes several sets of unique Keys and returns the
      * ORed set (all unique elements).  The first dimension of the
      * array holds the individual sets, the second holds the actual
      * Keys.
      *
      * @param keySets 2-dimensional set of Keys
      * @return The ORed set of Keys in order
      */
     public static Key[] orKeySets(Key[][] keySets) {
        if ( keySets.length == 0 )
           return EmptyKeys;
        else if ( keySets.length == 1 )
           return keySets[0];
        else if ( keySets.length == 2 ) {
           // Optimization since most ORs will be 2 sets only
           if ( keySets[1].length == 0 )
              return keySets[0];
           else if ( keySets[0].length == 0 )
              return keySets[1];
        }
        
        SortedSet set = new TreeSet();
  
        for ( int i = 0; i < keySets.length; i++ )
           for ( int j = 0; j < keySets[i].length; j++ )
              set.add(keySets[i][j]);
  
        return (Key[])set.toArray(EmptyKeys);
     }
     
     /**
      * normalizeString normalizes the specific String by stripping
      * all leading, trailing, and continuous runs of white space.
      *
      * @param value The value to normalize
      * @return The result
      */
     public static String normalizeString(String value) {
        char[] c = value.toCharArray();
        char[] n = new char[c.length];
        boolean white = true;
        int pos = 0;
        for ( int i = 0; i < c.length; i++ ) {
           if ( " \t\n\r".indexOf(c[i]) != -1 ) {
              if ( !white ) {
                 n[pos++] = ' ';
                 white = true;
              }
           }
           else {
              n[pos++] = c[i];
              white = false;
           }
        }
        if ( white && pos > 0 )
           pos--;
        return new String(n, 0, pos);
     }
  
     /**
      * expandEntities expands the String's pre-defined XML entities
      * (&lt;, &gt;, etc...) into their actual character representations.
      *
      * @param value The value to expand entities for
      * @return The expanded String
      */
     public static String expandEntities(String value) {
        int idx = value.indexOf('&');
        if ( idx == -1 )
           return value;
  
        StringBuffer sb = new StringBuffer(value.length());
        int pos = 0;
        while ( pos < value.length() ) {
           if ( idx != -1 ) {
              if ( idx > pos )
                 sb.append(value.substring(pos, idx));
  
              int end = value.indexOf(';', idx)+1;
              if ( end == 0 )
                 // Some sort of error
                 return value;
  
              String token = value.substring(idx+1, end-1);
              if ( token.equals("apos") )
                 sb.append("'");
              else if ( token.equals("quot") )
                 sb.append("\"");
              else if ( token.equals("amp") )
                 sb.append("&");
              else if ( token.equals("lt") )
                 sb.append("<");
              else if ( token.equals("gt") )
                 sb.append(">");
              else
                 // Some sort of error
                 return value;
  
              pos = end;
              idx = value.indexOf('&', pos);
           }
           else {
              sb.append(value.substring(pos));
              break;
           }
        }
        return sb.toString();
     }
  
  }
  
  
  
  
  1.1                  xml-xindice/Xindice/java/src/org/apache/xindice/core/query/QueryException.java
  
  Index: QueryException.java
  ===================================================================
  package org.apache.xindice.core.query;
  
  /*
   * The Apache Software License, Version 1.1
   *
   *
   * Copyright (c) 1999 The Apache Software Foundation.  All rights
   * reserved.
   *
   * Redistribution and use in source and binary forms, with or without
   * modification, are permitted provided that the following conditions
   * are met:
   *
   * 1. Redistributions of source code must retain the above copyright
   *    notice, this list of conditions and the following disclaimer.
   *
   * 2. Redistributions in binary form must reproduce the above copyright
   *    notice, this list of conditions and the following disclaimer in
   *    the documentation and/or other materials provided with the
   *    distribution.
   *
   * 3. The end-user documentation included with the redistribution,
   *    if any, must include the following acknowledgment:
   *       "This product includes software developed by the
   *        Apache Software Foundation (http://www.apache.org/)."
   *    Alternately, this acknowledgment may appear in the software itself,
   *    if and wherever such third-party acknowledgments normally appear.
   *
   * 4. The names "Xindice" and "Apache Software Foundation" must
   *    not be used to endorse or promote products derived from this
   *    software without prior written permission. For written
   *    permission, please contact apache@apache.org.
   *
   * 5. Products derived from this software may not be called "Apache",
   *    nor may "Apache" appear in their name, without prior written
   *    permission of the Apache Software Foundation.
   *
   * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
   * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
   * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
   * DISCLAIMED.  IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
   * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
   * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
   * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
   * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
   * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
   * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
   * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
   * SUCH DAMAGE.
   * ====================================================================
   *
   * This software consists of voluntary contributions made by many
   * individuals on behalf of the Apache Software Foundation and was
   * originally based on software copyright (c) 1999-2001, The dbXML
   * Group, L.L.C., http://www.dbxmlgroup.com.  For more
   * information on the Apache Software Foundation, please see
   * <http://www.apache.org/>.
   *
   * $Id: QueryException.java,v 1.1 2001/12/06 21:00:14 bradford Exp $
   */
  
  import org.apache.xindice.core.*;
  
  /**
   * A QueryException is thrown by a Query if an exception occurs
   * in the processing of the Query.
   */
  
  public class QueryException extends DBException {
     public QueryException(int faultCode) {
        super(faultCode);
     }
     
     public QueryException(int faultCode, String message) {
        super(faultCode, message);
     }
  }
  
  
  
  1.1                  xml-xindice/Xindice/java/src/org/apache/xindice/core/query/QueryResolver.java
  
  Index: QueryResolver.java
  ===================================================================
  package org.apache.xindice.core.query;
  
  /*
   * The Apache Software License, Version 1.1
   *
   *
   * Copyright (c) 1999 The Apache Software Foundation.  All rights
   * reserved.
   *
   * Redistribution and use in source and binary forms, with or without
   * modification, are permitted provided that the following conditions
   * are met:
   *
   * 1. Redistributions of source code must retain the above copyright
   *    notice, this list of conditions and the following disclaimer.
   *
   * 2. Redistributions in binary form must reproduce the above copyright
   *    notice, this list of conditions and the following disclaimer in
   *    the documentation and/or other materials provided with the
   *    distribution.
   *
   * 3. The end-user documentation included with the redistribution,
   *    if any, must include the following acknowledgment:
   *       "This product includes software developed by the
   *        Apache Software Foundation (http://www.apache.org/)."
   *    Alternately, this acknowledgment may appear in the software itself,
   *    if and wherever such third-party acknowledgments normally appear.
   *
   * 4. The names "Xindice" and "Apache Software Foundation" must
   *    not be used to endorse or promote products derived from this
   *    software without prior written permission. For written
   *    permission, please contact apache@apache.org.
   *
   * 5. Products derived from this software may not be called "Apache",
   *    nor may "Apache" appear in their name, without prior written
   *    permission of the Apache Software Foundation.
   *
   * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
   * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
   * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
   * DISCLAIMED.  IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
   * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
   * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
   * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
   * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
   * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
   * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
   * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
   * SUCH DAMAGE.
   * ====================================================================
   *
   * This software consists of voluntary contributions made by many
   * individuals on behalf of the Apache Software Foundation and was
   * originally based on software copyright (c) 1999-2001, The dbXML
   * Group, L.L.C., http://www.dbxmlgroup.com.  For more
   * information on the Apache Software Foundation, please see
   * <http://www.apache.org/>.
   *
   * $Id: QueryResolver.java,v 1.1 2001/12/06 21:00:14 bradford Exp $
   */
  
  import org.apache.xindice.core.*;
  import org.apache.xindice.core.data.*;
  import org.apache.xindice.xml.*;
  import org.apache.xindice.util.*;
  
  import org.w3c.dom.*;
  
  /**
   * QueryResolver is an interface that has to be implemented to actually
   * perfrom query resolution.  Xindice provides an XPathQueryResolver to
   * handle XPath queries against sets of Documents in a Collection.
   */
  
  public interface QueryResolver extends Configurable {
     /**
      * setQueryEngine hands a reference for the QueryEngine to the
      * Resolver.
      *
      * @param engine The QueryEngine
      */
     void setQueryEngine(QueryEngine engine);
  
     /**
      * getQueryStyle returns the Query style supported by this Resolver.
      *
      * @return The query style
      */
     String getQueryStyle();
  
     /**
      * compileQuery compiles a Query against the specified Collection
      * context and returns the compiled Query.  This DOES NOT actually
      * run the query, merely just parses it and primes any possible
      * Indexers that the query might need.
      *
      * @param context The Collection Context
      * @param query The Query
      * @param nsMap The namespace Map (if any)
      * @param keys The initial Key set to use (if any)
      * @return The compiled Query
      */
     Query compileQuery(Collection context, String query, NamespaceMap nsMap, Key[] keys) throws QueryException;
  
     /**
      * query compiles a Query against the specified Collection context
      * and returns the query results.
      *
      * @param context The Collection Context
      * @param query The Query
      * @param nsMap The namespace Map (if any)
      * @param keys The initial Key set to use (if any)
      * @return The resulting NodeSet
      */
     NodeSet query(Collection context, String query, NamespaceMap nsMap, Key[] keys) throws QueryException;
     
  }
  
  
  
  1.1                  xml-xindice/Xindice/java/src/org/apache/xindice/core/query/StyleNotFoundException.java
  
  Index: StyleNotFoundException.java
  ===================================================================
  package org.apache.xindice.core.query;
  
  /*
   * The Apache Software License, Version 1.1
   *
   *
   * Copyright (c) 1999 The Apache Software Foundation.  All rights
   * reserved.
   *
   * Redistribution and use in source and binary forms, with or without
   * modification, are permitted provided that the following conditions
   * are met:
   *
   * 1. Redistributions of source code must retain the above copyright
   *    notice, this list of conditions and the following disclaimer.
   *
   * 2. Redistributions in binary form must reproduce the above copyright
   *    notice, this list of conditions and the following disclaimer in
   *    the documentation and/or other materials provided with the
   *    distribution.
   *
   * 3. The end-user documentation included with the redistribution,
   *    if any, must include the following acknowledgment:
   *       "This product includes software developed by the
   *        Apache Software Foundation (http://www.apache.org/)."
   *    Alternately, this acknowledgment may appear in the software itself,
   *    if and wherever such third-party acknowledgments normally appear.
   *
   * 4. The names "Xindice" and "Apache Software Foundation" must
   *    not be used to endorse or promote products derived from this
   *    software without prior written permission. For written
   *    permission, please contact apache@apache.org.
   *
   * 5. Products derived from this software may not be called "Apache",
   *    nor may "Apache" appear in their name, without prior written
   *    permission of the Apache Software Foundation.
   *
   * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
   * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
   * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
   * DISCLAIMED.  IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
   * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
   * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
   * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
   * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
   * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
   * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
   * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
   * SUCH DAMAGE.
   * ====================================================================
   *
   * This software consists of voluntary contributions made by many
   * individuals on behalf of the Apache Software Foundation and was
   * originally based on software copyright (c) 1999-2001, The dbXML
   * Group, L.L.C., http://www.dbxmlgroup.com.  For more
   * information on the Apache Software Foundation, please see
   * <http://www.apache.org/>.
   *
   * $Id: StyleNotFoundException.java,v 1.1 2001/12/06 21:00:14 bradford Exp $
   */
  
  import org.apache.xindice.core.*;
  
  /**
   * A StyleNotFoundException is thrown by a Query if the QueryEngine
   * can't resolve a specified style name.
   */
  
  public final class StyleNotFoundException extends QueryException {
     public StyleNotFoundException() {
        super(FaultCodes.QRY_STYLE_NOT_FOUND);
     }
     
     public StyleNotFoundException(String message) {
        super(FaultCodes.QRY_STYLE_NOT_FOUND, message);
     }
  }
  
  
  
  1.1                  xml-xindice/Xindice/java/src/org/apache/xindice/core/query/XPathQueryResolver.java
  
  Index: XPathQueryResolver.java
  ===================================================================
  package org.apache.xindice.core.query;
  
  /*
   * The Apache Software License, Version 1.1
   *
   *
   * Copyright (c) 1999 The Apache Software Foundation.  All rights
   * reserved.
   *
   * Redistribution and use in source and binary forms, with or without
   * modification, are permitted provided that the following conditions
   * are met:
   *
   * 1. Redistributions of source code must retain the above copyright
   *    notice, this list of conditions and the following disclaimer.
   *
   * 2. Redistributions in binary form must reproduce the above copyright
   *    notice, this list of conditions and the following disclaimer in
   *    the documentation and/or other materials provided with the
   *    distribution.
   *
   * 3. The end-user documentation included with the redistribution,
   *    if any, must include the following acknowledgment:
   *       "This product includes software developed by the
   *        Apache Software Foundation (http://www.apache.org/)."
   *    Alternately, this acknowledgment may appear in the software itself,
   *    if and wherever such third-party acknowledgments normally appear.
   *
   * 4. The names "Xindice" and "Apache Software Foundation" must
   *    not be used to endorse or promote products derived from this
   *    software without prior written permission. For written
   *    permission, please contact apache@apache.org.
   *
   * 5. Products derived from this software may not be called "Apache",
   *    nor may "Apache" appear in their name, without prior written
   *    permission of the Apache Software Foundation.
   *
   * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
   * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
   * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
   * DISCLAIMED.  IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
   * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
   * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
   * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
   * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
   * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
   * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
   * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
   * SUCH DAMAGE.
   * ====================================================================
   *
   * This software consists of voluntary contributions made by many
   * individuals on behalf of the Apache Software Foundation and was
   * originally based on software copyright (c) 1999-2001, The dbXML
   * Group, L.L.C., http://www.dbxmlgroup.com.  For more
   * information on the Apache Software Foundation, please see
   * <http://www.apache.org/>.
   *
   * $Id: XPathQueryResolver.java,v 1.1 2001/12/06 21:00:14 bradford Exp $
   */
  
  import org.apache.xindice.core.*;
  import org.apache.xindice.core.Collection;
  import org.apache.xindice.core.data.*;
  import org.apache.xindice.core.data.NodeSet;
  import org.apache.xindice.core.indexer.*;
  import org.apache.xindice.core.indexer.helpers.*;
  import org.apache.xindice.util.*;
  import org.apache.xindice.xml.*;
  import org.apache.xindice.xml.dom.*;
  
  import org.w3c.dom.*;
  
  import java.util.*;
  
  import javax.xml.transform.*;
  
  import org.apache.xpath.*;
  import org.apache.xpath.compiler.*;
  import org.apache.xpath.compiler.Compiler;
  import org.apache.xml.utils.*;
  import org.apache.xpath.objects.*;
  
  /**
   * XPathQueryResolver
   */
  
  public final class XPathQueryResolver extends SimpleConfigurable implements QueryResolver {
     private static final Key[] EmptyKeys = new Key[0];
     private static final Key[][] EmptyKeySet = new Key[0][0];
     private static final String WILDCARD = "*";
     private static final String THISNODE = ".";
     private static final String PARENTNODE = "..";
  
     private static final String AUTOINDEX = "autoindex";
  
     public static final String STYLE_XPATH = "XPath";
  
     // Maps Xalan Comparisons To IndexQuery
     private static final int[] OpMap = { IndexQuery.NEQ,
                                          IndexQuery.EQ,
                                          IndexQuery.LEQ,
                                          IndexQuery.LT,
                                          IndexQuery.GEQ,
                                          IndexQuery.GT };
  
     // Maps XPath Functions To Internal IDs (These are Xalan IDs)
     public static final int FUNC_NOT = 11;
     public static final int FUNC_TRUE = 12;
     public static final int FUNC_FALSE = 13;
     public static final int FUNC_BOOLEAN = 14;
     public static final int FUNC_NUMBER = 15;
     public static final int FUNC_FLOOR = 16;
     public static final int FUNC_CEILING = 17;
     public static final int FUNC_ROUND = 18;
     public static final int FUNC_STRING = 20;
     public static final int FUNC_STARTS_WITH = 21;
     public static final int FUNC_CONTAINS = 22;
     public static final int FUNC_SUBSTRING_BEFORE = 23;
     public static final int FUNC_SUBSTRING_AFTER = 24;
     public static final int FUNC_NORMALIZE_SPACE = 25;
     public static final int FUNC_TRANSLATE = 26;
     public static final int FUNC_CONCAT = 27;
     public static final int FUNC_SUBSTRING = 29;
     public static final int FUNC_STRING_LENGTH = 30;
  
     private QueryEngine engine;
     private DefaultErrorHandler errorListener = new DefaultErrorHandler();
     private boolean autoIndex = false;
  
     public void setConfig(Configuration config) throws XindiceException {
        super.setConfig(config);
        autoIndex = config.getBooleanAttribute(AUTOINDEX, autoIndex);
     }
  
     public String getQueryStyle() {
        return STYLE_XPATH;
     }
  
     public void setQueryEngine(QueryEngine engine) {
        this.engine = engine;
     }
  
     public Query compileQuery(Collection context, String query, NamespaceMap nsMap, Key[] keys) throws QueryException {
        return new XPathQuery(context, query, nsMap, keys);
     }
     
     public NodeSet query(Collection context, String query, NamespaceMap nsMap, Key[] keys) throws QueryException {
        XPathQuery xq = new XPathQuery(context, query, nsMap, keys);
        return xq.execute();
     }
     
  
     /**
      * XPathQuery
      */
  
     private class XPathQuery implements Query {
        public Collection context;
        public IndexManager idxMgr;
        public NamespaceMap nsMap;
        public PrefixResolver pr;
        public SymbolTable symbols;
        public String query;
        public Compiler cmp;
        public XPath xp;
        public Key[] keys;
  
        public XPathQuery(Collection context, String query, NamespaceMap nsMap, Key[] keys) throws QueryException {
           this.context = context;
           this.query = query;
           this.nsMap = nsMap;
           this.keys = keys;
  
           Expression ex = null;
           
           try {
              if ( nsMap != null ) {
                 Node n = nsMap.getContextNode();
                 pr = new PrefixResolverDefault(n);
              }
           
              XPathParser parser = new XPathParser(errorListener, null);
              cmp = new Compiler(errorListener, null);
              parser.initXPath(cmp, query, pr);
              ex = cmp.compile(0);
              
              symbols = context.getSymbols();
              idxMgr = context.getIndexManager();
           }
           catch ( Exception e ) {
              throw new CompilationException("Error Compiling XPath Expression");
           }
           if ( ex == null )
              throw new CompilationException("Error Compiling XPath Expression");
        }
        
        public String getQueryStyle() {
           return STYLE_XPATH;
        }
  
        public String getQueryString() {
           return query;
        }
  
        public Collection getQueryContext() {
           return context;
        }
        
        public NamespaceMap getNamespaceMap() {
           return nsMap;
        }
        
        public Key[] getKeySet() {
           return keys;
        }
  
        public NodeSet execute() throws QueryException {
           try {
              Key[] keySet = keys;
  
              // TODO: Add logic to do an indexed check on provided
              //       keySets that are larger than a certain minimum
  
              if ( keys == null && idxMgr != null ) {
                 // Issue the query using Indexes
                 try {
                    Object obj = evaluate(null, 0);
                    if ( obj instanceof NamedKeys )
                       keySet = ((NamedKeys)obj).keys;
                 }
                 catch ( Exception e ) {
                    org.apache.xindice.Debug.printStackTrace(e);
                 }
              }
              
              if ( keySet == null ) {
                 // Fall back to a Collection scan
                 SortedSet set = new TreeSet();
                 RecordSet rs = context.getFiler().getRecordSet();
                 while ( rs.hasMoreRecords() )
                    set.add(rs.getNextKey());
                 keySet = (Key[])set.toArray(EmptyKeys);
              }
  
              return new ResultSet(context, pr, keySet, query);
           }
           catch ( Exception e ) {
              throw new ProcessingException("Error executing XPath query");
           }
        }
  
        private Key[] andKeys(List list) {
           if ( !list.isEmpty() ) {
              if ( list.size() > 1 ) {
                 Key[][] keys = (Key[][])list.toArray(EmptyKeySet);
                 return QueryEngine.andKeySets(keys);
              }
              else
                 return (Key[])list.get(0);
           }
           else
              return null;
        }
  
  
        // Evaluation Methods
  
        /**
         * evaluate does a partial evaluation of the XPath in
         * order to determine the optimal indexes to prepare for
         * the query and retrieve the Document subset that will be
         * used for the actual XPath query.
         * <br><br>
         * This will return an instance of one of the following classes:
         * <pre>
         *    String    If the sub-expression resolves to a Node Name
         *    XNumber   If the sub-expression resolves to a Number
         *    XString   If the sub-expression resolves to a String
         *    XBoolean  If the sub-expression resolves to a Boolean
         *    NamedKeys If the sub-expression resolves to a Key set
         * </pre>
         *
         * @param owner The parent node name for this context
         * @param pos The position to start at (recursively called)
         * @return Some Object result
         */
        private Object evaluate(String owner, int pos) throws Exception {
           int op = cmp.getOp(pos);
           if ( op == -1 )
              return null;
  
           switch ( op ) {
  
              case OpCodes.OP_LOCATIONPATH:
                 return evalLocationPath(op, owner, pos);
  
              case OpCodes.OP_ARGUMENT:
              case OpCodes.OP_XPATH:
              case OpCodes.OP_PREDICATE:
                 return evaluate(owner, cmp.getFirstChildPos(pos));
  
              case OpCodes.OP_OR:
              case OpCodes.OP_AND:
                 return evalSetComparison(op, owner, pos);
  
              case OpCodes.OP_NOTEQUALS:
              case OpCodes.OP_EQUALS:
              case OpCodes.OP_LTE:
              case OpCodes.OP_LT:
              case OpCodes.OP_GTE:
              case OpCodes.OP_GT:
                 return evalValComparison(op, owner, pos);
  
              case OpCodes.OP_PLUS:
              case OpCodes.OP_MINUS:
              case OpCodes.OP_MULT:
              case OpCodes.OP_DIV:
              case OpCodes.OP_MOD:
              case OpCodes.OP_QUO:
                 return evalMathOperation(op, owner, pos);
  
              case OpCodes.OP_NEG:
              case OpCodes.OP_STRING:
              case OpCodes.OP_BOOL:
              case OpCodes.OP_NUMBER:
                 return evalUnaryOperation(op, owner, pos);
  
              case OpCodes.OP_UNION:
                 break;
  
              case OpCodes.OP_VARIABLE:
                 break;
  
              case OpCodes.OP_GROUP:
                 return evaluate(owner, cmp.getFirstChildPos(pos));
  
              case OpCodes.OP_EXTFUNCTION:
                 break;
  
              case OpCodes.OP_FUNCTION:
                 return evalFunction(op, owner, pos);
  
              case OpCodes.FROM_ANCESTORS:
              case OpCodes.FROM_ANCESTORS_OR_SELF:
              case OpCodes.FROM_ATTRIBUTES:
              case OpCodes.FROM_CHILDREN:
              case OpCodes.FROM_DESCENDANTS:
              case OpCodes.FROM_DESCENDANTS_OR_SELF:
              case OpCodes.FROM_FOLLOWING:
              case OpCodes.FROM_FOLLOWING_SIBLINGS:
              case OpCodes.FROM_PARENT:
              case OpCodes.FROM_PRECEDING:
              case OpCodes.FROM_PRECEDING_SIBLINGS:
              case OpCodes.FROM_NAMESPACE:
              case OpCodes.FROM_SELF:
              case OpCodes.FROM_ROOT:
                 return evalAxis(op, owner, pos);
  
              case OpCodes.NODENAME:
              case OpCodes.OP_LITERAL:
              case OpCodes.OP_NUMBERLIT:
                 return evalLiteral(op, owner, pos);
  
              case OpCodes.NODETYPE_TEXT:
              case OpCodes.NODETYPE_NODE:
                 return owner;
  
              case OpCodes.NODETYPE_ANYELEMENT:
              case OpCodes.ELEMWILDCARD:
                 return WILDCARD;
  
              case OpCodes.NODETYPE_ROOT:
              case OpCodes.NODETYPE_COMMENT:
              case OpCodes.NODETYPE_PI:
              case OpCodes.NODETYPE_FUNCTEST:
                 break;
  
              default:
                 org.apache.xindice.Debug.println("Unknown: "+op);
  
           }
           return null;
        }
  
        private Object evalLocationPath(int op, String owner, int pos) throws Exception {
           int lp = cmp.getFirstChildPos(pos);
           List ks = new ArrayList();
           String name = null;
           boolean attr = false;
           while ( cmp.getOp(lp) != -1 ) {
              Object obj = evaluate(owner, lp);
              if ( obj instanceof NamedKeys ) {
                 NamedKeys nk = (NamedKeys)obj;
                 if ( nk.name != null ) {
                    attr = nk.attribute;
                    if ( attr && name != null ) {
                       StringBuffer sb = new StringBuffer(32);
                       sb.append(name);
                       sb.append('@');
                       sb.append(nk.name);
                       name = sb.toString();
                    }
                    else
                       name = nk.name;
                 }
                 if ( nk.keys != null )
                    ks.add(nk.keys);
                 else if ( name != null ) {
                    // Try to use a NameIndex to resolve the path component
                    IndexPattern pattern = new IndexPattern(symbols, name, nsMap);
                    Indexer idx = context.getIndexManager().getBestIndexer(Indexer.STYLE_NODENAME, pattern);
                    if ( idx != null ) {
                       IndexMatch[] matches = idx.queryMatches(new IndexQueryANY(pattern));
                       Key[] keys = QueryEngine.getUniqueKeys(matches);
                       ks.add(keys);
                    }
                 }
              }
              lp = cmp.getNextOpPos(lp);
           }
           return new NamedKeys(name, attr, andKeys(ks));
        }
  
        private Object evalSetComparison(int op, String owner, int pos) throws Exception {
           int l = cmp.getFirstChildPos(pos);
           int r = cmp.getNextOpPos(l);
           Object left = evaluate(owner, l);
           Object right = evaluate(owner, r);
  
           NamedKeys nkl = left instanceof NamedKeys ? (NamedKeys)left : null;
           NamedKeys nkr = right instanceof NamedKeys ? (NamedKeys)right : null;
           if ( nkl != null && nkr != null && nkl.keys != null && nkr.keys != null ) {
              Key[][] keys = new Key[][] { nkl.keys, nkr.keys };
              if ( op == OpCodes.OP_OR )
                 return new NamedKeys(null, false, QueryEngine.orKeySets(keys));
              else
                 return new NamedKeys(null, false, QueryEngine.andKeySets(keys));
           }
           else if ( op == OpCodes.OP_AND ) {
              if ( nkl != null && nkl.keys != null )
                 return new NamedKeys(null, false, nkl.keys);
              else if ( nkr != null && nkr.keys != null )
                 return new NamedKeys(null, false, nkr.keys);
           }
           return null;
        }
  
        private Object evalValComparison(int op, String owner, int pos) throws Exception {
           int l = cmp.getFirstChildPos(pos);
           int r = cmp.getNextOpPos(l);
           Object left = evaluate(owner, l);
           Object right = evaluate(owner, r);
  
           if ( ( left instanceof XObject ) && ( right instanceof XObject ) ) {
              switch ( op ) {
                 case OpCodes.OP_NOTEQUALS: return new XBoolean(((XObject)left).notEquals((XObject)right));
                 case OpCodes.OP_EQUALS:    return new XBoolean(((XObject)left).equals((XObject)right));
                 case OpCodes.OP_LTE:       return new XBoolean(((XObject)left).lessThanOrEqual((XObject)right));
                 case OpCodes.OP_LT:        return new XBoolean(((XObject)left).lessThan((XObject)right));
                 case OpCodes.OP_GTE:       return new XBoolean(((XObject)left).greaterThanOrEqual((XObject)right));
                 case OpCodes.OP_GT:        return new XBoolean(((XObject)left).greaterThan((XObject)right));
                 default:                   return null; // Won't happen
              }
           }
           else
              return queryComparison(op, owner, left, right);
        }
  
        private strictfp Object evalMathOperation(int op, String owner, int pos) throws Exception {
           int lc = cmp.getFirstChildPos(pos);
           int rc = cmp.getNextOpPos(lc);
           XObject left = (XObject)evaluate(owner, lc);
           XObject right = (XObject)evaluate(owner, rc);
  
           switch ( op ) {
              case OpCodes.OP_PLUS:  return new XNumber(left.num() + right.num());
              case OpCodes.OP_MINUS: return new XNumber(left.num() - right.num());
              case OpCodes.OP_MULT:  return new XNumber(left.num() * right.num());
              case OpCodes.OP_DIV:   return new XNumber(left.num() / right.num());
              case OpCodes.OP_MOD:   return new XNumber(left.num() % right.num());
              case OpCodes.OP_QUO:   return new XNumber(left.num() / right.num());
              default:               return null; // Won't happen
           }
        }
  
        private Object evalUnaryOperation(int op, String owner, int pos) throws Exception {
           XObject val = (XObject)evaluate(owner, cmp.getFirstChildPos(pos));
           switch ( op ) {
              case OpCodes.OP_NEG:    return new XNumber(-val.num());
              case OpCodes.OP_STRING: return new XString(val.str());
              case OpCodes.OP_BOOL:   return new XBoolean(val.bool());
              case OpCodes.OP_NUMBER: return new XNumber(val.num());
              default:                return null; // Won't happen
           }
        }
  
        private Object evalFunction(int op, String owner, int pos) throws Exception {
           int idx = cmp.getFirstChildPos(pos);
           int id = cmp.getOp(idx);
           int endFunc = pos + cmp.getOpMap()[pos+1] - 1;
  
           List args = new ArrayList();
           int lp = idx+1;
           while ( lp < endFunc ) {
              args.add(evaluate(owner, lp));
              lp = cmp.getNextOpPos(lp);
           }
  
           switch ( id ) {
              case FUNC_BOOLEAN:
                 return funcBoolean(owner, args);
              case FUNC_CEILING:
                 return funcCeiling(owner, args);
              case FUNC_CONCAT:
                 return funcConcat(owner, args);
              case FUNC_CONTAINS:
                 return funcContains(owner, args);
              case FUNC_FALSE:
                 return XBoolean.S_FALSE;
              case FUNC_FLOOR:
                 return funcFloor(owner, args);
              case FUNC_NORMALIZE_SPACE:
                 return funcNormalizeSpace(owner, args);
              case FUNC_NOT:
                 return funcNot(owner, args);
              case FUNC_NUMBER:
                 return funcNumber(owner, args);
              case FUNC_ROUND:
                 return funcRound(owner, args);
              case FUNC_STARTS_WITH:
                 return funcStartsWith(owner, args);
              case FUNC_STRING:
                 return funcString(owner, args);
              case FUNC_STRING_LENGTH:
                 return funcStringLength(owner, args);
              case FUNC_SUBSTRING:
                 return funcSubstring(owner, args);
              case FUNC_SUBSTRING_AFTER:
                 return funcSubstringAfter(owner, args);
              case FUNC_SUBSTRING_BEFORE:
                 return funcSubstringBefore(owner, args);
              case FUNC_TRANSLATE:
                 return funcTranslate(owner, args);
              case FUNC_TRUE:
                 return XBoolean.S_TRUE;
              default:
                 return null;
           }
        }
  
        private Object evalAxis(int op, String owner, int pos) throws Exception {
           String nsURI = cmp.getStepNS(pos);
           owner = (String)evaluate(owner, cmp.getFirstChildPosOfStep(pos));
           //owner = cmp.getStepLocalName(pos);
           
           if ( nsURI != null && nsMap != null ) {
              // We have to determine the prefix that was used
              // There has to be an easier way to do this with Xalan
              String pfx = null;
              Iterator i = nsMap.keySet().iterator();
              while ( i.hasNext() ) {
                 String p = (String)i.next();
                 if ( nsMap.getNamespaceURI(p).equals(nsURI) ) {
                    pfx = p;
                    break;
                 }
              }
              if ( pfx != null ) {
                 StringBuffer sb = new StringBuffer(32);
                 sb.append(pfx);
                 sb.append(':');
                 sb.append(owner);
                 owner = sb.toString();
              }
           }
           
           int rp = cmp.getFirstPredicateOpPos(pos);
  
           List ks = new ArrayList();
           while ( rp < pos+cmp.getOp(pos+1) ) {
              Object obj = evaluate(owner, rp);
              if ( obj instanceof NamedKeys ) {
                 NamedKeys nk = (NamedKeys)obj;
                 if ( nk.keys != null )
                    ks.add(nk.keys);
              }
              rp = cmp.getNextOpPos(rp);
           }
           return new NamedKeys(owner, (op == OpCodes.FROM_ATTRIBUTES), andKeys(ks));
        }
  
        private Object evalLiteral(int op, String owner, int pos) throws Exception {
           int idx = cmp.getOp(cmp.getFirstChildPos(pos));
           switch ( idx ) {
              case OpCodes.EMPTY:
                 return owner;
              case OpCodes.ELEMWILDCARD:
                 return WILDCARD;
              default:
                 return cmp.getToken(idx);
           }
        }
  
  
        // XPath Functions
  
        private Object funcBoolean(String owner, List args) throws Exception {
           if ( args.size() == 1 ) {
              Object o = args.get(0);
              if ( o instanceof XObject ) {
                 if ( ((XObject)o).bool() )
                    return XBoolean.S_TRUE;
                 else
                    return XBoolean.S_FALSE;
              }
              else
                 return o;
           }
           return null;
        }
  
        private Object funcCeiling(String owner, List args) throws Exception {
           if ( args.size() == 1 ) {
              Object o = args.get(0);
              if ( o instanceof XObject )
                 return new XNumber(Math.ceil(((XObject)o).num()));
           }
           return null;
        }
  
        private Object funcConcat(String owner, List args) {
           StringBuffer sb = new StringBuffer();
           for ( int i = 0; i < args.size(); i++ ) {
              Object o = args.get(i);
              if ( o instanceof XObject )
                 sb.append(((XObject)o).str());
           }
           return new XString(sb.toString());
        }
  
        private Object funcContains(String owner, List args) {
           if ( args.size() == 2 ) {
              Object o = args.get(0);
              Object s = args.get(1);
              if ( o instanceof XObject && s instanceof XObject ) {
                 if ( ((XObject)o).str().indexOf(((XObject)s).str()) != -1 )
                    return XBoolean.S_TRUE;
                 else
                    return XBoolean.S_FALSE;
              }
           }
           return null;
        }
  
        private Object funcFloor(String owner, List args) throws Exception {
           if ( args.size() == 1 ) {
              Object o = args.get(0);
              if ( o instanceof XObject )
                 return new XNumber(Math.floor(((XObject)o).num()));
           }
           return null;
        }
  
        private Object funcNormalizeSpace(String owner, List args) {
           if ( args.size() == 1 ) {
              Object o = args.get(0);
              if ( o instanceof XObject )
                 return new XString(QueryEngine.normalizeString(((XObject)o).str()));
              else
                 return o;
           }
           return null;
        }
  
        private Object funcNot(String owner, List args) throws Exception {
           if ( args.size() == 1 ) {
              Object o = args.get(0);
              if ( o instanceof XObject ) {
                 if ( ((XObject)o).bool() )
                    return XBoolean.S_FALSE;
                 else
                    return XBoolean.S_TRUE;
              }
           }
           return null;
        }
  
        private Object funcNumber(String owner, List args) throws Exception {
           if ( args.size() == 1 ) {
              Object o = args.get(0);
              if ( o instanceof XObject )
                 return new XNumber(((XObject)o).num());
              else
                 return o;
           }
           return null;
        }
  
        private Object funcRound(String owner, List args) throws Exception {
           if ( args.size() == 1 ) {
              Object o = args.get(0);
              if ( o instanceof XObject )
                 return new XNumber(Math.round(((XObject)o).num()));
           }
           return null;
        }
  
        private Object funcStartsWith(String owner, List args) {
           if ( args.size() == 2 ) {
              Object o = args.get(0);
              Object s = args.get(1);
  
              if ( o instanceof XObject && s instanceof XObject ) {
                 if ( ((XObject)o).str().startsWith(((XObject)s).str()) )
                    return XBoolean.S_TRUE;
                 else
                    return XBoolean.S_FALSE;
              }
              else if ( o instanceof NamedKeys && s instanceof XObject ) {
                 NamedKeys nk = (NamedKeys)o;
                 String ps;
                 if ( nk.attribute && nk.name.indexOf('@') == -1 )
                    ps = owner+"@"+nk.name;
                 else
                    ps = nk.name;
  
                 IndexPattern pattern = new IndexPattern(symbols, ps, nsMap);
  
                 XObject obj = (XObject)s;
                 Value val1 = new Value(obj.str());
  
                 IndexQuery iq = new IndexQuerySW(pattern, val1);
                 return queryIndexes(nk, iq, ps, obj.getType());
              }
           }
           return null;
        }
  
        private Object funcString(String owner, List args) {
           if ( args.size() == 1 ) {
              Object o = args.get(0);
              if ( o instanceof XObject )
                 return new XString(((XObject)o).str());
              else
                 return o;
           }
           return null;
        }
  
        private Object funcStringLength(String owner, List args) {
           if ( args.size() == 1 ) {
              Object o = args.get(0);
              if ( o instanceof XObject )
                 return new XNumber(((XObject)o).str().length());
           }
           return null;
        }
  
        private Object funcSubstring(String owner, List args) throws Exception {
           if ( args.size() == 2 || args.size() == 3 ) {
              Object o = args.get(0);
              Object pos = args.get(1);
              Object len = args.get(2);
              if ( o instanceof XObject && pos instanceof XObject && (len == null || len instanceof XObject ) ) {
                 int ipos = (int)((XObject)pos).num()-1;
                 if ( len != null ) {
                    int ilen = (int)((XObject)len).num();
                    return new XString(((XObject)o).str().substring(ipos, ipos+ilen));
                 }
                 else
                    return new XString(((XObject)o).str().substring(ipos));
              }
           }
           return null;
        }
  
        private Object funcSubstringAfter(String owner, List args) {
           if ( args.size() == 2 ) {
              Object o = args.get(0);
              Object s = args.get(1);
              if ( o instanceof XObject && s instanceof XObject ) {
                 String val = ((XObject)o).str();
                 String sub = ((XObject)s).str();
                 int i = val.indexOf(sub);
                 if ( i == -1 )
                    return new XString("");
                 else
                    return new XString(val.substring(i+sub.length()));
              }
           }
           return null;
        }
  
        private Object funcSubstringBefore(String owner, List args) {
           if ( args.size() == 2 ) {
              Object o = args.get(0);
              Object s = args.get(1);
              if ( o instanceof XObject && s instanceof XObject ) {
                 String val = ((XObject)o).str();
                 String sub = ((XObject)s).str();
                 int i = val.indexOf(sub);
                 if ( i == -1 )
                    return new XString("");
                 else
                    return new XString(val.substring(0, i));
              }
           }
           return null;
        }
  
        private Object funcTranslate(String owner, List args) {
           if ( args.size() == 3 ) {
              Object o = args.get(0);
              Object c1 = args.get(1);
              Object c2 = args.get(2);
              if ( o instanceof XObject && c1 instanceof XObject && c2 instanceof XObject) {
                 char ch1 = ((XObject)c1).str().charAt(0);
                 char ch2 = ((XObject)c2).str().charAt(0);
                 return new XString(((XObject)o).str().replace(ch1, ch2));
              }
           }
           return null;
        }
  
        
        // The Actual Querying Methods
  
        /**
         * queryIndexes actually performs index-based querying on behalf of
         * the evaluation methods.
         *
         * @param nk The NamedKeys instance to use for matches
         * @param iq The actual IndexQuery to use for resolution
         * @param ps The pattern String to possibly use for index gen
         * @param objType The object type to possibly use for index gen
         * @return The resulting Keys (if any)
         */
        private Object queryIndexes(NamedKeys nk, IndexQuery iq, String ps, int objType) {
           try {
              IndexPattern pattern = iq.getPattern();
  
              Indexer idx = context.getIndexManager().getBestIndexer(Indexer.STYLE_NODEVALUE, pattern);
              if ( idx != null )
                 return new NamedKeys(nk.name, nk.attribute, QueryEngine.getUniqueKeys(idx.queryMatches(iq)));
              else if ( autoIndex ) {
                 // TODO: This has to *not* be hardcoded
                 Element e = new DocumentImpl().createElement("index");
                 e.setAttribute("class", "org.apache.xindice.core.indexer.ValueIndexer");
                 e.setAttribute("name", "xp_"+ps);
                 e.setAttribute("pattern", ps);
  
                 // Set the type for the index
                 String type = null;
                 switch ( objType ) {
                    case XObject.CLASS_BOOLEAN: type = "boolean"; break;
                    case XObject.CLASS_NUMBER:  type = "double";  break;
                    case XObject.CLASS_STRING:
                       if ( ps.indexOf('@') != -1 )
                          type = "string";
                       else
                          type = "trimmed";
                       break;
                 }
                 if ( type != null )
                    e.setAttribute("type", type);
  
                 idxMgr.create(new Configuration(e));
              }
           }
           catch ( Exception e ) {
              org.apache.xindice.Debug.printStackTrace(e);
           }
           return null;
        }
  
        /**
         * queryComparison performs a comparison query use the operands that
         * are passed to it, and returns the resulting Keys.
         *
         * @param op The Operator
         * @param owner The Owner Node
         * @param left The left Operand
         * @param right The right Operand
         * @return The resulting Keys (if any)
         */
        private Object queryComparison(int op, String owner, Object left, Object right) {
           if ( ! ( ( left instanceof NamedKeys ) && ( right instanceof XObject )
                 || ( left instanceof XObject ) && ( right instanceof NamedKeys ) ) )
              return null; // How'd we get here?
  
           op = OpMap[op-OpCodes.OP_NOTEQUALS];
  
           if ( left instanceof XObject ) {
              // Check if we have to switch the operation
              if ( op == IndexQuery.GT
                || op == IndexQuery.LT
                || op == IndexQuery.GEQ
                || op == IndexQuery.LEQ )
                 op = -op;
              // Swap the operands
              Object tmp = left;
              left = right;
              right = tmp;
           }
  
           NamedKeys nk = (NamedKeys)left;
           XObject obj = (XObject)right;
  
           String ps;
           if ( nk.attribute && nk.name.indexOf('@') == -1 )
              ps = owner+"@"+nk.name;
           else
              ps = nk.name;
  
           IndexQuery iq;
           IndexPattern pattern = new IndexPattern(symbols, ps, nsMap);
           String value = obj.str();
  
           switch ( op ) {
              case IndexQuery.NEQ: iq = new IndexQueryNEQ(pattern, value); break;
              case IndexQuery.EQ:  iq = new IndexQueryEQ(pattern, value);  break;
              case IndexQuery.LEQ: iq = new IndexQueryLEQ(pattern, value); break;
              case IndexQuery.LT:  iq = new IndexQueryLT(pattern, value);  break;
              case IndexQuery.GEQ: iq = new IndexQueryGEQ(pattern, value); break;
              case IndexQuery.GT:  iq = new IndexQueryGT(pattern, value);  break;
              default:             iq = null; // Won't happen
           }
  
           return queryIndexes(nk, iq, ps, obj.getType());
        }
     }
  
  
     /**
      * NamedKeys
      */
  
     private class NamedKeys {
        public boolean attribute = false;
        public String name;
        public Key[] keys;
  
        public NamedKeys(String name, boolean attribute, Key[] keys) {
           this.name = name;
           this.attribute = attribute;
           this.keys = keys;
        }
     }
     
  
     /**
      * ResultSet
      */
     
     private class ResultSet implements NodeSet {
        public XPathContext xpc = new XPathContext();
        
        public Collection context;
        public String query;
        public ErrorListener errors;
        public PrefixResolver pr;
        public XPath xp;
        
        public Key[] keySet;
        public int keyPos = 0;
        public NodeList nl;
        public int nlPos = 0;
        public int nlSize = 0;
        public Node node;
              
        public ResultSet(Collection context, PrefixResolver pr, Key[] keySet, String query) {
  //System.out.println("Query: "+query);
           this.context = context;
           this.pr = pr;
           this.keySet = keySet;
           this.query = query;
  
           errors = new ErrorListener() {
              public void fatalError(TransformerException te) {
                 org.apache.xindice.Debug.println(te);
              }
              
              public void error(TransformerException te) {
                 org.apache.xindice.Debug.println(te);
              }
              
              public void warning(TransformerException te) {
                 org.apache.xindice.Debug.println(te);
              }
           };
           
           prepareNextNode();
        }
              
        private void prepareNextNode() {
           node = null;
           while ( keyPos < keySet.length ) {
              try {
  //System.out.println("  Key: "+keySet[keyPos]);
                 DBDocument d = (DBDocument)context.getDocument(keySet[keyPos++]);
                 if ( d == null )
                    continue;
                           
                 Node n = d.getDocumentElement();
                 
                 PrefixResolver pfx;
                 if ( pr == null ) {
                    pfx = new PrefixResolverDefault(d.getDocumentElement());
                    xp = new XPath(query, null, pfx, XPath.SELECT, errors);
                 }
                 else {
                    pfx = pr;
                    if ( xp == null )
                       xp = new XPath(query, null, pfx, XPath.SELECT, errors);
                 }
  
                 nl = xp.execute(xpc, n, pfx).mutableNodeset();
  
                 nlSize = nl.getLength();
                 if ( nlSize == 0 )
                    continue;
                 else {
                    nlPos = 1;
                    node = nl.item(0);
                    break;
                 }
              }
              catch ( Exception e ) {
                 org.apache.xindice.Debug.printStackTrace(e);
              }
           }
        }
        
        public boolean hasMoreNodes() {
           return node != null;
        }
     
        public Node getNextNode() {
           Node n = node;
           
           if ( nlPos < nlSize )
              node = nl.item(nlPos++);
           else
              prepareNextNode();
  
           return n;
        }
     }
  }
  
  
  
  
  
  
  
  
  
  1.1                  xml-xindice/Xindice/java/src/org/apache/xindice/core/query/package.html
  
  Index: package.html
  ===================================================================
  <html>
    <title>Xindice Query Engine.</title>
    <body>
      <p>Implements the Xindice QueryEngine and XPathQueryResolver.  Also
      defines several interfaces for extending the QueryEngine beyond
      XPath queries.</p>
   </body>
  </html>
  
  
  
  
  
  1.1                  xml-xindice/Xindice/java/src/org/apache/xindice/core/request/URIMapper.java
  
  Index: URIMapper.java
  ===================================================================
  package org.apache.xindice.core.request;
  
  /*
   * The Apache Software License, Version 1.1
   *
   *
   * Copyright (c) 1999 The Apache Software Foundation.  All rights
   * reserved.
   *
   * Redistribution and use in source and binary forms, with or without
   * modification, are permitted provided that the following conditions
   * are met:
   *
   * 1. Redistributions of source code must retain the above copyright
   *    notice, this list of conditions and the following disclaimer.
   *
   * 2. Redistributions in binary form must reproduce the above copyright
   *    notice, this list of conditions and the following disclaimer in
   *    the documentation and/or other materials provided with the
   *    distribution.
   *
   * 3. The end-user documentation included with the redistribution,
   *    if any, must include the following acknowledgment:
   *       "This product includes software developed by the
   *        Apache Software Foundation (http://www.apache.org/)."
   *    Alternately, this acknowledgment may appear in the software itself,
   *    if and wherever such third-party acknowledgments normally appear.
   *
   * 4. The names "Xindice" and "Apache Software Foundation" must
   *    not be used to endorse or promote products derived from this
   *    software without prior written permission. For written
   *    permission, please contact apache@apache.org.
   *
   * 5. Products derived from this software may not be called "Apache",
   *    nor may "Apache" appear in their name, without prior written
   *    permission of the Apache Software Foundation.
   *
   * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
   * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
   * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
   * DISCLAIMED.  IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
   * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
   * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
   * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
   * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
   * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
   * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
   * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
   * SUCH DAMAGE.
   * ====================================================================
   *
   * This software consists of voluntary contributions made by many
   * individuals on behalf of the Apache Software Foundation and was
   * originally based on software copyright (c) 1999-2001, The dbXML
   * Group, L.L.C., http://www.dbxmlgroup.com.  For more
   * information on the Apache Software Foundation, please see
   * <http://www.apache.org/>.
   *
   * $Id: URIMapper.java,v 1.1 2001/12/06 21:00:14 bradford Exp $
   */
  
  import org.apache.xindice.util.*;
  import org.apache.xindice.core.*;
  import org.apache.xindice.core.Collection;
  import org.apache.xindice.xml.*;
  import org.apache.xindice.core.objects.*;
  
  import org.w3c.dom.*;
  
  import java.net.*;
  import java.io.*;
  import java.util.*;
  
  /**
   * URIMapper maps a URI (from whence it came) to a Xindice object.  Xindice
   * URIs can identify any of several different object types, each of which
   * exposes a different (or slightly different) interface to the outside
   * world.
   */
  
  public final class URIMapper extends URLConnection implements Poolable {
  
     public static final int UNKNOWN = -1;
     public static final int APPLICATION = 1;
     public static final int COLLECTION = 2;
     public static final int DOCUMENT = 3;
     public static final int XMLOBJECT = 4;
  
     private static final String[] EmptyStrings = new String[0];
  
     private ObjectPool   pool = null;
     private String       uri = null;
     private int          type = 0;
  
     private byte[]       buf = null;
     private int          pos = 0;
     private char         lastChar = 0;
  
     private Database  db = null;
     private Collection   collection = null;
     private Document     document = null;
     private XMLObject    xmlObject = null;
     private String       method = null;
     private Container    container = null;
  
     private Properties   params = null;
     private String[]     args = null;
  
     private String       urlresult = null;       // Holds the value of the URL resolution results (XML doc or XMLObject call results )
     private boolean      inputstreamset = false; // Flag to tell if the input stream has been initialized
  
     /** Constructor for creating URIMapper instance using a standard URL
      */
     public URIMapper(URL u) {
        super(u);
        try {
           setURI(u.toString());
        }
        catch ( Exception e) {
           // Put error code here!
           org.apache.xindice.Debug.printStackTrace(e);
        }
     }
  
     /** Constructor for older URIMapper instances
      */
     public URIMapper(String uri) throws XindiceException {
        super(null);
        setURI(uri);
     }
  
     /** Constructor for older URIMapper instances
      */
     public URIMapper() {
        super(null);
     }
  
     /* Code for new URL instance of URIMapper */
     public Object invokeRequest() throws XMLObjectException {
  
        Reflectable obj;
        obj = (Reflectable)getXMLObject();
  
        String name = getMethod();
        Reflector ref = obj.getReflector();
        Object result;
  
        Properties props = getProperties();
        if ( props != null )
           result = ref.invoke(obj, name, new MapArgs(props));
        else
           result = ref.invoke(obj, name, getArguments());
  
        return result;
     }
  
     /**
        Opens a communications link to the resource referenced by this URL,
        if such a connection has not already been established.
     */
     public void connect() {
        this.connected=true;
     }
  
     /**
        Returns an input stream that reads from this open connection.
     */
     public InputStream getInputStream() {
  
        String output = null ;
        Object result = null ;
  
        // Check if the inputstream has already been initialized, if not do now, else return the contents of urlresult
        if ( ! inputstreamset ) {
           try {
              switch ( type ) {
  
                 case URIMapper.DOCUMENT:
                    Writer doc = new StringWriter();
                    result = this.getDocument();
                    TextWriter.write((Node)result, doc);
                    output = doc.toString();
                    break;
  
                 case URIMapper.XMLOBJECT:
                    result = invokeRequest();
  
                    if ( result instanceof Node ) {
                       Writer ser = new StringWriter();
                       TextWriter.write((Node)result, ser);
                       output = ser.toString();
                    }
                    else
                       if ( result != null ) {
                          output = result.toString();
                       }
                    break;
  
                 default:
                    //  Document type not found, output error message
                    throw new Exception("Content type unsupported");
              }
           }
           catch ( Exception e ) {
              org.apache.xindice.Debug.printStackTrace(e);
           }
        }
        // Inputstream already initialized, set output to be value of urlresult
        else {
           output=urlresult ;
        }
  
        // Save the value of output into local variable urlresult
        urlresult = output ;
        // Set inpustreamset flag to signal that url has already been resolved
        inputstreamset = true ;
  
        // Send the result to the client, sending blank string if NULL
        if ( output == null)
           return new StringBufferInputStream("");
        else
           return new StringBufferInputStream(output);
  
     }
  
  
     /**
      * Returns the value of the content-encoding header field.
      * Returns:
      *       the content encoding of the resource that the URL references, or null if not known.
      */
     public String getContentEncoding() {
        // For now this method only returns null values since we are not currenlty encoding documents
        return null;
     }
  
  
     /**
      * Returns the value of the content-type header field.
      * Returns:
      *       the content type of the resource that the URL references, or null if not known.
      */
     public String getContentType() {
        // Return the docuement's content type, for now this can only be "text/xml"
        return new String("text/xml");
     }
  
     /**
      * Returns the value of the content-length header field.
      * Returns:
      *       the content length of the resource that this connection's URL references, or -1 if the content length is not known.
      */
     public int getContentLength() {
        // Check to see if this document has already been resolved, if not call getInputStream
        if ( ! inputstreamset ) {
           this.getInputStream();
        }
  
        // Return the lenght of this document/XMLObject call
        return urlresult.length();
     }
  
     /**
      * Returns the value of the last-modified header field. The result is the number of milliseconds since January 1, 1970 GMT.
      * Returns:
      *  the date the resource referenced by this URLConnection was last modified, or 0 if not known.
      */
     public long getLastModified() {
        // For now this functionality is not available, return 0
        return 0 ;
     }
  
  
  
  
  
     public void setPool(ObjectPool pool) {
        this.pool = pool;
     }
  
     public void reclaim() {
        if ( xmlObject != null && xmlObject instanceof Poolable )
           ((Poolable)xmlObject).reclaim();
        reset();
        if ( pool != null )
           pool.putObject(this);
     }
  
     /**
      * reset resets the state of the URIMapper.
      */
     private void reset() {
        type = UNKNOWN;
        lastChar = 0;
        method = "";
        db = null;
        collection = null;
        document = null;
        xmlObject = null;
        params = null;
        args = null;
        container = null;
  
        // reset urlresult and inputstreamset
        urlresult = null ;
        inputstreamset = false ;
     }
  
  
  
  
     /**
      * setURI sets the URI for the URIMapper and parses it.  The parsed
      * components of a URI can be retrieved using getObjectType and any
      * of the get<component> methods.
      *
      * @param uri The URI
      */
     public void setURI(String uri) throws XindiceException {
        this.uri = uri;
        reset();
        parse();
     }
  
     /**
      * parseName parses an identifier up to any of the specified delimiters.
      *
      * @param delims The delimiters to use
      * @return The parsed name
      */
     private String parseName(String delims) {
        int start = pos;
        while ( pos < buf.length ) {
           lastChar = (char)buf[pos++];
           if ( delims.indexOf(lastChar) != -1 )
              break;
        }
        if ( pos == buf.length && delims.indexOf(lastChar) == -1 )
           pos++;
        return pos > start ? new String(buf, start, pos-start-1)
                           : "";
     }
  
     /**
      * parseParams parses a parameter set and produces either a Properties or
      * String[] Object representing those parameters.
      */
     private void parseParams() {
        if ( lastChar == '?' ) {
           // Query String param list
           params = new Properties();
           String name;
           String value;
           String temp;
           while ( true ) {
              name = parseName("=");
              if ( name.length() == 0 )
                 break;
              value = parseName("?&;");
              temp = params.getProperty(name);
              if( temp != null ) {
                 StringBuffer sb = new StringBuffer(32);
                 sb.append(temp);
                 sb.append('\u0001');
                 sb.append(value);
                 value = sb.toString();
              }
              params.setProperty(name, value);
           }
        }
        else if ( lastChar == '(' ) {
           // Java-like argument list
           // TODO: This code is nowhere near perfect... It could use a good gutting
           String tmp = new String(buf, pos, buf.length-pos);
           StringReader bis = new StringReader(tmp);
           StreamTokenizer st = new StreamTokenizer(bis);
           st.resetSyntax();
           st.whitespaceChars(0, 32);
           st.wordChars(48, 122);
           st.wordChars(13, 13);
           st.ordinaryChars(33, 46);
           st.ordinaryChars(58, 64);
           st.ordinaryChars(91, 96);
           st.ordinaryChars(123, 127);
           st.slashSlashComments(false);
           st.slashStarComments(false);
           st.eolIsSignificant(false);
           st.quoteChar('\"');
           st.quoteChar('\'');
           st.quoteChar('|');
           st.commentChar('/');
           List list = new ArrayList();
           boolean done = false;
           try {
              while ( !done && st.nextToken() != StreamTokenizer.TT_EOF ) {
                 switch ( st.ttype ) {
  
                    case StreamTokenizer.TT_WORD:
                       list.add(st.sval);
                       break;
  
                    case '\"':
                       list.add(st.sval);
                       break;
  
                    case '\'':
                    case '|':
                       list.add(st.sval);
                       break;
  
                    case '[':
                       boolean doneArray = false;
                       StringBuffer sb = new StringBuffer();
                       while ( !doneArray && st.nextToken() != StreamTokenizer.TT_EOF) {
                          switch ( st.ttype ) {
  
                             case StreamTokenizer.TT_WORD:
                                if ( sb.length() > 0 )
                                   sb.append('\u0001');
                                sb.append(st.sval);
                                break;
  
                             case ']':
                                doneArray = true;
                                break;
  
                          }
                       }
                       list.add(sb.toString());
                       break;
  
                    case ')':
                       done = true;
                       break;
  
                 }
              }
           }
           catch ( Exception e ) {
              org.apache.xindice.Debug.printStackTrace(e);
              return;
           }
           args = (String[])list.toArray(EmptyStrings);
        }
        else
           params = new Properties();
     }
  
     private void parseXMLObject() {
        try {
           if ( lastChar == '/' )
              method = parseName("/(?");
           if ( method.length() == 0 )
              method = "execute";
  
           type = XMLOBJECT;
           parseParams();
        }
        catch ( Exception e ) {
           org.apache.xindice.Debug.printStackTrace(e);
        }
     }
  
     /**
      * parse parses the URI.
      */
     private void parse() throws XindiceException {
        buf = uri.getBytes();
        pos = 0;
        String tmp;
  
        if ( buf.length == 0 ) {
           throw new DBException(FaultCodes.URI_EMPTY);
        }
        
        // TODO: Be Able To Handle Remote URIs
        if ( (char)buf[0] != '/' ) {
           parseName(":"); // Ignore Protocol
           parseName("/"); // Ignore Slash
           parseName("/"); // Ignore Slash
           parseName("/:"); // Ignore Host (For Now)
           if ( lastChar == ':' )
              parseName("/"); // Ignore Port
        }
        else
           pos = 1;
  
        // Database check
        tmp = parseName("/");
        if ( tmp == null )
           return;
  
        db = Database.getDatabase(tmp);
        if ( db == null )
           return;
  
        type = APPLICATION;
        tmp = parseName("/(?");
  
  
        int objType = getParsedObjectType(db, tmp);
        // If unknown then this URI just points to db and we're done.
        // Otherwise we need to keep walking down the URI.
        if (objType != UNKNOWN) {
           type = walkURI(db, tmp, objType);
        }
  
        if ( lastChar == '?' ) {
           parseParams();
           return;
        }
     }
  
     /**
      * Recursive method to handle the parse of the URI and setup the instance
      * objects.
      */
     protected int walkURI(Collection col, String name, int objType)
           throws XindiceException {
        switch (objType) {
           case DOCUMENT:
              container = col.getContainer(name);
              document = container.getDocument();
              return DOCUMENT;
  
           case XMLOBJECT:
              xmlObject = col.getXMLObject(name);
              if ( xmlObject != null ) {
                 parseXMLObject();
                 return XMLOBJECT;
              }
              break;
  
           case COLLECTION:
              Collection c = col.getCollection(name);
              if ( c != null ) {
                 collection = c;
                 String tmp = parseName("/(?");
                 // If we have another name recurse to handle it.
                 if (! tmp.equals("")) {
                    return walkURI(c, tmp, getParsedObjectType(c, tmp));
                 }
  
                 return COLLECTION;
              }
        }
  
        return UNKNOWN;
     }
  
     /**
      * Determine the type of object. If more then one object has the same name
      * the order of precedence is COLLECTION - XMLOBJECT - DOCUMENT
      */
     protected int getParsedObjectType(Collection col, String name)
           throws XindiceException {
  
        if (col.getCollection(name) != null) {
           return COLLECTION;
        }
        else if (col.getXMLObject(name) != null) {
           return XMLOBJECT;
        }
        else if ((col.getFiler() != null) && (col.getContainer(name) != null)) {
           return DOCUMENT;
        }
        else {
           return UNKNOWN;
        }
     }
  
     /**
      * getObjectType returns the type of Object that was identified in the
      * parsing of the URI.  This method will return one of the following
      * values: UNKNOWN, APPLICATION, DATABASE, COLLECTION, DOCUMENT or
      * XMLOBJECT.
      *
      * @return The object type
      */
     public int getObjectType() {
        return type;
     }
  
     /**
      * getDatabase returns the Database that was resolved in the
      * parsing of this URI.
      *
      * @return The Database
      */
     public Database getDatabase() {
        return db;
     }
  
     /**
      * getCollection returns the Collection object that was resolved in the
      * parsing of the URI.  If no Collection was resolved, this method will
      * return null.
      *
      * @return The Collection
      */
     public Collection getCollection() {
        return collection;
     }
  
     /**
      * getDocument returns the Document object that was resolved in the
      * parsing of the URI.  If no Document was resolved, this method will
      * return null.
      *
      * @return The Document
      */
     public Document getDocument() {
        return document;
     }
  
     /**
      * getContainer returns the Document Container that was resolved in
      * the parsing of the URI.  If no Container was resolved, this method
      * will return null.
      *
      * @return The Container
      */
     public Container getContainer() {
        return container;
     }
  
     /**
      * getXMLObject returns the XMLObject that was resolved in the parsing
      * of the URI.  If no XMLObject was resolve, this method will return
      * null.
      *
      * @return The XMLObject
      */
     public XMLObject getXMLObject() {
        return xmlObject;
     }
  
     /**
      * getMethod returns the method name that was resolved in the parsing
      * of the URI.  Method names are associated with XMLObjects.
      * If no method name was resolved, this method will return null.
      *
      * @return The method name
      */
     public String getMethod() {
        return method;
     }
  
     /**
      * getProperties returns the Properties object that was produced in
      * parsing the URI's Query String.  Properties are passed into methods
      * that are associated with XMLObjects.  This method will return null if
      * no Properties were resolved.
      *
      * @return The Query String Properties
      */
     public Properties getProperties() {
        return params;
     }
  
     /**
      * getArguments returns method arguments in the form of a String array.
      * Method arguments are passed to a method in the order that they are
      * specified in the URI.  If no arguments were parsed, this method will
      * return null.
      *
      * @return The method arguments
      */
     public String[] getArguments() {
        return args;
     }
  }
  
  
  
  
  
  1.1                  xml-xindice/Xindice/java/src/org/apache/xindice/core/request/XindiceStreamHandler.java
  
  Index: XindiceStreamHandler.java
  ===================================================================
  package org.apache.xindice.core.request;
  
  /*
   * The Apache Software License, Version 1.1
   *
   *
   * Copyright (c) 1999 The Apache Software Foundation.  All rights
   * reserved.
   *
   * Redistribution and use in source and binary forms, with or without
   * modification, are permitted provided that the following conditions
   * are met:
   *
   * 1. Redistributions of source code must retain the above copyright
   *    notice, this list of conditions and the following disclaimer.
   *
   * 2. Redistributions in binary form must reproduce the above copyright
   *    notice, this list of conditions and the following disclaimer in
   *    the documentation and/or other materials provided with the
   *    distribution.
   *
   * 3. The end-user documentation included with the redistribution,
   *    if any, must include the following acknowledgment:
   *       "This product includes software developed by the
   *        Apache Software Foundation (http://www.apache.org/)."
   *    Alternately, this acknowledgment may appear in the software itself,
   *    if and wherever such third-party acknowledgments normally appear.
   *
   * 4. The names "Xindice" and "Apache Software Foundation" must
   *    not be used to endorse or promote products derived from this
   *    software without prior written permission. For written
   *    permission, please contact apache@apache.org.
   *
   * 5. Products derived from this software may not be called "Apache",
   *    nor may "Apache" appear in their name, without prior written
   *    permission of the Apache Software Foundation.
   *
   * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
   * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
   * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
   * DISCLAIMED.  IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
   * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
   * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
   * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
   * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
   * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
   * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
   * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
   * SUCH DAMAGE.
   * ====================================================================
   *
   * This software consists of voluntary contributions made by many
   * individuals on behalf of the Apache Software Foundation and was
   * originally based on software copyright (c) 1999-2001, The dbXML
   * Group, L.L.C., http://www.dbxmlgroup.com.  For more
   * information on the Apache Software Foundation, please see
   * <http://www.apache.org/>.
   *
   * $Id: XindiceStreamHandler.java,v 1.1 2001/12/06 21:00:14 bradford Exp $
   */
  
  import java.net.*;
  import java.io.*;
  
  /**
   *
   * XindiceStreamHandler handler that knows how to handle Xindice URL instances
   *
   */
  
  public class XindiceStreamHandler extends URLStreamHandler{
  
     public XindiceStreamHandler () {
     }
  
     /**
      * Returns a URLConnection object that represents a connection to the remote object referred to by the URL.
      *
      */
     protected URLConnection openConnection(URL u) {
        return new URIMapper(u);
     }
  
  
  }
  
  
  
  1.1                  xml-xindice/Xindice/java/src/org/apache/xindice/core/request/XindiceStreamHandlerFactory.java
  
  Index: XindiceStreamHandlerFactory.java
  ===================================================================
  package org.apache.xindice.core.request;
  
  /*
   * The Apache Software License, Version 1.1
   *
   *
   * Copyright (c) 1999 The Apache Software Foundation.  All rights
   * reserved.
   *
   * Redistribution and use in source and binary forms, with or without
   * modification, are permitted provided that the following conditions
   * are met:
   *
   * 1. Redistributions of source code must retain the above copyright
   *    notice, this list of conditions and the following disclaimer.
   *
   * 2. Redistributions in binary form must reproduce the above copyright
   *    notice, this list of conditions and the following disclaimer in
   *    the documentation and/or other materials provided with the
   *    distribution.
   *
   * 3. The end-user documentation included with the redistribution,
   *    if any, must include the following acknowledgment:
   *       "This product includes software developed by the
   *        Apache Software Foundation (http://www.apache.org/)."
   *    Alternately, this acknowledgment may appear in the software itself,
   *    if and wherever such third-party acknowledgments normally appear.
   *
   * 4. The names "Xindice" and "Apache Software Foundation" must
   *    not be used to endorse or promote products derived from this
   *    software without prior written permission. For written
   *    permission, please contact apache@apache.org.
   *
   * 5. Products derived from this software may not be called "Apache",
   *    nor may "Apache" appear in their name, without prior written
   *    permission of the Apache Software Foundation.
   *
   * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
   * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
   * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
   * DISCLAIMED.  IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
   * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
   * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
   * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
   * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
   * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
   * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
   * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
   * SUCH DAMAGE.
   * ====================================================================
   *
   * This software consists of voluntary contributions made by many
   * individuals on behalf of the Apache Software Foundation and was
   * originally based on software copyright (c) 1999-2001, The dbXML
   * Group, L.L.C., http://www.dbxmlgroup.com.  For more
   * information on the Apache Software Foundation, please see
   * <http://www.apache.org/>.
   *
   * $Id: XindiceStreamHandlerFactory.java,v 1.1 2001/12/06 21:00:14 bradford Exp $
   */
  
  import java.net.*;
  import java.io.*;
  
  
  /**
  
     This interface defines a factory for URL stream protocol handlers.
     It is used by the URL class to create a URLStreamHandler for a specific protocol.
  
  */
  
  
  public class XindiceStreamHandlerFactory implements URLStreamHandlerFactory {
     static { URL.setURLStreamHandlerFactory( new XindiceStreamHandlerFactory() ); }
  
     String OurProtocol = "xindice";
     /**
      * Creates an instance of an URLStreamHandler
      */
     public URLStreamHandler createURLStreamHandler(String protocol) {
  
        // If dealing with a Xindice object, return our stream handler
        if ( protocol.equalsIgnoreCase(OurProtocol) ) {
           return new XindiceStreamHandler();
        }
        // Else return null to use default stream handler for protocol
        else
           return null;
     }
  
  
  }
  
  
  
  
  1.1                  xml-xindice/Xindice/java/src/org/apache/xindice/core/request/package.html
  
  Index: package.html
  ===================================================================
  <html>
    <title>Xindice Request Handlers.</title>
    <body>
      <p>Implements several interfaces for extending Xindice resources
      into the standard Java URLConnection system.</p>
   </body>
  </html>
  
  
  
  
  
  1.1                  xml-xindice/Xindice/java/src/org/apache/xindice/core/security/AccessDeniedException.java
  
  Index: AccessDeniedException.java
  ===================================================================
  package org.apache.xindice.core.security;
  
  /*
   * The Apache Software License, Version 1.1
   *
   *
   * Copyright (c) 1999 The Apache Software Foundation.  All rights
   * reserved.
   *
   * Redistribution and use in source and binary forms, with or without
   * modification, are permitted provided that the following conditions
   * are met:
   *
   * 1. Redistributions of source code must retain the above copyright
   *    notice, this list of conditions and the following disclaimer.
   *
   * 2. Redistributions in binary form must reproduce the above copyright
   *    notice, this list of conditions and the following disclaimer in
   *    the documentation and/or other materials provided with the
   *    distribution.
   *
   * 3. The end-user documentation included with the redistribution,
   *    if any, must include the following acknowledgment:
   *       "This product includes software developed by the
   *        Apache Software Foundation (http://www.apache.org/)."
   *    Alternately, this acknowledgment may appear in the software itself,
   *    if and wherever such third-party acknowledgments normally appear.
   *
   * 4. The names "Xindice" and "Apache Software Foundation" must
   *    not be used to endorse or promote products derived from this
   *    software without prior written permission. For written
   *    permission, please contact apache@apache.org.
   *
   * 5. Products derived from this software may not be called "Apache",
   *    nor may "Apache" appear in their name, without prior written
   *    permission of the Apache Software Foundation.
   *
   * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
   * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
   * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
   * DISCLAIMED.  IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
   * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
   * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
   * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
   * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
   * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
   * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
   * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
   * SUCH DAMAGE.
   * ====================================================================
   *
   * This software consists of voluntary contributions made by many
   * individuals on behalf of the Apache Software Foundation and was
   * originally based on software copyright (c) 1999-2001, The dbXML
   * Group, L.L.C., http://www.dbxmlgroup.com.  For more
   * information on the Apache Software Foundation, please see
   * <http://www.apache.org/>.
   *
   * $Id: AccessDeniedException.java,v 1.1 2001/12/06 21:00:14 bradford Exp $
   */
  
  import org.apache.xindice.core.*;
  import org.apache.xindice.util.*;
  
  /**
   * A AccessDeniedException is thrown if access is denied to a resource within
   * the database.
   */
  
  public class AccessDeniedException extends SecurityException {
     public AccessDeniedException() {
        super(FaultCodes.SEC_INVALID_ACCESS);
     }
     
     public AccessDeniedException(String message) {
        super(FaultCodes.SEC_INVALID_ACCESS, message);
     }
  }
  
  
  
  1.1                  xml-xindice/Xindice/java/src/org/apache/xindice/core/security/Credentials.java
  
  Index: Credentials.java
  ===================================================================
  package org.apache.xindice.core.security;
  
  /*
   * The Apache Software License, Version 1.1
   *
   *
   * Copyright (c) 1999 The Apache Software Foundation.  All rights
   * reserved.
   *
   * Redistribution and use in source and binary forms, with or without
   * modification, are permitted provided that the following conditions
   * are met:
   *
   * 1. Redistributions of source code must retain the above copyright
   *    notice, this list of conditions and the following disclaimer.
   *
   * 2. Redistributions in binary form must reproduce the above copyright
   *    notice, this list of conditions and the following disclaimer in
   *    the documentation and/or other materials provided with the
   *    distribution.
   *
   * 3. The end-user documentation included with the redistribution,
   *    if any, must include the following acknowledgment:
   *       "This product includes software developed by the
   *        Apache Software Foundation (http://www.apache.org/)."
   *    Alternately, this acknowledgment may appear in the software itself,
   *    if and wherever such third-party acknowledgments normally appear.
   *
   * 4. The names "Xindice" and "Apache Software Foundation" must
   *    not be used to endorse or promote products derived from this
   *    software without prior written permission. For written
   *    permission, please contact apache@apache.org.
   *
   * 5. Products derived from this software may not be called "Apache",
   *    nor may "Apache" appear in their name, without prior written
   *    permission of the Apache Software Foundation.
   *
   * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
   * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
   * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
   * DISCLAIMED.  IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
   * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
   * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
   * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
   * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
   * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
   * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
   * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
   * SUCH DAMAGE.
   * ====================================================================
   *
   * This software consists of voluntary contributions made by many
   * individuals on behalf of the Apache Software Foundation and was
   * originally based on software copyright (c) 1999-2001, The dbXML
   * Group, L.L.C., http://www.dbxmlgroup.com.  For more
   * information on the Apache Software Foundation, please see
   * <http://www.apache.org/>.
   *
   * $Id: Credentials.java,v 1.1 2001/12/06 21:00:14 bradford Exp $
   */
  
   import java.util.*;
  
  /**
   * Credenials encapsulates authentication credentials within the system.
   */
  public interface Credentials {
  
     /**
      * Verifies that the credentials are valid.
      *
      * @exception InvalidCredentialsException Thrown if the credentials
      *            are not valid.
      */
     void verify() throws InvalidCredentialsException;
  
     /**
      * Determines if these credentials have an association with the specified
      * group.
      *
      * @param group The group to check membership of
      * @return true if the group membership exists false otherwise.
      * @exception AccessDeniedException Thrown when access to the resource is
      *            denied.
      * @exception InvalidCredentialsException Thrown if the provided credentials
      *            are not valid.
      */
     boolean checkGroup(String group) throws AccessDeniedException,
        InvalidCredentialsException;
  
     /**
      * Returns the list of groups to which these credentials belong.
      *
      * @return the list of groups
      */
     public ArrayList getGroups();
  }
  
  
  
  1.1                  xml-xindice/Xindice/java/src/org/apache/xindice/core/security/DBSecurityManager.java
  
  Index: DBSecurityManager.java
  ===================================================================
  package org.apache.xindice.core.security;
  
  /*
   * The Apache Software License, Version 1.1
   *
   *
   * Copyright (c) 1999 The Apache Software Foundation.  All rights
   * reserved.
   *
   * Redistribution and use in source and binary forms, with or without
   * modification, are permitted provided that the following conditions
   * are met:
   *
   * 1. Redistributions of source code must retain the above copyright
   *    notice, this list of conditions and the following disclaimer.
   *
   * 2. Redistributions in binary form must reproduce the above copyright
   *    notice, this list of conditions and the following disclaimer in
   *    the documentation and/or other materials provided with the
   *    distribution.
   *
   * 3. The end-user documentation included with the redistribution,
   *    if any, must include the following acknowledgment:
   *       "This product includes software developed by the
   *        Apache Software Foundation (http://www.apache.org/)."
   *    Alternately, this acknowledgment may appear in the software itself,
   *    if and wherever such third-party acknowledgments normally appear.
   *
   * 4. The names "Xindice" and "Apache Software Foundation" must
   *    not be used to endorse or promote products derived from this
   *    software without prior written permission. For written
   *    permission, please contact apache@apache.org.
   *
   * 5. Products derived from this software may not be called "Apache",
   *    nor may "Apache" appear in their name, without prior written
   *    permission of the Apache Software Foundation.
   *
   * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
   * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
   * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
   * DISCLAIMED.  IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
   * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
   * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
   * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
   * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
   * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
   * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
   * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
   * SUCH DAMAGE.
   * ====================================================================
   *
   * This software consists of voluntary contributions made by many
   * individuals on behalf of the Apache Software Foundation and was
   * originally based on software copyright (c) 1999-2001, The dbXML
   * Group, L.L.C., http://www.dbxmlgroup.com.  For more
   * information on the Apache Software Foundation, please see
   * <http://www.apache.org/>.
   *
   * $Id: DBSecurityManager.java,v 1.1 2001/12/06 21:00:14 bradford Exp $
   */
  
   import org.apache.xindice.util.*;
  
  /**
   * SecurityManager is the interface to the access control functionality of the
   * server.
   */
  public interface DBSecurityManager extends Named, Configurable {
     /**
      * Determines if the provided credentials are valid for accessing the
      * specified resource.
      *
      * @param resource The resource to check access for.
      * @param requestedAccess The access level being requested.
      * @param cred The credentials to use to authenticate
      * @exception AccessDeniedException Thrown when access to the resource is
      *            denied.
      * @exception InvalidCredentialsException Thrown if the provided credentials
      *            are not valid.
      */
     void checkAccess(String resource, int requestedAccess, Credentials cred)
        throws AccessDeniedException, InvalidCredentialsException;
  
     /**
      * Determines if the credentials retrieved from thread local storage are
      * valid for accessing the specified resource.
      *
      * @param resource The resource to check access for.
      * @param requestedAccess The access level being requested.
      * @param cred The credentials to use to authenticate
      * @exception AccessDeniedException Thrown when access to the resource is
      *            denied.
      * @exception InvalidCredentialsException Thrown if the credentials retrieved
      *            from thread local storage are not valid.
      */
     void checkAccess(String resource, int requestedAccess)
        throws AccessDeniedException, InvalidCredentialsException;
  
     /**
      * Authenticates the user and retrieves a credentials object for the
      * provided username and password. If
      * an existing object can be found in the cache it will be returned otherwise
      * a new Credentials instance will be created and returned. Cached objects
      * are verified before being returned.
      *
      * @param username The username to authenticate
      * @param password The password used to authenticate the user.
      * @exception InvalidPasswordException Thrown when the password provided does
      *            not match for the username.
      * @exception UnknownUserException Thrown when the username can not be found.
      */
     Credentials authenticate(String username, String password)
        throws InvalidPasswordException, UnknownUserException,
           InvalidCredentialsException;
  
     /**
      * Removes any credentials associated with the current thread. Any further
      * access by the thread will result in a InvalidCredentialsException being
      * thrown.
      */
     void logout();
  
     /**
      * Reads the security managers configuration and prepares it for operation.
      */
     void readConfig();
  
     void setActive();
  }
  
  
  
  1.1                  xml-xindice/Xindice/java/src/org/apache/xindice/core/security/InvalidCredentialsException.java
  
  Index: InvalidCredentialsException.java
  ===================================================================
  package org.apache.xindice.core.security;
  
  /*
   * The Apache Software License, Version 1.1
   *
   *
   * Copyright (c) 1999 The Apache Software Foundation.  All rights
   * reserved.
   *
   * Redistribution and use in source and binary forms, with or without
   * modification, are permitted provided that the following conditions
   * are met:
   *
   * 1. Redistributions of source code must retain the above copyright
   *    notice, this list of conditions and the following disclaimer.
   *
   * 2. Redistributions in binary form must reproduce the above copyright
   *    notice, this list of conditions and the following disclaimer in
   *    the documentation and/or other materials provided with the
   *    distribution.
   *
   * 3. The end-user documentation included with the redistribution,
   *    if any, must include the following acknowledgment:
   *       "This product includes software developed by the
   *        Apache Software Foundation (http://www.apache.org/)."
   *    Alternately, this acknowledgment may appear in the software itself,
   *    if and wherever such third-party acknowledgments normally appear.
   *
   * 4. The names "Xindice" and "Apache Software Foundation" must
   *    not be used to endorse or promote products derived from this
   *    software without prior written permission. For written
   *    permission, please contact apache@apache.org.
   *
   * 5. Products derived from this software may not be called "Apache",
   *    nor may "Apache" appear in their name, without prior written
   *    permission of the Apache Software Foundation.
   *
   * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
   * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
   * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
   * DISCLAIMED.  IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
   * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
   * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
   * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
   * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
   * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
   * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
   * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
   * SUCH DAMAGE.
   * ====================================================================
   *
   * This software consists of voluntary contributions made by many
   * individuals on behalf of the Apache Software Foundation and was
   * originally based on software copyright (c) 1999-2001, The dbXML
   * Group, L.L.C., http://www.dbxmlgroup.com.  For more
   * information on the Apache Software Foundation, please see
   * <http://www.apache.org/>.
   *
   * $Id: InvalidCredentialsException.java,v 1.1 2001/12/06 21:00:14 bradford Exp $
   */
  
  import org.apache.xindice.core.*;
  import org.apache.xindice.util.*;
  
  /**
   * A InvalidCredentialsException is thrown if the credentials used in an access
   * control method are invalid.
   */
  
  public class InvalidCredentialsException extends SecurityException {
     public InvalidCredentialsException() {
        super(FaultCodes.SEC_INVALID_CREDENTIALS);
     }
     
     public InvalidCredentialsException(String message) {
        super(FaultCodes.SEC_INVALID_CREDENTIALS, message);
     }
  }
  
  
  
  1.1                  xml-xindice/Xindice/java/src/org/apache/xindice/core/security/InvalidPasswordException.java
  
  Index: InvalidPasswordException.java
  ===================================================================
  package org.apache.xindice.core.security;
  
  /*
   * The Apache Software License, Version 1.1
   *
   *
   * Copyright (c) 1999 The Apache Software Foundation.  All rights
   * reserved.
   *
   * Redistribution and use in source and binary forms, with or without
   * modification, are permitted provided that the following conditions
   * are met:
   *
   * 1. Redistributions of source code must retain the above copyright
   *    notice, this list of conditions and the following disclaimer.
   *
   * 2. Redistributions in binary form must reproduce the above copyright
   *    notice, this list of conditions and the following disclaimer in
   *    the documentation and/or other materials provided with the
   *    distribution.
   *
   * 3. The end-user documentation included with the redistribution,
   *    if any, must include the following acknowledgment:
   *       "This product includes software developed by the
   *        Apache Software Foundation (http://www.apache.org/)."
   *    Alternately, this acknowledgment may appear in the software itself,
   *    if and wherever such third-party acknowledgments normally appear.
   *
   * 4. The names "Xindice" and "Apache Software Foundation" must
   *    not be used to endorse or promote products derived from this
   *    software without prior written permission. For written
   *    permission, please contact apache@apache.org.
   *
   * 5. Products derived from this software may not be called "Apache",
   *    nor may "Apache" appear in their name, without prior written
   *    permission of the Apache Software Foundation.
   *
   * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
   * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
   * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
   * DISCLAIMED.  IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
   * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
   * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
   * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
   * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
   * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
   * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
   * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
   * SUCH DAMAGE.
   * ====================================================================
   *
   * This software consists of voluntary contributions made by many
   * individuals on behalf of the Apache Software Foundation and was
   * originally based on software copyright (c) 1999-2001, The dbXML
   * Group, L.L.C., http://www.dbxmlgroup.com.  For more
   * information on the Apache Software Foundation, please see
   * <http://www.apache.org/>.
   *
   * $Id: InvalidPasswordException.java,v 1.1 2001/12/06 21:00:14 bradford Exp $
   */
  
  import org.apache.xindice.core.*;
  import org.apache.xindice.util.*;
  
  /**
   * A InvalidPasswordException is thrown if access is denied to a resource within
   * the database.
   */
  
  public class InvalidPasswordException extends SecurityException {
     public InvalidPasswordException() {
        super(FaultCodes.SEC_INVALID_ACCESS);
     }
     
     public InvalidPasswordException(String message) {
        super(FaultCodes.SEC_INVALID_ACCESS, message);
     }
  }
  
  
  
  1.1                  xml-xindice/Xindice/java/src/org/apache/xindice/core/security/LocalSecurityManager.java
  
  Index: LocalSecurityManager.java
  ===================================================================
  package org.apache.xindice.core.security;
  
  /*
   * The Apache Software License, Version 1.1
   *
   *
   * Copyright (c) 1999 The Apache Software Foundation.  All rights
   * reserved.
   *
   * Redistribution and use in source and binary forms, with or without
   * modification, are permitted provided that the following conditions
   * are met:
   *
   * 1. Redistributions of source code must retain the above copyright
   *    notice, this list of conditions and the following disclaimer.
   *
   * 2. Redistributions in binary form must reproduce the above copyright
   *    notice, this list of conditions and the following disclaimer in
   *    the documentation and/or other materials provided with the
   *    distribution.
   *
   * 3. The end-user documentation included with the redistribution,
   *    if any, must include the following acknowledgment:
   *       "This product includes software developed by the
   *        Apache Software Foundation (http://www.apache.org/)."
   *    Alternately, this acknowledgment may appear in the software itself,
   *    if and wherever such third-party acknowledgments normally appear.
   *
   * 4. The names "Xindice" and "Apache Software Foundation" must
   *    not be used to endorse or promote products derived from this
   *    software without prior written permission. For written
   *    permission, please contact apache@apache.org.
   *
   * 5. Products derived from this software may not be called "Apache",
   *    nor may "Apache" appear in their name, without prior written
   *    permission of the Apache Software Foundation.
   *
   * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
   * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
   * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
   * DISCLAIMED.  IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
   * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
   * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
   * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
   * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
   * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
   * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
   * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
   * SUCH DAMAGE.
   * ====================================================================
   *
   * This software consists of voluntary contributions made by many
   * individuals on behalf of the Apache Software Foundation and was
   * originally based on software copyright (c) 1999-2001, The dbXML
   * Group, L.L.C., http://www.dbxmlgroup.com.  For more
   * information on the Apache Software Foundation, please see
   * <http://www.apache.org/>.
   *
   * $Id: LocalSecurityManager.java,v 1.1 2001/12/06 21:00:14 bradford Exp $
   */
  
  import org.apache.xindice.core.*;
  import org.apache.xindice.xml.dom.*;
  import org.apache.xindice.util.*;
  
  import java.util.*;
  import java.io.*;
  import org.w3c.dom.*;
  
  /**
   * Implements security based off of configurations stored in the local database
   * configuration.
   */
  public class LocalSecurityManager implements DBSecurityManager {
     private static final String ACL_COLLECTION = "system/SysAccess";
     private static final String ACL_FILE = "config/acl.xml";
     private static final String PERMISSIONS = "permissions";
     private static final String COLLECTIONS = "collections";
     private static final String COLLECTION = "collection";
     private static final String DOCUMENTS = "documents";
     private static final String XMLOBJECTS = "xmlobjects";
     private static final String XMLOBJECT = "xmlobject";
     private static final String RESOURCES = "resources";
     private static final String RESOURCE = "resource";
     private static final String NAME = "name";
     private static final String CORE = "core";
     private static final String ADMIN = "admin";
     private static final String ALL_ACCESS_GROUP = "xindice-sys-all";
  
     protected Configuration config = null;
     protected Database db = null;
     protected HashMap permissions = null;
  
     private static ThreadLocal credentials = new ThreadLocal();
  
     // When the security manager is first started it is set into startup mode
     // which disables access control so system collections can be loaded.
     private boolean startup = true;
  
     // Can be set in the server configuration to disable security. This is here
     // mainly for development should probably be removed in production.
     private boolean disabled = false;
  
     /**
      * Initialize the security manager. The security manager can not actually be
      * used until readConfig() is called.
      *
      * @param db the Database instance associated with this manager
      * @param disabled whether security should be enabled or not. true to
      *        disable.
      */
     public LocalSecurityManager(Database db, boolean disabled) {
        this.db = db;
        this.disabled = disabled;
  
        permissions = new HashMap();
     }
  
     /**
      * getName retrieves the contextually important name of the object
      *
      * @return The object's name
      */
     public String getName() {
        return "LocalSecurityManager";
     }
  
     /**
      * Determines if the provided credentials are valid for accessing the
      * specified resource.
      *
      * @param resource The resource to check access for.
      * @param requestedAccess The access level being requested.
      * @param cred The credentials to use to authenticate
      * @exception AccessDeniedException Thrown when access to the resource is
      *            denied.
      * @exception InvalidCredentialsException Thrown if the provided credentials
      *            are not valid.
      */
     public void checkAccess(String resource, int requestedAccess, Credentials cred)
           throws AccessDeniedException, InvalidCredentialsException {
        // If we're in startup mode or security is disabled no access checking
        // can be done.
        if (startup || disabled) {
           return;
        }
  
        if (cred == null) {
           throw new InvalidCredentialsException();
        }
  
        ResourcePermissions perms = (ResourcePermissions)permissions.get(resource);
        // get list of groups
        ArrayList groups = cred.getGroups();
  
        // If the admin group exists unrestricted access is allowed.
        if (groups.contains(ADMIN)) {
            return;
        }
  
        if (perms != null) {
           // for each group check if they have access
           for (int i = 0; i < groups.size(); i++) {
              String group = (String)groups.get(i);
              // Check if the resource has been granted default full access.
              if (perms.checkPermission(Permission.ALLOW, requestedAccess,
                    ALL_ACCESS_GROUP)) {
                 return;
              }
  
              // Check first for explicit deny. If a deny is found for any group
              // then access is automatically denied.
              if (perms.checkPermission(Permission.DENY, requestedAccess, group)) {
                 throw new AccessDeniedException();
              }
              else {
                 if (perms.checkPermission(Permission.ALLOW, requestedAccess, group)) {
                    return;
                 }
              }
           }
        }
  
        throw new AccessDeniedException();
     }
  
     /**
      * Determines if the credentials retrieved from thread local storage are
      * valid for accessing the specified resource.
      *
      * @param resource The resource to check access for.
      * @param requestedAccess The access level being requested.
      * @param cred The credentials to use to authenticate
      * @exception AccessDeniedException Thrown when access to the resource is
      *            denied.
      * @exception InvalidCredentialsException Thrown if the credentials retrieved
      *            from thread local storage are not valid.
      */
     public void checkAccess(String resource, int requestedAccess)
           throws AccessDeniedException, InvalidCredentialsException {
        checkAccess(resource, requestedAccess, (Credentials)credentials.get());
     }
  
     /**
      * Authenticates the user and retrieves a credentials object for
      * the provided username and password. If
      * an existing object can be found in the cache it will be returned otherwise
      * a new Credentials instance will be created and returned. Cached objects
      * are verified before being returned.
      *
      * @param username The username to authenticate
      * @param password The password used to authenticate the user.
      * @exception InvalidPasswordException Thrown when the password provided does
      *            not match for the username.
      * @exception UnknownUserException Thrown when the username can not be found.
      */
     public Credentials authenticate(String username, String password)
           throws InvalidPasswordException, UnknownUserException,
              InvalidCredentialsException {
        Credentials cred =
           new PasswordCredentials(username, password, db);
  
        // Add the credentials to thread local storage for the requesting thread.
        credentials.set(cred);
  
        return cred;
     }
  
     /**
      * Removes any credentials associated with the current thread. Any further
      * access by the thread will result in a InvalidCredentialsException being
      * thrown.
      */
     public void logout() {
        credentials.set(null);
     }
  
     public void setActive() {
        this.startup = false;
     }
  
     /**
      * Reads the ACL security configuration from the database.
      */
     public void readConfig() {
        String base = "/";
        try {
           // Read in the configuration. For now we read it from the file system.
           // TODO: Eventually it should be stored in the database
           Document doc = null;
  
           // TODO: aclFile should be configurable via either the command line or
           // via system.xml. Probably system.xml.
           String aclFile = ACL_FILE;
           try {
              FileInputStream fis = new FileInputStream(aclFile);
              doc = DOMParser.toDocument(fis);
              fis.close();
           }
           catch ( Exception e ) {
              org.apache.xindice.Debug.println("\u0007FATAL ERROR: Reading security configuration file '" + aclFile + "'");
              org.apache.xindice.Debug.printStackTrace(e);
              System.exit(1);
           }
  
  //         Document doc =
  //            db.getCollection(ACL_COLLECTION).getDocument(ACL_FILE);
           if (doc != null) {
              Configuration config = new Configuration(doc.getDocumentElement(), false);
              Configuration core = config.getChild(CORE);
              final String resourceName = base + core.getAttribute(NAME) + "/";
              handleConfig(resourceName, core.getChild(PERMISSIONS, true));
  
              Configuration collections = core.getChild(COLLECTIONS);
              if (collections != null) {
                 collections.processChildren(COLLECTION,
                    new ConfigurationCallback() {
                       public void process(Configuration cfg) {
                          try {
                             org.apache.xindice.Debug.println(cfg.getName());
                             String name = resourceName + cfg.getAttribute(NAME) + "/";
                             handleCollection(resourceName, cfg);
                          }
                          catch (ReadOnlyException e) {
                             org.apache.xindice.Debug.printStackTrace(e);
                          }
                       }
                 });
              }
           }
           else {
              org.apache.xindice.Debug.println("Access Control List could not be loaded");
           }
        }
        catch (Exception e) {
           org.apache.xindice.Debug.printStackTrace(e);
        }
     }
  
     /**
      * Handles the configuration of ACLs for a collection instance.
      */
     protected void handleCollection(String base, Configuration config)
           throws ReadOnlyException {
        if (config != null) {
           final String resourceName = base + config.getAttribute(NAME) + "/";
  
           Configuration child = config.getChild(PERMISSIONS, true);
           if (child != null) {
              handleConfig(resourceName, child);
           }
  
           processChildren(resourceName, XMLOBJECTS, XMLOBJECT, config);
  
           child = config.getChild(DOCUMENTS, true);
           if (child != null) {
              processChildren(resourceName, RESOURCES, RESOURCE, child);
              processChildren(resourceName, XMLOBJECTS, XMLOBJECT, child);
           }
  
           Configuration collections = config.getChild(COLLECTIONS);
           if (collections != null) {
              collections.processChildren(COLLECTION,
                 new ConfigurationCallback() {
                    public void process(Configuration cfg) {
                       try {
                          String name = resourceName + cfg.getAttribute(NAME) + "/";
                          handleCollection(resourceName, cfg);
                       }
                       catch (ReadOnlyException e) {
                          org.apache.xindice.Debug.printStackTrace(e);
                       }
                    }
              });
           }
        }
     }
  
     protected void processChildren(final String resourceName, String childContainer,
           final String child, Configuration config) throws ReadOnlyException {
  
        Configuration container = config.getChild(childContainer, true);
        if (container != null) {
           container.processChildren(child,
              new ConfigurationCallback() {
                 public void process(Configuration cfg) {
                    try {
                       String name = resourceName + cfg.getAttribute(NAME) + "/";
                       handleConfig(name, cfg.getChild(PERMISSIONS, true));
                    }
                    catch (ReadOnlyException e) {
                       org.apache.xindice.Debug.printStackTrace(e);
                    }
                 }
           });
        }
     }
  
     protected void handleConfig(String resourceName, Configuration config) {
        if (config != null) {
           try {
              ResourcePermissions perm = new ResourcePermissions(resourceName);
              perm.setConfig(config);
              permissions.put(resourceName, perm);
           }
           catch (NullPointerException e) {
              org.apache.xindice.Debug.println("Name attribute is required for all ACL objects");
           }
        }
     }
  
     /**
      * setConfig sets the configuration information for the Configurable
      * object instance.
      *
      * @param config The configuration Node
      */
     public void setConfig(Configuration config) {
        this.config = config;
     }
  
     /**
      * getConfig retrieves the configuration information for the
      * Configurable object instance.
      *
      * @return The configuration Node
      */
     public Configuration getConfig() {
        return config;
     }
  }
  
  
  
  1.1                  xml-xindice/Xindice/java/src/org/apache/xindice/core/security/PasswordCredentials.java
  
  Index: PasswordCredentials.java
  ===================================================================
  package org.apache.xindice.core.security;
  
  /*
   * The Apache Software License, Version 1.1
   *
   *
   * Copyright (c) 1999 The Apache Software Foundation.  All rights
   * reserved.
   *
   * Redistribution and use in source and binary forms, with or without
   * modification, are permitted provided that the following conditions
   * are met:
   *
   * 1. Redistributions of source code must retain the above copyright
   *    notice, this list of conditions and the following disclaimer.
   *
   * 2. Redistributions in binary form must reproduce the above copyright
   *    notice, this list of conditions and the following disclaimer in
   *    the documentation and/or other materials provided with the
   *    distribution.
   *
   * 3. The end-user documentation included with the redistribution,
   *    if any, must include the following acknowledgment:
   *       "This product includes software developed by the
   *        Apache Software Foundation (http://www.apache.org/)."
   *    Alternately, this acknowledgment may appear in the software itself,
   *    if and wherever such third-party acknowledgments normally appear.
   *
   * 4. The names "Xindice" and "Apache Software Foundation" must
   *    not be used to endorse or promote products derived from this
   *    software without prior written permission. For written
   *    permission, please contact apache@apache.org.
   *
   * 5. Products derived from this software may not be called "Apache",
   *    nor may "Apache" appear in their name, without prior written
   *    permission of the Apache Software Foundation.
   *
   * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
   * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
   * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
   * DISCLAIMED.  IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
   * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
   * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
   * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
   * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
   * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
   * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
   * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
   * SUCH DAMAGE.
   * ====================================================================
   *
   * This software consists of voluntary contributions made by many
   * individuals on behalf of the Apache Software Foundation and was
   * originally based on software copyright (c) 1999-2001, The dbXML
   * Group, L.L.C., http://www.dbxmlgroup.com.  For more
   * information on the Apache Software Foundation, please see
   * <http://www.apache.org/>.
   *
   * $Id: PasswordCredentials.java,v 1.1 2001/12/06 21:00:14 bradford Exp $
   */
  
  import org.apache.xindice.core.*;
  import org.apache.xindice.core.Collection;
  import org.apache.xindice.core.*;
  import org.apache.xindice.core.data.*;
  import org.apache.xindice.util.*;
  
  import java.util.*;
  
  import org.w3c.dom.*;
  /**
   * PasswordCredentials provides a Credentials implementation that uses usernames
   * and passwords stored in the Systemdatabase.
   */
  public class PasswordCredentials implements Credentials {
     private static final String COLLECTION = "system/SysGroups";
     protected boolean isValid = false;
     protected String username = null;
     protected String password = null;
     protected ArrayList groups = null;
     protected Database db = null;
  
     /**
      * Creates a new PasswordCredentials using the username and password provided.
      * The username will be looked up in system/SysUsers and the password will be
      * compared to that stored in the record.
      *
      * @param username The username to authenticate
      * @param password The password used to authenticate the user.
      * @param db The Database instance in effect
      * @exception InvalidPasswordException Thrown when the password provided does
      *            not match for the username.
      * @exception UnknownUserException Thrown when the username can not be found.
      */
     public PasswordCredentials(String username, String password,
           Database db)
           throws InvalidPasswordException, UnknownUserException {
        this.username = username;
        this.password = password;
        this.db = db;
        groups = new ArrayList();
  
        try {
           Collection users = db.getCollection("system/SysUsers");
  
           Document user = null;
           try {
  org.apache.xindice.Debug.println("USER: " + username);
              user = users.getDocument(username);
              if (user == null) {
                 throw new UnknownUserException();
              }
           }
           catch (DBException e) {
              org.apache.xindice.Debug.printStackTrace(e);
           }
  
           // Authenticate the user
           String hash = new MD5().md(password).toString();
           if (!user.getDocumentElement().getAttribute("password").equals(hash)) {
              throw new InvalidPasswordException();
           }
  
           // Retrieve a list of all groups that this user is a member of
           Collection groupsCol = db.getCollection(COLLECTION);
           NodeSet results = groupsCol.queryCollection("XPath", "/group/members/member/@name='" +
              username + "'", null);
           if (results != null) {
              while (results.hasMoreNodes()) {
                 Node node = results.getNextNode();
                 String groupName = ((Element)node).getAttribute("name");
                 groups.add(groupName);
              }
           }
        }
        catch (XindiceException e) {
           org.apache.xindice.Debug.printStackTrace(e);
           throw new UnknownUserException();
        }
  
        isValid = true;
     }
  
     /**
      * Verifies that the credentials are valid.
      *
      * @exception InvalidCredentialsException Thrown if the credentials
      *            are not valid.
      */
     public void verify() throws InvalidCredentialsException {
        if ((username == null) || (password == null) || (!isValid)) {
           throw new InvalidCredentialsException();
        }
     }
  
     /**
      * Determines if these credentials have an association with the specified
      * group.
      *
      * @param group The group to check membership of
      * @return true if the group exists false otherwise.
      * @exception AccessDeniedException Thrown when access to the resource is
      *            denied.
      * @exception InvalidCredentialsException Thrown if the provided credentials
      *            are not valid.
      */
     public boolean checkGroup(String group) throws AccessDeniedException,
           InvalidCredentialsException {
        return groups.contains(group);
     }
  
     /**
      * Returns the list of groups to which these credentials belong.
      *
      * @return the list of groups
      */
     public ArrayList getGroups() {
        return groups;
     }
  
     /**
      * Returns the username associated with these credentials
      *
      * @return the username
      */
     public String getUsername() {
        return username;
     }
  
     /**
      * Returns the password associated with these credentials
      *
      * @return the password
      */
     public String getPassword() {
        return password;
     }
  }
  
  
  
  1.1                  xml-xindice/Xindice/java/src/org/apache/xindice/core/security/Permission.java
  
  Index: Permission.java
  ===================================================================
  package org.apache.xindice.core.security;
  
  /*
   * The Apache Software License, Version 1.1
   *
   *
   * Copyright (c) 1999 The Apache Software Foundation.  All rights
   * reserved.
   *
   * Redistribution and use in source and binary forms, with or without
   * modification, are permitted provided that the following conditions
   * are met:
   *
   * 1. Redistributions of source code must retain the above copyright
   *    notice, this list of conditions and the following disclaimer.
   *
   * 2. Redistributions in binary form must reproduce the above copyright
   *    notice, this list of conditions and the following disclaimer in
   *    the documentation and/or other materials provided with the
   *    distribution.
   *
   * 3. The end-user documentation included with the redistribution,
   *    if any, must include the following acknowledgment:
   *       "This product includes software developed by the
   *        Apache Software Foundation (http://www.apache.org/)."
   *    Alternately, this acknowledgment may appear in the software itself,
   *    if and wherever such third-party acknowledgments normally appear.
   *
   * 4. The names "Xindice" and "Apache Software Foundation" must
   *    not be used to endorse or promote products derived from this
   *    software without prior written permission. For written
   *    permission, please contact apache@apache.org.
   *
   * 5. Products derived from this software may not be called "Apache",
   *    nor may "Apache" appear in their name, without prior written
   *    permission of the Apache Software Foundation.
   *
   * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
   * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
   * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
   * DISCLAIMED.  IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
   * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
   * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
   * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
   * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
   * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
   * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
   * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
   * SUCH DAMAGE.
   * ====================================================================
   *
   * This software consists of voluntary contributions made by many
   * individuals on behalf of the Apache Software Foundation and was
   * originally based on software copyright (c) 1999-2001, The dbXML
   * Group, L.L.C., http://www.dbxmlgroup.com.  For more
   * information on the Apache Software Foundation, please see
   * <http://www.apache.org/>.
   *
   * $Id: Permission.java,v 1.1 2001/12/06 21:00:14 bradford Exp $
   */
  
  import java.util.*;
  
  /**
   *
   */
  public final class Permission {
     public static final int UNKNOWN = 0;
     public static final int READ = 1;
     public static final int WRITE = 2;
     public static final int DELETE = 3;
     public static final int MODIFY = 4;
     public static final int EXECUTE = 5;
     public static final int ADMIN = 6;
  
     public static final int ALLOW = 100;
     public static final int DENY = 101;
  
     public static final String READ_STR = "read";
     public static final String WRITE_STR = "write";
     public static final String EXECUTE_STR = "execute";
     public static final String MODIFY_STR = "modify";
     public static final String DELETE_STR = "delete";
     public static final String ADMIN_STR = "admin";
  
     /**
      * Maps a type String into a integer type value.
      */
     protected static int mapType(String name) {
        if (name.equalsIgnoreCase(READ_STR))
           return READ;
        else if (name.equalsIgnoreCase(WRITE_STR))
           return WRITE;
        else if (name.equalsIgnoreCase(DELETE_STR))
           return DELETE;
        else if (name.equalsIgnoreCase(MODIFY_STR))
           return MODIFY;
        else if (name.equalsIgnoreCase(EXECUTE_STR))
           return EXECUTE;
        else if (name.equalsIgnoreCase(ADMIN_STR))
           return ADMIN;
        else
           return UNKNOWN;
     }
  }
  
  
  
  1.1                  xml-xindice/Xindice/java/src/org/apache/xindice/core/security/ResourcePermissions.java
  
  Index: ResourcePermissions.java
  ===================================================================
  package org.apache.xindice.core.security;
  
  /*
   * The Apache Software License, Version 1.1
   *
   *
   * Copyright (c) 1999 The Apache Software Foundation.  All rights
   * reserved.
   *
   * Redistribution and use in source and binary forms, with or without
   * modification, are permitted provided that the following conditions
   * are met:
   *
   * 1. Redistributions of source code must retain the above copyright
   *    notice, this list of conditions and the following disclaimer.
   *
   * 2. Redistributions in binary form must reproduce the above copyright
   *    notice, this list of conditions and the following disclaimer in
   *    the documentation and/or other materials provided with the
   *    distribution.
   *
   * 3. The end-user documentation included with the redistribution,
   *    if any, must include the following acknowledgment:
   *       "This product includes software developed by the
   *        Apache Software Foundation (http://www.apache.org/)."
   *    Alternately, this acknowledgment may appear in the software itself,
   *    if and wherever such third-party acknowledgments normally appear.
   *
   * 4. The names "Xindice" and "Apache Software Foundation" must
   *    not be used to endorse or promote products derived from this
   *    software without prior written permission. For written
   *    permission, please contact apache@apache.org.
   *
   * 5. Products derived from this software may not be called "Apache",
   *    nor may "Apache" appear in their name, without prior written
   *    permission of the Apache Software Foundation.
   *
   * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
   * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
   * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
   * DISCLAIMED.  IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
   * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
   * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
   * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
   * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
   * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
   * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
   * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
   * SUCH DAMAGE.
   * ====================================================================
   *
   * This software consists of voluntary contributions made by many
   * individuals on behalf of the Apache Software Foundation and was
   * originally based on software copyright (c) 1999-2001, The dbXML
   * Group, L.L.C., http://www.dbxmlgroup.com.  For more
   * information on the Apache Software Foundation, please see
   * <http://www.apache.org/>.
   *
   * $Id: ResourcePermissions.java,v 1.1 2001/12/06 21:00:14 bradford Exp $
   */
  
  import java.util.*;
  import org.apache.xindice.util.*;
  
  /**
   *
   */
  public class ResourcePermissions implements Configurable {
     private static final String ALLOW = "allow";
     private static final String DENY = "deny";
     private static final String ALL = "all";
  
     protected ArrayList allowRead = null;
     protected ArrayList allowWrite = null;
     protected ArrayList allowExecute = null;
     protected ArrayList allowDelete = null;
     protected ArrayList allowModify = null;
     protected ArrayList allowAdmin = null;
  
     protected ArrayList denyRead = null;
     protected ArrayList denyWrite = null;
     protected ArrayList denyExecute = null;
     protected ArrayList denyDelete = null;
     protected ArrayList denyModify = null;
     protected ArrayList denyAdmin = null;
  
     protected String resource = "";
     protected Configuration config = null;
  
     public ResourcePermissions(String resource) {
        this.resource = resource;
     }
  
     /**
      * Grants the specified group a permission for this resource.
      *
      *    Valid permission types are
      *       Permission.READ
      *       Permission.WRITE
      *       Permission.DELETE
      *       Permission.MODIFY
      *       Permission.EXECUTE
      *       Permission.ADMIN
      *
      * @param type The type of permission to set.
      * @param group The group being given the permission.
      */
     public void addPermissionAllow(int type, String group) {
        switch(type) {
           case Permission.READ:
              allowRead = addPermission(allowRead, group);
              break;
  
           case Permission.WRITE:
              allowWrite = addPermission(allowWrite, group);
              break;
  
           case Permission.DELETE:
              allowDelete = addPermission(allowDelete, group);
              break;
  
           case Permission.MODIFY:
              allowModify = addPermission(allowModify, group);
              break;
  
           case Permission.EXECUTE:
              allowExecute = addPermission(allowExecute, group);
              break;
  
           case Permission.ADMIN:
              allowAdmin = addPermission(allowAdmin, group);
              break;
        }
     }
  
  
     /**
      * Denys the specified group a permission for this resource.
      *
      *    Valid permission types are
      *       Permission.READ
      *       Permission.WRITE
      *       Permission.DELETE
      *       Permission.MODIFY
      *       Permission.EXECUTE
      *       Permission.ADMIN
      *
      * @param type The type of permission to set.
      * @param group The group being denied the permission.
      */
     public void addPermissionDeny(int type, String group) {
        switch(type) {
           case Permission.READ:
              denyRead = addPermission(denyRead, group);
              break;
  
           case Permission.WRITE:
              denyWrite = addPermission(denyWrite, group);
              break;
  
           case Permission.DELETE:
              denyDelete = addPermission(denyDelete, group);
              break;
  
           case Permission.MODIFY:
              denyModify = addPermission(denyModify, group);
              break;
  
           case Permission.EXECUTE:
              denyExecute = addPermission(denyExecute, group);
              break;
  
           case Permission.ADMIN:
              denyAdmin = addPermission(denyAdmin, group);
              break;
        }
     }
  
     protected ArrayList addPermission(ArrayList list, String group) {
        if (list == null) {
           list = new ArrayList();
        }
  
        list.add(group);
        return list;
     }
  
     /**
      * Checks whether the specified group has type permission to access this
      * resource.
      *
      *    Valid permission types are
      *       Permission.READ
      *       Permission.WRITE
      *       Permission.DELETE
      *       Permission.MODIFY
      *       Permission.EXECUTE
      *       Permission.ADMIN
      *
      * @param type The type of permission to check.
      * @param group The group requested permission.
      */
     public boolean checkPermission(int access, int type, String group) {
        if (access == Permission.ALLOW) {
           switch(type) {
              case Permission.READ:
                 return checkPermission(allowRead, group);
  
              case Permission.WRITE:
                 return checkPermission(allowWrite, group);
  
              case Permission.DELETE:
                 return checkPermission(allowDelete, group);
  
              case Permission.MODIFY:
                 return checkPermission(allowModify, group);
  
              case Permission.EXECUTE:
                 return checkPermission(allowExecute, group);
  
              case Permission.ADMIN:
                 return checkPermission(allowAdmin, group);
           }
        }
        else if (access == Permission.DENY) {
           switch(type) {
              case Permission.READ:
                 return checkPermission(denyRead, group);
  
              case Permission.WRITE:
                 return checkPermission(denyWrite, group);
  
              case Permission.DELETE:
                 return checkPermission(denyDelete, group);
  
              case Permission.MODIFY:
                 return checkPermission(denyModify, group);
  
              case Permission.EXECUTE:
                 return checkPermission(denyExecute, group);
  
              case Permission.ADMIN:
                 return checkPermission(denyAdmin, group);
           }
        }
  
        return false;
     }
  
     protected boolean checkPermission(ArrayList list, String group) {
        if (list != null) {
           if (list.indexOf(group) != -1) {
              return true;
           }
        }
  
        return false;
     }
  
  
  
     /**
      * setConfig sets the configuration information for the Configurable
      * object instance.
      *
      * @param config The configuration Node
      */
     public void setConfig(Configuration config) {
        this.config = config;
        config.processChildren(ALLOW,
           new ConfigurationCallback() {
              public void process(Configuration cfg) {
                 String type = cfg.getAttribute("type", "");
                 String group = cfg.getAttribute("group", "");
  
                 // If we have a type of all then all user level perms for
                 // this group should be granted.
                 if (type.equalsIgnoreCase(ALL)) {
                    addPermissionAllow(Permission.READ, group);
                    addPermissionAllow(Permission.WRITE, group);
                    addPermissionAllow(Permission.DELETE, group);
                    addPermissionAllow(Permission.EXECUTE, group);
                    addPermissionAllow(Permission.MODIFY, group);
                 }
                 else {
                    addPermissionAllow(Permission.mapType(type), group);
                 }
              }
        });
  
        config.processChildren(DENY,
           new ConfigurationCallback() {
              public void process(Configuration cfg) {
                 String type = cfg.getAttribute("type", "");
                 String group = cfg.getAttribute("group", "");
  
                 // If we have a type of all then all user level perms for
                 // this group should be granted.
                 if (type.equalsIgnoreCase(ALL)) {
                    addPermissionDeny(Permission.READ, group);
                    addPermissionDeny(Permission.WRITE, group);
                    addPermissionDeny(Permission.DELETE, group);
                    addPermissionDeny(Permission.EXECUTE, group);
                    addPermissionDeny(Permission.MODIFY, group);
                 }
                 else {
                    addPermissionDeny(Permission.mapType(type), group);
                 }
              }
        });
     }
  
     /**
      * getConfig retrieves the configuration information for the
      * Configurable object instance.
      *
      * @return The configuration Node
      */
     public Configuration getConfig() {
        return config;
     }
  }
  
  
  
  1.1                  xml-xindice/Xindice/java/src/org/apache/xindice/core/security/SecurityException.java
  
  Index: SecurityException.java
  ===================================================================
  package org.apache.xindice.core.security;
  
  /*
   * The Apache Software License, Version 1.1
   *
   *
   * Copyright (c) 1999 The Apache Software Foundation.  All rights
   * reserved.
   *
   * Redistribution and use in source and binary forms, with or without
   * modification, are permitted provided that the following conditions
   * are met:
   *
   * 1. Redistributions of source code must retain the above copyright
   *    notice, this list of conditions and the following disclaimer.
   *
   * 2. Redistributions in binary form must reproduce the above copyright
   *    notice, this list of conditions and the following disclaimer in
   *    the documentation and/or other materials provided with the
   *    distribution.
   *
   * 3. The end-user documentation included with the redistribution,
   *    if any, must include the following acknowledgment:
   *       "This product includes software developed by the
   *        Apache Software Foundation (http://www.apache.org/)."
   *    Alternately, this acknowledgment may appear in the software itself,
   *    if and wherever such third-party acknowledgments normally appear.
   *
   * 4. The names "Xindice" and "Apache Software Foundation" must
   *    not be used to endorse or promote products derived from this
   *    software without prior written permission. For written
   *    permission, please contact apache@apache.org.
   *
   * 5. Products derived from this software may not be called "Apache",
   *    nor may "Apache" appear in their name, without prior written
   *    permission of the Apache Software Foundation.
   *
   * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
   * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
   * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
   * DISCLAIMED.  IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
   * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
   * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
   * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
   * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
   * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
   * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
   * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
   * SUCH DAMAGE.
   * ====================================================================
   *
   * This software consists of voluntary contributions made by many
   * individuals on behalf of the Apache Software Foundation and was
   * originally based on software copyright (c) 1999-2001, The dbXML
   * Group, L.L.C., http://www.dbxmlgroup.com.  For more
   * information on the Apache Software Foundation, please see
   * <http://www.apache.org/>.
   *
   * $Id: SecurityException.java,v 1.1 2001/12/06 21:00:14 bradford Exp $
   */
  
  import org.apache.xindice.core.*;
  
  /**
   * A SecurityException is thrown if access is denied to a resource within
   * the database.
   */
  
  public class SecurityException extends DBException {
     public SecurityException(int faultCode) {
        super(faultCode);
     }
     
     public SecurityException(int faultCode, String message) {
        super(faultCode, message);
     }
  }
  
  
  
  1.1                  xml-xindice/Xindice/java/src/org/apache/xindice/core/security/UnknownUserException.java
  
  Index: UnknownUserException.java
  ===================================================================
  package org.apache.xindice.core.security;
  
  /*
   * The Apache Software License, Version 1.1
   *
   *
   * Copyright (c) 1999 The Apache Software Foundation.  All rights
   * reserved.
   *
   * Redistribution and use in source and binary forms, with or without
   * modification, are permitted provided that the following conditions
   * are met:
   *
   * 1. Redistributions of source code must retain the above copyright
   *    notice, this list of conditions and the following disclaimer.
   *
   * 2. Redistributions in binary form must reproduce the above copyright
   *    notice, this list of conditions and the following disclaimer in
   *    the documentation and/or other materials provided with the
   *    distribution.
   *
   * 3. The end-user documentation included with the redistribution,
   *    if any, must include the following acknowledgment:
   *       "This product includes software developed by the
   *        Apache Software Foundation (http://www.apache.org/)."
   *    Alternately, this acknowledgment may appear in the software itself,
   *    if and wherever such third-party acknowledgments normally appear.
   *
   * 4. The names "Xindice" and "Apache Software Foundation" must
   *    not be used to endorse or promote products derived from this
   *    software without prior written permission. For written
   *    permission, please contact apache@apache.org.
   *
   * 5. Products derived from this software may not be called "Apache",
   *    nor may "Apache" appear in their name, without prior written
   *    permission of the Apache Software Foundation.
   *
   * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
   * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
   * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
   * DISCLAIMED.  IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
   * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
   * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
   * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
   * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
   * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
   * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
   * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
   * SUCH DAMAGE.
   * ====================================================================
   *
   * This software consists of voluntary contributions made by many
   * individuals on behalf of the Apache Software Foundation and was
   * originally based on software copyright (c) 1999-2001, The dbXML
   * Group, L.L.C., http://www.dbxmlgroup.com.  For more
   * information on the Apache Software Foundation, please see
   * <http://www.apache.org/>.
   *
   * $Id: UnknownUserException.java,v 1.1 2001/12/06 21:00:14 bradford Exp $
   */
  
  import org.apache.xindice.core.*;
  import org.apache.xindice.util.*;
  
  /**
   * A UnknownUserException is thrown if access is denied to a resource within
   * the database.
   */
  
  public class UnknownUserException extends SecurityException {
     public UnknownUserException() {
        super(FaultCodes.SEC_INVALID_USER);
     }
     
     public UnknownUserException(String message) {
        super(FaultCodes.SEC_INVALID_USER, message);
     }
  }
  
  
  
  1.1                  xml-xindice/Xindice/java/src/org/apache/xindice/core/security/package.html
  
  Index: package.html
  ===================================================================
  <html>
    <title>Xindice Security Framework.</title>
    <body>
      <p>Defines several classes for Xindice access control
      and authentication.</p>
   </body>
  </html>
  
  
  
  
  
  1.1                  xml-xindice/Xindice/java/src/org/apache/xindice/core/system/Sequencer.java
  
  Index: Sequencer.java
  ===================================================================
  package org.apache.xindice.core.system;
  
  /*
   * The Apache Software License, Version 1.1
   *
   *
   * Copyright (c) 1999 The Apache Software Foundation.  All rights
   * reserved.
   *
   * Redistribution and use in source and binary forms, with or without
   * modification, are permitted provided that the following conditions
   * are met:
   *
   * 1. Redistributions of source code must retain the above copyright
   *    notice, this list of conditions and the following disclaimer.
   *
   * 2. Redistributions in binary form must reproduce the above copyright
   *    notice, this list of conditions and the following disclaimer in
   *    the documentation and/or other materials provided with the
   *    distribution.
   *
   * 3. The end-user documentation included with the redistribution,
   *    if any, must include the following acknowledgment:
   *       "This product includes software developed by the
   *        Apache Software Foundation (http://www.apache.org/)."
   *    Alternately, this acknowledgment may appear in the software itself,
   *    if and wherever such third-party acknowledgments normally appear.
   *
   * 4. The names "Xindice" and "Apache Software Foundation" must
   *    not be used to endorse or promote products derived from this
   *    software without prior written permission. For written
   *    permission, please contact apache@apache.org.
   *
   * 5. Products derived from this software may not be called "Apache",
   *    nor may "Apache" appear in their name, without prior written
   *    permission of the Apache Software Foundation.
   *
   * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
   * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
   * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
   * DISCLAIMED.  IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
   * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
   * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
   * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
   * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
   * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
   * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
   * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
   * SUCH DAMAGE.
   * ====================================================================
   *
   * This software consists of voluntary contributions made by many
   * individuals on behalf of the Apache Software Foundation and was
   * originally based on software copyright (c) 1999-2001, The dbXML
   * Group, L.L.C., http://www.dbxmlgroup.com.  For more
   * information on the Apache Software Foundation, please see
   * <http://www.apache.org/>.
   *
   * $Id: Sequencer.java,v 1.1 2001/12/06 21:00:15 bradford Exp $
   */
  
  import org.apache.xindice.core.*;
  import org.apache.xindice.core.Collection;
  import org.apache.xindice.core.objects.*;
  import org.apache.xindice.xml.*;
  import org.apache.xindice.xml.dom.*;
  
  import java.util.*;
  
  import org.w3c.dom.*;
  
  /**
   * Sequencer is a system-level sequencer for creating auto-incrementing
   * values.  It operates in a similar fashion to how Interbase performs
   * auto-incrementing.  You use the methods to create and retrieve values
   * from named sequences.  These sequences don't have to be explicitly
   * associated with any particular Collection, which allows them to be
   * shared between Collections, or even Databases and Servers for that
   * matter.
   */
  
  public final class Sequencer extends SimpleXMLObject {
     private static final String PREFIX = "[sequencer]";
     private static final String SEQUENCES = "sequences";
     private static final String SEQUENCE = "sequence";
     private static final String NAME = "name";
     private static final String VALUE = "value";
     
     private Map values = Collections.synchronizedMap(new HashMap());
     private boolean loaded = false;
     private Collection sysObj;
     private String docKey;
     private DocumentImpl doc;
     
     public Sequencer() {
     }
  
     private void checkLoaded() {
        if ( loaded )
           return;
        try {
           sysObj = collection.getSystemCollection().getCollection(SystemCollection.OBJECTS);
           docKey = PREFIX + collection.getCanonicalName();
           doc = (DocumentImpl)sysObj.getDocument(docKey);
           if ( doc != null ) {
              Element e = doc.getDocumentElement();
              NodeList nl = e.getElementsByTagName(SEQUENCE);
              for ( int i = 0; i < nl.getLength(); i++ ) {
                 Element elem = (Element)nl.item(i);
                 String name = elem.getAttribute(NAME);
                 long val = Long.parseLong(elem.getAttribute(VALUE));
                 values.put(name, new SequenceValue(elem, val));
              }
           }
           else {
              doc = new DocumentImpl();
              doc.setSymbols(sysObj.getSymbols());
              doc.appendChild(doc.createElement(SEQUENCES));
           }
           loaded = true;
        }
        catch ( Exception e ) {
           org.apache.xindice.Debug.printStackTrace(e);
        }
     }
     
     public static final String[] PARAMS_create = {"name"};
     public void create(String name) {
        checkLoaded();
        SequenceValue sv = (SequenceValue)values.get(name);
        if ( sv == null ) {
           Element elem = doc.createElement(SEQUENCE);
           elem.setAttribute(NAME, name);
           elem.setAttribute(VALUE, "0");
           doc.getDocumentElement().appendChild(elem);
           values.put(name, new SequenceValue(elem, 0));
           write();
        }
     }
  
     public static final String[] PARAMS_createValue = {"name", "value"};
     public void createValue(String name, long value) {
        checkLoaded();
        SequenceValue sv = (SequenceValue)values.get(name);
        if ( sv == null ) {
           Element elem = doc.createElement(SEQUENCE);
           elem.setAttribute(NAME, name);
           elem.setAttribute(VALUE, Long.toString(value));
           doc.getDocumentElement().appendChild(elem);
           values.put(name, new SequenceValue(elem, value));
           write();
        }
     }
  
     public static final String[] PARAMS_remove = {"name"};
     public void remove(String name) {
        checkLoaded();
        SequenceValue sv = (SequenceValue)values.get(name);
        if ( sv != null ) {
           doc.removeChild(sv.elem);
           values.remove(name);
           write();
        }
     }
  
     public static final String[] PARAMS_reset = {"name", "value"};
     public void reset(String name, long value) {
        checkLoaded();
        SequenceValue sv = (SequenceValue)values.get(name);
        if ( sv != null )
           sv.reset(value);
     }
  
     public static final String[] PARAMS_next = {"name", };
     public long next(String name) {
        checkLoaded();
        SequenceValue sv = (SequenceValue)values.get(name);
        if ( sv != null )
           return sv.next();
        else
           return -1;
     }
  
     private void write() {
        try {
           sysObj.setDocument(docKey, doc);
        }
        catch ( Exception e ) {
           org.apache.xindice.Debug.printStackTrace(e);
        }
     }
  
     
     /**
      * SequenceValue
      */
     private class SequenceValue {
        private Element elem;
        private long value;
        
        public SequenceValue(Element elem) {
           this.elem = elem;
           value = 0;
        }
        
        public SequenceValue(Element elem, long value) {
           this.elem = elem;
           this.value = value;
        }
        
        public synchronized void reset(long value) {
           this.value = value;
           write();
        }
        
        public synchronized long next() {
           value++;
           write();
           return value;
        }
        
        private void write() {
           elem.setAttribute(VALUE, Long.toString(value));
           Sequencer.this.write();
        }
     }
  }
  
  
  
  
  
  1.1                  xml-xindice/Xindice/java/src/org/apache/xindice/core/system/package.html
  
  Index: package.html
  ===================================================================
  <html>
    <title>The Xindice System Package.</title>
    <body>
      <p>This package contains system-level classes and XMLObjects.</p>
   </body>
  </html>
  
  
  
  
  
  1.1                  xml-xindice/Xindice/java/src/org/apache/xindice/core/xupdate/XObjectImpl.java
  
  Index: XObjectImpl.java
  ===================================================================
  package org.apache.xindice.core.xupdate;
  
  /*
   * The Apache Software License, Version 1.1
   *
   *
   * Copyright (c) 1999 The Apache Software Foundation.  All rights
   * reserved.
   *
   * Redistribution and use in source and binary forms, with or without
   * modification, are permitted provided that the following conditions
   * are met:
   *
   * 1. Redistributions of source code must retain the above copyright
   *    notice, this list of conditions and the following disclaimer.
   *
   * 2. Redistributions in binary form must reproduce the above copyright
   *    notice, this list of conditions and the following disclaimer in
   *    the documentation and/or other materials provided with the
   *    distribution.
   *
   * 3. The end-user documentation included with the redistribution,
   *    if any, must include the following acknowledgment:
   *       "This product includes software developed by the
   *        Apache Software Foundation (http://www.apache.org/)."
   *    Alternately, this acknowledgment may appear in the software itself,
   *    if and wherever such third-party acknowledgments normally appear.
   *
   * 4. The names "Xindice" and "Apache Software Foundation" must
   *    not be used to endorse or promote products derived from this
   *    software without prior written permission. For written
   *    permission, please contact apache@apache.org.
   *
   * 5. Products derived from this software may not be called "Apache",
   *    nor may "Apache" appear in their name, without prior written
   *    permission of the Apache Software Foundation.
   *
   * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
   * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
   * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
   * DISCLAIMED.  IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
   * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
   * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
   * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
   * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
   * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
   * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
   * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
   * SUCH DAMAGE.
   * ====================================================================
   *
   * This software consists of voluntary contributions made by many
   * individuals on behalf of the Apache Software Foundation and was
   * originally based on software copyright (c) 1999-2001, The dbXML
   * Group, L.L.C., http://www.dbxmlgroup.com.  For more
   * information on the Apache Software Foundation, please see
   * <http://www.apache.org/>.
   *
   * $Id: XObjectImpl.java,v 1.1 2001/12/06 21:00:15 bradford Exp $
   */
   
  import org.w3c.dom.DocumentFragment;
  import org.w3c.dom.NodeList;
  
  import org.xml.sax.SAXException;
  
  import org.apache.xpath.objects.*;
  
  /**
   * Wrapper for Xalan XObject
   */
  public final class XObjectImpl implements org.infozone.tools.xml.queries.XObject {
  
      private XObject _xobj = null;
      
      /**
       * Creates a new XObject to wrap a Xalan XObject
       *
       * @param xobj xalan's XObject that should be wrapped.
       * @exception IllegalArgumentException If the given XObject was null.
       */
      public XObjectImpl (XObject xobj) throws IllegalArgumentException {
          if (xobj == null)
              throw new IllegalArgumentException ("XalanXObject(): Argument was null!");
          _xobj = xobj;
      }
  
      public int getType() {
          return _xobj.getType();
      }
  
      public boolean bool() throws Exception {
          return _xobj.bool();
      }
  
      public double num() throws Exception {
          return _xobj.num();
      }
  
      public String str() {
          return _xobj.str();
      }
  
      public NodeList nodeset() throws Exception {
          return (NodeList) _xobj.nodeset();
      }
  
      public DocumentFragment rtree() {
          return _xobj.rtree();
      }
  }
  
  
  
  1.1                  xml-xindice/Xindice/java/src/org/apache/xindice/core/xupdate/XPathQueryFactoryImpl.java
  
  Index: XPathQueryFactoryImpl.java
  ===================================================================
  package org.apache.xindice.core.xupdate;
  
  /*
   * The Apache Software License, Version 1.1
   *
   *
   * Copyright (c) 1999 The Apache Software Foundation.  All rights
   * reserved.
   *
   * Redistribution and use in source and binary forms, with or without
   * modification, are permitted provided that the following conditions
   * are met:
   *
   * 1. Redistributions of source code must retain the above copyright
   *    notice, this list of conditions and the following disclaimer.
   *
   * 2. Redistributions in binary form must reproduce the above copyright
   *    notice, this list of conditions and the following disclaimer in
   *    the documentation and/or other materials provided with the
   *    distribution.
   *
   * 3. The end-user documentation included with the redistribution,
   *    if any, must include the following acknowledgment:
   *       "This product includes software developed by the
   *        Apache Software Foundation (http://www.apache.org/)."
   *    Alternately, this acknowledgment may appear in the software itself,
   *    if and wherever such third-party acknowledgments normally appear.
   *
   * 4. The names "Xindice" and "Apache Software Foundation" must
   *    not be used to endorse or promote products derived from this
   *    software without prior written permission. For written
   *    permission, please contact apache@apache.org.
   *
   * 5. Products derived from this software may not be called "Apache",
   *    nor may "Apache" appear in their name, without prior written
   *    permission of the Apache Software Foundation.
   *
   * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
   * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
   * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
   * DISCLAIMED.  IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
   * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
   * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
   * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
   * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
   * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
   * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
   * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
   * SUCH DAMAGE.
   * ====================================================================
   *
   * This software consists of voluntary contributions made by many
   * individuals on behalf of the Apache Software Foundation and was
   * originally based on software copyright (c) 1999-2001, The dbXML
   * Group, L.L.C., http://www.dbxmlgroup.com.  For more
   * information on the Apache Software Foundation, please see
   * <http://www.apache.org/>.
   *
   * $Id: XPathQueryFactoryImpl.java,v 1.1 2001/12/06 21:00:15 bradford Exp $
   */
   
  import org.infozone.tools.xml.queries.*;
  
  public final class XPathQueryFactoryImpl extends XPathQueryFactory {
  
      public XPathQueryFactoryImpl() {
      }
  
      public XPathQuery newXPathQuery() throws XPathQueryConfigurationException {
          return new XPathQueryImpl();
      }
  }
  
  
  
  1.1                  xml-xindice/Xindice/java/src/org/apache/xindice/core/xupdate/XPathQueryImpl.java
  
  Index: XPathQueryImpl.java
  ===================================================================
  package org.apache.xindice.core.xupdate;
  
  /*
   * The Apache Software License, Version 1.1
   *
   *
   * Copyright (c) 1999 The Apache Software Foundation.  All rights
   * reserved.
   *
   * Redistribution and use in source and binary forms, with or without
   * modification, are permitted provided that the following conditions
   * are met:
   *
   * 1. Redistributions of source code must retain the above copyright
   *    notice, this list of conditions and the following disclaimer.
   *
   * 2. Redistributions in binary form must reproduce the above copyright
   *    notice, this list of conditions and the following disclaimer in
   *    the documentation and/or other materials provided with the
   *    distribution.
   *
   * 3. The end-user documentation included with the redistribution,
   *    if any, must include the following acknowledgment:
   *       "This product includes software developed by the
   *        Apache Software Foundation (http://www.apache.org/)."
   *    Alternately, this acknowledgment may appear in the software itself,
   *    if and wherever such third-party acknowledgments normally appear.
   *
   * 4. The names "Xindice" and "Apache Software Foundation" must
   *    not be used to endorse or promote products derived from this
   *    software without prior written permission. For written
   *    permission, please contact apache@apache.org.
   *
   * 5. Products derived from this software may not be called "Apache",
   *    nor may "Apache" appear in their name, without prior written
   *    permission of the Apache Software Foundation.
   *
   * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
   * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
   * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
   * DISCLAIMED.  IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
   * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
   * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
   * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
   * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
   * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
   * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
   * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
   * SUCH DAMAGE.
   * ====================================================================
   *
   * This software consists of voluntary contributions made by many
   * individuals on behalf of the Apache Software Foundation and was
   * originally based on software copyright (c) 1999-2001, The dbXML
   * Group, L.L.C., http://www.dbxmlgroup.com.  For more
   * information on the Apache Software Foundation, please see
   * <http://www.apache.org/>.
   *
   * $Id: XPathQueryImpl.java,v 1.1 2001/12/06 21:00:15 bradford Exp $
   */
   
  import org.w3c.dom.*;
  import org.w3c.dom.traversal.NodeFilter;
  
  import org.infozone.tools.xml.queries.*;
  
  import org.apache.xpath.*;
  import org.apache.xml.utils.*;
  
  /**
   * XPath Query Impl to handle Xalan 2 XPath constructs.
   */
  public final class XPathQueryImpl implements XPathQuery {
     
     private String qstring;
     private Node rootNode;
     private Node namespace;
     private NodeFilter filter;
     private XPath xpath;
  
     /**
      * Constructor for the XPathQueryImpl object
      */
     public XPathQueryImpl() {
     }
  
     /**
      * Sets the QString attribute of the XPathQueryImpl object
      *
      * @param qstring The new QString value
      * @exception Exception Description of Exception
      */
     public void setQString(String qstring) throws Exception {
        this.qstring = qstring;
     }
  
     /**
      * Sets the Namespace attribute of the XPathQueryImpl object
      *
      * @param namespace The new Namespace value
      * @exception Exception Description of Exception
      */
     public void setNamespace(Node namespace) throws Exception {
        this.namespace = namespace;
     }
  
     /**
      * Sets the NodeFilter attribute of the XPathQueryImpl object
      *
      * @param filter The new NodeFilter value
      * @exception Exception Description of Exception
      */
     public void setNodeFilter(NodeFilter filter) throws Exception {
        this.filter = filter;
     }
  
     /**
      * Execute the xpath.
      *
      * @param rootNode The node from which the query should start or null.
      * @return The XObject insulating the query result.
      * @exception Exception
      */
     public XObject execute(Node rootNode) throws Exception {
        if (rootNode.getNodeType() == Node.DOCUMENT_NODE) {
           rootNode = ((Document) rootNode).getDocumentElement();
        }
  
        this.rootNode = rootNode;
  
        // Since we don't have a XML Parser involved here, install some default
        // support for things like namespaces, etc.
        XPathContext xpathSupport = new XPathContext();
        
        PrefixResolver prefixResolver = null;
        // Create an object to resolve namespace prefixes.
        if (namespace != null) {
           if (namespace.getNodeType() == Node.DOCUMENT_NODE) {
              namespace = ((Document) namespace).getDocumentElement();
           }
           
           prefixResolver = new PrefixResolverDefault(namespace);
        }
        else {
           prefixResolver = new PrefixResolverDefault(rootNode);
        }
        
        // Create the XPath object.
        xpath = new XPath(qstring, null, prefixResolver, XPath.SELECT, null);
        
        // execute the XPath query on the specified root node
        return new XObjectImpl(xpath.execute(xpathSupport, rootNode, prefixResolver));
     }
  }
  
  
  
  
  1.1                  xml-xindice/Xindice/java/src/org/apache/xindice/core/xupdate/XUpdateImpl.java
  
  Index: XUpdateImpl.java
  ===================================================================
  package org.apache.xindice.core.xupdate;
  
  /*
   * The Apache Software License, Version 1.1
   *
   *
   * Copyright (c) 1999 The Apache Software Foundation.  All rights
   * reserved.
   *
   * Redistribution and use in source and binary forms, with or without
   * modification, are permitted provided that the following conditions
   * are met:
   *
   * 1. Redistributions of source code must retain the above copyright
   *    notice, this list of conditions and the following disclaimer.
   *
   * 2. Redistributions in binary form must reproduce the above copyright
   *    notice, this list of conditions and the following disclaimer in
   *    the documentation and/or other materials provided with the
   *    distribution.
   *
   * 3. The end-user documentation included with the redistribution,
   *    if any, must include the following acknowledgment:
   *       "This product includes software developed by the
   *        Apache Software Foundation (http://www.apache.org/)."
   *    Alternately, this acknowledgment may appear in the software itself,
   *    if and wherever such third-party acknowledgments normally appear.
   *
   * 4. The names "Xindice" and "Apache Software Foundation" must
   *    not be used to endorse or promote products derived from this
   *    software without prior written permission. For written
   *    permission, please contact apache@apache.org.
   *
   * 5. Products derived from this software may not be called "Apache",
   *    nor may "Apache" appear in their name, without prior written
   *    permission of the Apache Software Foundation.
   *
   * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
   * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
   * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
   * DISCLAIMED.  IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
   * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
   * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
   * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
   * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
   * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
   * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
   * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
   * SUCH DAMAGE.
   * ====================================================================
   *
   * This software consists of voluntary contributions made by many
   * individuals on behalf of the Apache Software Foundation and was
   * originally based on software copyright (c) 1999-2001, The dbXML
   * Group, L.L.C., http://www.dbxmlgroup.com.  For more
   * information on the Apache Software Foundation, please see
   * <http://www.apache.org/>.
   *
   * $Id: XUpdateImpl.java,v 1.1 2001/12/06 21:00:15 bradford Exp $
   */
  
  import org.apache.xindice.core.Collection;
  import org.apache.xindice.core.data.*;
  import org.apache.xindice.xml.dom.*;
  import org.apache.xindice.xml.*;
  
  import org.infozone.lexus.commands.*;
  import org.infozone.lexus.*;
  
  import java.util.*;
  
  import org.w3c.dom.*;
  
  /**
   * Provides Collection and document based XUpdate capabilities.
   *
   * For more detail about XUpdate look at the
   * <a href="http://www.xmldb.org/xupdate/xupdate-wd.html">XUpdate Working Draft</a>.
   */
  public class XUpdateImpl extends XUpdateQueryImpl {
     protected int nodesModified = 0;
     
     /**
      * Execute the XUpdate commands against a document.
      */
     public void execute(Node contextNode) throws Exception {
        CommandObject currentCommand = new DefaultCommand(contextNode);
        Enumeration commands = _query[0].elements();
        Enumeration attributes = _query[1].elements();
        Enumeration characters = _query[2].elements();
        Node origNode = contextNode;
  
        while (commands.hasMoreElements()) {
           int id = ((Integer) commands.nextElement()).intValue();
  
           if ( id == _commands.ATTRIBUTES ) {
              currentCommand.submitAttributes((Hashtable) attributes.nextElement());
           }
           else if ( id == _commands.CHARACTERS ) {
              currentCommand.submitCharacters((String) characters.nextElement());
           }
           else if ( id > 0 ) {
              if ( ! currentCommand.submitInstruction(id) ) {
                 _commands.setContextNode(contextNode);
                 currentCommand = _commands.commandForID(id);
                 if (currentCommand == null) {
                    throw new Exception("operation can not have any XUpdate-instruction !");
                 }
                 currentCommand.reset();
              }
           }
           else {
              if ( ! currentCommand.executeInstruction() ) {
                 contextNode = currentCommand.execute();
                 currentCommand = new DefaultCommand(contextNode);
              }
           }
        }
  
        if ( origNode instanceof CompressedNode ) {
           CompressedNode cn = (CompressedNode)origNode;
           if ( cn.isDirty() )
              nodesModified++;
        }
     }
  
     /**
      * Execute the set of XUpdate commands against a collection.
      *
      * @param contextNode Description of Parameter
      * @exception Exception Description of Exception
      */
     public void execute(Collection col) throws Exception {
  
        int attribIndex = 0;
        for (int i = 0; i < _query[0].size(); i++) {
           int cmdID = ((Integer) _query[0].elementAt(i)).intValue();
  
           if ( cmdID == _commands.ATTRIBUTES ) {
              Hashtable attribs = (Hashtable) _query[1].elementAt(attribIndex);
              attribIndex++;
              String selector = (String) attribs.get("select");
  
              // If we found an XPath selector we need to execute the commands.
              if (selector != null) {
                 NodeSet ns = col.queryCollection("XPath", selector, null);
                 Document lastDoc = null;
                 while (ns != null && ns.hasMoreNodes()) {
                    DBNode node = (DBNode)ns.getNextNode();
                    Document doc = node.getOwnerDocument();
                    
                    if ( doc == lastDoc )
                       continue; // We only have to process it once
                    else
                       lastDoc = doc;
                    
                    NodeSource source = node.getSource();
  
                    Node contextNode = doc.getDocumentElement();
                    execute(contextNode);
  
                    col.setDocument(source.getKey(), doc);
                 }
              }
           }
        }
     }
     
     public int getModifiedCount() {
        return nodesModified;
     }
  }
  
  
  
  
  1.1                  xml-xindice/Xindice/java/src/org/apache/xindice/core/xupdate/XUpdateQueryResolver.java
  
  Index: XUpdateQueryResolver.java
  ===================================================================
  package org.apache.xindice.core.xupdate;
  
  /*
   * The Apache Software License, Version 1.1
   *
   *
   * Copyright (c) 1999 The Apache Software Foundation.  All rights
   * reserved.
   *
   * Redistribution and use in source and binary forms, with or without
   * modification, are permitted provided that the following conditions
   * are met:
   *
   * 1. Redistributions of source code must retain the above copyright
   *    notice, this list of conditions and the following disclaimer.
   *
   * 2. Redistributions in binary form must reproduce the above copyright
   *    notice, this list of conditions and the following disclaimer in
   *    the documentation and/or other materials provided with the
   *    distribution.
   *
   * 3. The end-user documentation included with the redistribution,
   *    if any, must include the following acknowledgment:
   *       "This product includes software developed by the
   *        Apache Software Foundation (http://www.apache.org/)."
   *    Alternately, this acknowledgment may appear in the software itself,
   *    if and wherever such third-party acknowledgments normally appear.
   *
   * 4. The names "Xindice" and "Apache Software Foundation" must
   *    not be used to endorse or promote products derived from this
   *    software without prior written permission. For written
   *    permission, please contact apache@apache.org.
   *
   * 5. Products derived from this software may not be called "Apache",
   *    nor may "Apache" appear in their name, without prior written
   *    permission of the Apache Software Foundation.
   *
   * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
   * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
   * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
   * DISCLAIMED.  IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
   * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
   * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
   * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
   * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
   * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
   * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
   * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
   * SUCH DAMAGE.
   * ====================================================================
   *
   * This software consists of voluntary contributions made by many
   * individuals on behalf of the Apache Software Foundation and was
   * originally based on software copyright (c) 1999-2001, The dbXML
   * Group, L.L.C., http://www.dbxmlgroup.com.  For more
   * information on the Apache Software Foundation, please see
   * <http://www.apache.org/>.
   *
   * $Id: XUpdateQueryResolver.java,v 1.1 2001/12/06 21:00:15 bradford Exp $
   */
  
  import org.apache.xindice.core.*;
  import org.apache.xindice.core.data.*;
  import org.apache.xindice.core.query.*;
  import org.apache.xindice.core.xupdate.*;
  import org.apache.xindice.util.*;
  
  import org.apache.xindice.xml.*;
  import org.apache.xindice.xml.dom.*;
  
  import org.w3c.dom.*;
  
  /**
   * XUpdateQueryResolver
   */
  
  public final class XUpdateQueryResolver extends SimpleConfigurable implements QueryResolver {
     private static final String XUPDATE_XPATH_PROP = "org.infozone.tools.xml.queries.XPathQueryFactory";
     private static final String XUPDATE_XPATH_IMPL = "org.apache.xindice.core.xupdate.XPathQueryFactoryImpl";
     static {
        System.setProperty (XUPDATE_XPATH_PROP, XUPDATE_XPATH_IMPL);
     }
  
     public static final String STYLE_XUPDATE = "XUpdate";
  
     private QueryEngine engine;
  
     public void setConfig(Configuration config) throws XindiceException {
        super.setConfig(config);
     }
  
     public String getQueryStyle() {
        return STYLE_XUPDATE;
     }
  
     public void setQueryEngine(QueryEngine engine) {
        this.engine = engine;
     }
  
     public Query compileQuery(Collection context, String query, NamespaceMap nsMap, Key[] keys) throws QueryException {
        return new XUpdateQuery(context, query, nsMap, keys);
     }
     
     public NodeSet query(Collection context, String query, NamespaceMap nsMap, Key[] keys) throws QueryException {
        XUpdateQuery xq = new XUpdateQuery(context, query, nsMap, keys);
        return xq.execute();
     }
     
  
     /**
      * XUpdateQuery
      */
  
     private class XUpdateQuery implements Query {
        public Collection context;
        public String query;
        public NamespaceMap nsMap;
        public XUpdateImpl xu;
        public Key[] keys;
  
        public XUpdateQuery(Collection context, String query, NamespaceMap nsMap, Key[] keys) throws QueryException {
           this.context = context;
           this.query = query;
           this.nsMap = nsMap;
           this.keys = keys;
  
           try {
              xu = new XUpdateImpl();
              xu.setQString(query);
           }
           catch ( Exception e ) {
              throw new CompilationException("Error Compiling XUpdate Query");
           }
        }
  
        public String getQueryStyle() {
           return STYLE_XUPDATE;
        }
  
        public Collection getQueryContext() {
           return context;
        }
        
        public String getQueryString() {
           return query;
        }
        
        public NamespaceMap getNamespaceMap() {
           return nsMap;
        }
        
        public Key[] getKeySet() {
           return keys;
        }
  
        public NodeSet execute() throws QueryException {
           try {
              if ( keys != null ) {
                 try {
                    for ( int i = 0; i < keys.length; i++ ) {
                       Document doc = context.getDocument(keys[i]);
                       xu.execute(doc.getDocumentElement());
                       context.setDocument(keys[i], doc);
                    }
                 }
                 catch ( Exception e ) {
                    org.apache.xindice.Debug.printStackTrace(e);
                 }
              }
              else
                 xu.execute(context);
              
              DocumentImpl doc = new DocumentImpl();
              Element elem = doc.createElementNS(NodeSource.SOURCE_NS, "src:"+NodeSource.SOURCE_MODIFIED);
              elem.setAttribute(NodeImpl.XMLNS_PREFIX+":src", NodeSource.SOURCE_NS);
              doc.appendChild(elem);
              Text count = doc.createTextNode(Integer.toString(xu.getModifiedCount()));
              elem.appendChild(count);
              
              return new NodeListSet(doc.getChildNodes());
           }
           catch ( Exception e ) {
              throw new ProcessingException("Error executing XUpdate query");
           }
        }
     }
  }
  
  
  
  
  1.1                  xml-xindice/Xindice/java/src/org/apache/xindice/core/xupdate/package.html
  
  Index: package.html
  ===================================================================
  <html>
    <title>Xindice XUpdate Implementation.</title>
    <body>
      <p>Defines several classes for Xindice XUpdate query
      processing.</p>
   </body>
  </html>