kevinross    2003/07/09 09:35:13

  Modified:    java/tests/src/org/apache/xindice/client/xmldb
                        DatabaseImplTest.java
               src/documentation/content/xdocs/dev guide-internals.xml
               java/src/org/apache/xindice/core Database.java
               java/src/org/apache/xindice/client/xmldb DatabaseImpl.java
               java/src/org/apache/xindice/client/xmldb/embed
                        DatabaseImpl.java
  Added:       java/src/org/apache/xindice/server ManagedServer.java
               java/tests/src/org/apache/xindice
                        IntegrationManagedTests.java
               java/src/org/apache/xindice/client/xmldb/managed
                        ManagedDatabaseImpl.java
  Log:
  PR: 21402
  Patch Submitted by: Kevin O'Neill ([EMAIL PROTECTED])
  Reviewed by: Kevin Ross
  
  Added a new driver whos database instance is managed externally.
  Unlike the embeded driver if the database is not available the driver will
  fail to load. It's designed specifically for use in environments where there 
an
  external process is managing the lifecycle of the database.
  
  The patch also includes some updates to database to prevent a registration
  race condition (outlined in an earlier email). This has some flow on effects 
in
  the embeded driver.
  
  Revision  Changes    Path
  1.1                  
xml-xindice/java/src/org/apache/xindice/server/ManagedServer.java
  
  Index: ManagedServer.java
  ===================================================================
  /*
   * The Apache Software License, Version 1.1
   *
   *
   * Copyright (c) 2003 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 [EMAIL PROTECTED]
   *
   * 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: ManagedServer.java,v 1.1 2003/07/09 16:35:11 kevinross Exp $
   */
  
  package org.apache.xindice.server;
  
  import java.io.File;
  import java.io.FileInputStream;
  import java.io.FileNotFoundException;
  
  import org.apache.commons.logging.Log;
  import org.apache.commons.logging.LogFactory;
  import org.apache.xindice.core.Database;
  import org.apache.xindice.util.Configuration;
  import org.apache.xindice.util.ReadOnlyException;
  import org.apache.xindice.util.XindiceException;
  import org.apache.xindice.xml.dom.DOMParser;
  
  /**
   * Creates an registers a database instance for use of the managed driver. 
This class
   * may be used to create the database the managed driver uses (as is the case 
in the test
   * cases) but it is not required. Any method may be used to create the 
database instance
   * that the managed driver talks to. As long as the instance name exists when 
the driver
   * fires up all will be good.
   *
   * @author <a href="mailto:[EMAIL PROTECTED]">Kevin O'Neill</a> 
   * 
   * @version $Revision: 1.1 $ - $Date: 2003/07/09 16:35:11 $
   */
  public class ManagedServer {
        protected Log _log = LogFactory.getLog(getClass());
        protected Database _db = null;
        protected boolean _running = false;
  
        public synchronized void start() throws Exception {
                if (!_running) {
                        configure();
                        _running = true;
                }
                else {
                        _log.warn("Start called on a running server, ignored");
                }
        }
  
        public void stop() throws Exception {
                if (_running) {
                        _db.close();
                        _db = null;
                }
                else {
                        _log.warn("Stop called on a stopped server, ignored");
                }
        }
  
        public void configure() throws FileNotFoundException, XindiceException {
                _db = Database.getDatabase(loadConfiguration());
  
                if (null == _db) {
                        _log.fatal("Unable to configure database");
  
                        throw new XindiceException("Unable to configure 
database");
                }
                else if (_log.isInfoEnabled()) {
                        _log.info("Database name: '" + _db.getName() + "'");
                }
        }
  
        protected Configuration loadConfiguration() throws 
FileNotFoundException, XindiceException, ReadOnlyException {
                Configuration config;
                String configFile = 
System.getProperty(Xindice.PROP_XINDICE_CONFIGURATION);
                if (configFile != null && !configFile.equals("")) {
                        if (_log.isInfoEnabled()) {
                                _log.info("Specified configuration file: '" + 
configFile + "'");
                        }
                        FileInputStream configXMLFile = new FileInputStream(new 
File(configFile));
  
                        config = new 
Configuration(DOMParser.toDocument(configXMLFile), false);
                }
                else {
                        if (_log.isInfoEnabled()) {
                                _log.info("No configuration file specified, 
going with the default configuration");
                        }
                        config = new 
Configuration(DOMParser.toDocument(Xindice.DEFAULT_CONFIGURATION), false);
                }
  
                config = config.getChild("root-collection", false);
                return config;
        }
  }
  
  
  
  1.3       +3 -3      
xml-xindice/java/tests/src/org/apache/xindice/client/xmldb/DatabaseImplTest.java
  
  Index: DatabaseImplTest.java
  ===================================================================
  RCS file: 
/home/cvs/xml-xindice/java/tests/src/org/apache/xindice/client/xmldb/DatabaseImplTest.java,v
  retrieving revision 1.2
  retrieving revision 1.3
  diff -u -r1.2 -r1.3
  --- DatabaseImplTest.java     28 Oct 2002 08:39:19 -0000      1.2
  +++ DatabaseImplTest.java     9 Jul 2003 16:35:11 -0000       1.3
  @@ -77,7 +77,7 @@
   
      public void testGetName()
            throws Exception {
  -      assertEquals("xindice, xindice-embed", db.getName());
  +      assertEquals("xindice, xindice-embed, xindice-managed", db.getName());
      }
   
      public void testAcceptXmlRpcURI()
  
  
  
  1.12      +30 -1     
xml-xindice/src/documentation/content/xdocs/dev/guide-internals.xml
  
  Index: guide-internals.xml
  ===================================================================
  RCS file: 
/home/cvs/xml-xindice/src/documentation/content/xdocs/dev/guide-internals.xml,v
  retrieving revision 1.11
  retrieving revision 1.12
  diff -u -r1.11 -r1.12
  --- guide-internals.xml       27 Dec 2002 17:23:02 -0000      1.11
  +++ guide-internals.xml       9 Jul 2003 16:35:11 -0000       1.12
  @@ -8,6 +8,7 @@
           <title>Xindice internals</title>
           <authors>
               <person id="jb" name="James Bates" email="[EMAIL PROTECTED]"/>
  +            <person id="kao" name="Kevin O'Neill" email="[EMAIL PROTECTED]"/>
           </authors>
           <notice/>
           <abstract>
  @@ -934,6 +935,34 @@
               <section>
                   <title>7.2. XML-RPC driver</title>
               </section>
  +                             <section>
  +                                     <title>7.3. Managed driver</title>
  +                                     <p>The Managed driver 
(<code>xindice-managed</code>) is designed for use in environments where the
  +                                     life cycle of the xindice database is 
controlled by an external service. Like the Embeded driver accesses
  +                                     a database running in the local vm. 
Unlike the Embeded driver the Manged driver will <strong>not</strong>
  +                                     create the database instance. It will 
fail to load if the database instance is not available</p>
  +                                     <section>
  +                                             <title>7.3.1. 
Configuraton</title>
  +                                             <p>Configuration of the driver 
is easy, create an instance of the class. There are two constructors provided,
  +                                             a "no args" default 
constructure one that takes the name of the database to connect to. The "no 
args" constructor
  +                                             will attempt to connect a 
database with the name of "db" or the value of the "xindice.drivers.managed.db" 
property.
  +                                             When the second constructor is 
used the database name is explicitly passed.</p>                                
         
  +                                     </section>
  +                                     <section>
  +                                             <title>7.3.2. 
ManagedServer</title>
  +                                             <p>ManagedServer is a simple 
class that loads a database for access by the Managed driver. It is by
  +                                             no means the only way to create 
and register a database instance. Configuration is the same as for
  +                                             the embeded driver. This is 
suitable for simple tests and standalone applications, but managed environments
  +                                             should provide their own 
configuration implementations.</p>
  +                                     </section>
  +                                     <section>
  +                                             <title>7.3.3. Advantages of the 
Embeded driver</title>
  +                                             <p>The main advantage is that 
the database has an explicit lifecycle. With the Emdeded driver database 
creation
  +                                             is a side effect of access to 
the client driver. The determination of what lifecycle methods are run when
  +                                             is unclear (for example when is 
the database closed). By making database instantiation an external task
  +                                             to the driver this problem 
disappears.</p>
  +                                     </section>
  +                             </section>
           </section>
   
       </body>
  
  
  
  1.1                  
xml-xindice/java/tests/src/org/apache/xindice/IntegrationManagedTests.java
  
  Index: IntegrationManagedTests.java
  ===================================================================
  /*
   * The Apache Software License, Version 1.1
   *
   *
   * Copyright (c) 2003 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 [EMAIL PROTECTED]
   *
   * 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: IntegrationManagedTests.java,v 1.1 2003/07/09 16:35:12 kevinross Exp $
   */
  package org.apache.xindice;
  
  import org.apache.xindice.integration.IntegrationTests;
  import org.apache.xindice.integration.client.XmlDbClient;
  import org.apache.xindice.integration.client.XmlDbClientSetup;
  import org.apache.xindice.server.ManagedServer;
  
  import org.xmldb.api.DatabaseManager;
  import org.xmldb.api.base.Database;
  
  import junit.framework.Test;
  import junitx.extensions.TestSetup;
  
  /**
   * Runs the Integration test suite using the managed driver.  
   *
   * @author <a href="mailto:[EMAIL PROTECTED]">Kevin O'Neill</a> 
   * @version $Revision: 1.1 $, $Date: 2003/07/09 16:35:12 $
   */
  public class IntegrationManagedTests {
  
        public static Test suite() throws Exception {
  
                return new TestSetup(new 
XmlDbClientSetup(IntegrationTests.testSuite("Managed client integration 
tests"), new XmlDbClient("xmldb:xindice-managed://"))) {
  
                        private Database database;
                        private ManagedServer server;
  
                        public void setUp() throws Exception {
                                server = new ManagedServer();
                                server.start();
  
                                String driver = 
"org.apache.xindice.client.xmldb.DatabaseImpl";
                                Class cls = Class.forName(driver);
  
                                database = (Database) cls.newInstance();
                                DatabaseManager.registerDatabase(database);
                        }
  
                        public void tearDown() throws Exception {
                                if (database != null) {
                                        
DatabaseManager.deregisterDatabase(database);
                                        database = null;
                                }
  
                                server.stop();
                                server = null;
                        }
                };
        }
  }
  
  
  
  1.18      +57 -30    
xml-xindice/java/src/org/apache/xindice/core/Database.java
  
  Index: Database.java
  ===================================================================
  RCS file: 
/home/cvs/xml-xindice/java/src/org/apache/xindice/core/Database.java,v
  retrieving revision 1.17
  retrieving revision 1.18
  diff -u -r1.17 -r1.18
  --- Database.java     27 Dec 2002 18:37:23 -0000      1.17
  +++ Database.java     9 Jul 2003 16:35:12 -0000       1.18
  @@ -88,7 +88,6 @@
      private static final String METADATA = "use-metadata";
      public static final String NAME = "name";
   
  -
      private static Log log = LogFactory.getLog("org.apache.xindice.core");
   
      public static final String PROP_XINDICE_HOME = "xindice.home";
  @@ -110,7 +109,45 @@
      private QueryEngine engine = new QueryEngine(this);
   
      public static Database getDatabase(String name) {
  -      return (Database)databases.get(name);
  +
  +             Database database = (Database) databases.get(name);
  +             if (null == database) {
  +                     // in case it's currently being added (only pay the 
sync hit on a miss)
  +                     synchronized (databases) {
  +                             database = (Database) databases.get(name);
  +                     }
  +             }
  +
  +             return database;
  +     }
  +
  +     public static Database getDatabase(Configuration config) {
  +
  +             String name = config.getAttribute(Database.NAME);
  +
  +             // no name in the config file ... can't the database
  +             if (null == name) {
  +                     log.error("Database configuration didn't contain a 
database name");
  +
  +                     return null;
  +             }
  +
  +             Database database = (Database) databases.get(name);
  +             if (null == database) {
  +                     // in case it's currently being added (only pay the 
sync hit on a miss)
  +                     synchronized (databases) {
  +                             // was it created while we waited?
  +                             database = (Database) databases.get(name);
  +                             if (null == database) {
  +                                     database = new Database();
  +                                     database.setConfig(config);
  +
  +                                     databases.put(database.getName(), 
database);
  +                             }
  +                     }
  +             }
  +
  +             return database;
      }
   
      public static String[] listDatabases() {
  @@ -137,8 +174,7 @@
            Configuration queryCfg = config.getChild(QUERYENGINE);
            if ( queryCfg != null )
               engine.setConfig(queryCfg);
  -      }
  -      catch ( Exception e ) {
  +             } catch (Exception e) {
            if (log.isDebugEnabled()) {
               log.debug("No message", e);
            }
  @@ -149,8 +185,7 @@
   
            try {
               sysCol.init();
  -         }
  -         catch ( XindiceException e ) {
  +                     } catch (XindiceException e) {
               if (log.isDebugEnabled()) {
                  log.debug("No message", e);
               }
  @@ -175,29 +210,25 @@
            }
   
            super.setConfig(new Configuration(colDoc.getDocumentElement(), 
false));
  -      }
  -      catch ( Exception e ) {
  +             } catch (Exception e) {
            if (log.isDebugEnabled()) {
               log.debug("No message", e);
            }
         }
   
         // Register the Database with the VM
  -      databases.put(getName(), this);
  +             // databases.put(getName(), this);
   
         // initialize the meta collection
         // but only if it's turned on in the config.
         String metaCfg = config.getAttribute(METADATA);
  -      if ( metaCfg.equalsIgnoreCase("on") )
  -      {
  +             if (metaCfg.equalsIgnoreCase("on")) {
            metaEnabled = true;
  -         if (!metaInit)
  -         {
  +                     if (!metaInit) {
               metaCol = new MetaSystemCollection(this);
               try {
                  metaCol.init();
  -            }
  -            catch ( XindiceException e ) {
  +                             } catch (XindiceException e) {
                  if (log.isDebugEnabled()) {
                     log.debug("Error initializing the meta collection", e);
                  }
  @@ -234,8 +265,7 @@
       * Return whether or not metadata is enabled on this database.
       * @return boolean
       */
  -   public boolean isMetaEnabled()
  -   {
  +     public boolean isMetaEnabled() {
         return metaEnabled;
      }
   
  @@ -251,8 +281,7 @@
         try {
            Document d = config.getElement().getOwnerDocument();
            sysCol.getCollection(SystemCollection.CONFIGS).setDocument(COLKEY, 
d);
  -      }
  -      catch ( Exception e ) {
  +             } catch (Exception e) {
            if (log.isErrorEnabled()) {
               log.error("Error Writing Configuration '"+name+"', for database 
"+getName(), e);
            }
  @@ -263,7 +292,11 @@
   
      public boolean close() throws DBException {
         flushConfig();
  +
  +             synchronized (databases) {
         databases.remove( getName() );
  +             }
  +
         return true;
      }
   
  @@ -287,15 +320,12 @@
      }
   
      // methods for recording the times when meta data is enabled.
  -   public synchronized void recordTime( String path, long created, long 
modified )
  -   {
  +     public synchronized void recordTime(String path, long created, long 
modified) {
         TimeRecord rec = (TimeRecord)timestamps.get(path);
         if( null == rec ) {
            rec = new TimeRecord(created, modified);
            timestamps.put(path, rec);
  -      }
  -      else
  -      {
  +             } else {
            if( created > 0 )
               rec.setCreatedTime(created);
            if( modified > 0 )
  @@ -303,15 +333,12 @@
         }
      }
   
  -   public synchronized void removeTime( String path )
  -   {
  +     public synchronized void removeTime(String path) {
         timestamps.remove(path);
      }
   
  -   public synchronized TimeRecord getTime( String path )
  -   {
  +     public synchronized TimeRecord getTime(String path) {
         TimeRecord rec = (TimeRecord)timestamps.get(path);
         return rec;
      }
   }
  -
  
  
  
  1.13      +12 -12    
xml-xindice/java/src/org/apache/xindice/client/xmldb/DatabaseImpl.java
  
  Index: DatabaseImpl.java
  ===================================================================
  RCS file: 
/home/cvs/xml-xindice/java/src/org/apache/xindice/client/xmldb/DatabaseImpl.java,v
  retrieving revision 1.12
  retrieving revision 1.13
  diff -u -r1.12 -r1.13
  --- DatabaseImpl.java 30 May 2003 22:39:16 -0000      1.12
  +++ DatabaseImpl.java 9 Jul 2003 16:35:12 -0000       1.13
  @@ -59,13 +59,12 @@
    * $Id$
    */
   
  -import java.lang.reflect.Constructor;
  -
  +import org.apache.commons.logging.Log;
  +import org.apache.commons.logging.LogFactory;
  +import org.apache.xindice.client.xmldb.managed.ManagedDatabaseImpl;
   import org.xmldb.api.base.Database;
   import org.xmldb.api.base.ErrorCodes;
   import org.xmldb.api.base.XMLDBException;
  -import org.apache.commons.logging.Log;
  -import org.apache.commons.logging.LogFactory;
   
   /**
    * DatabaseImpl is the XML:DB driver implementation for Xindice. It is the 
entry
  @@ -94,11 +93,13 @@
       */
      public static String XMLRPC_URI = "xindice://";
      public static String EMBED_URI = "xindice-embed://";
  +     public static String MANAGED_URI = "xindice-managed://";
  +   
   
      /**
       * Name used in the uri for collections associated with this instance.
       */
  -   public static String INSTANCE_NAME = "xindice, xindice-embed";
  +   public static String INSTANCE_NAME = "xindice, xindice-embed, 
xindice-managed";
      
      /**
         * The XML:DB API Core Level Conformance of this implementation.
  @@ -212,14 +213,13 @@
                    * Since the user never sees the actual xmlrpc.DatabaseImpl 
object,
                    * this is the only way to make sure that they can set that 
property.
                    */
  -                Class driverClass
  -                    = 
Class.forName("org.apache.xindice.client.xmldb.xmlrpc.DatabaseImpl");
  -                Constructor constructor = driverClass.getConstructor(
  -                    new Class[]{CommonConfigurable.class});
  -                driver = (Database) constructor.newInstance(new 
Object[]{this});
  +                driver = new 
org.apache.xindice.client.xmldb.xmlrpc.DatabaseImpl(this);
               }
               else if (uri.startsWith(EMBED_URI)) {
  -               driver = (Database) 
Class.forName("org.apache.xindice.client.xmldb.embed.DatabaseImpl").newInstance();
  +               driver = new 
org.apache.xindice.client.xmldb.embed.DatabaseImpl();
  +            }
  +            else if (uri.startsWith(MANAGED_URI)) {
  +             driver = new ManagedDatabaseImpl();     
               }
            }   
         }
  
  
  
  1.1                  
xml-xindice/java/src/org/apache/xindice/client/xmldb/managed/ManagedDatabaseImpl.java
  
  Index: ManagedDatabaseImpl.java
  ===================================================================
  /*
   * The Apache Software License, Version 1.1
   *
   *
   * Copyright (c) 2003 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 [EMAIL PROTECTED]
   *
   * 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: ManagedDatabaseImpl.java,v 1.1 2003/07/09 16:35:12 kevinross Exp $
   */
  package org.apache.xindice.client.xmldb.managed;
  
  import java.io.FileNotFoundException;
  
  import org.apache.commons.logging.Log;
  import org.apache.commons.logging.LogFactory;
  import org.apache.xindice.client.xmldb.CommonConfigurable;
  import org.apache.xindice.client.xmldb.embed.CollectionImpl;
  import org.apache.xindice.core.Database;
  import org.apache.xindice.util.XindiceException;
  import org.xmldb.api.base.Collection;
  import org.xmldb.api.base.ErrorCodes;
  import org.xmldb.api.base.XMLDBException;
  
  /**
   * The xindice-managed is a xindice client driver that requires third party 
code
   * to create the database within the constraints of the client classloader. 
Typically
   * it is used in embebed environments where database creation is managed by 
third party
   * code.
   * 
   * The driver will look for a database with the name passed in the 
constructor. If the no
   * argument constructor is used then the name defaults to 'db' though this 
can be changed
   * by setting [EMAIL PROTECTED] DATABASE_NAME_PROPERTY} property.
   * 
   * This driver will throw an exception if the hasn't been registered.
   *
   * @author <a href="mailto:[EMAIL PROTECTED]">Kevin O'Neill</a> 
   * 
   * @version $Revision: 1.1 $ - $Date: 2003/07/09 16:35:12 $
   */
  public class ManagedDatabaseImpl extends CommonConfigurable implements 
org.xmldb.api.base.Database {
        /* prefix used to denote XML:DB URI's that should use this driver */
        public static final String DRIVER_NAME = "xindice-managed";
        public static final String DATABASE_NAME_PROPERTY = 
"xindice.drivers.managed.db";
  
        /* XML:DB conformance level of this driver */
        public static final String CONFORMANCE_LEVEL = "0";
  
        public ManagedDatabaseImpl() throws FileNotFoundException, 
XindiceException {
                this(System.getProperty(DATABASE_NAME_PROPERTY, "db"));
        }
  
        public ManagedDatabaseImpl(String databaseName) throws 
FileNotFoundException, XindiceException {
  
                this.db = Database.getDatabase(databaseName);
  
                if (null == db) {
                        log.fatal("The database " + databaseName + " has not 
been created.");
  
                        throw new XindiceException("The " + getName() + " 
driver requires that the database instance be created and available in the 
JVM");
                }
        }
  
        private Log log = LogFactory.getLog(getClass());
        protected Database db;
  
        /* (non-Javadoc)
         * @see org.xmldb.api.base.Database#getName()
         */
        public String getName() {
                return DRIVER_NAME;
        }
  
        /**
         * Retrieves a <code>Collection</code> instance based on the URI 
provided
         * in the <code>uri</code> parameter. The format of the URI is defined 
in the
         * documentation for DatabaseManager.getCollection().<p/>
         */
        public Collection getCollection(String uri, String username, String 
password) throws XMLDBException {
                if (!acceptsURI(uri)) {
                        throw new XMLDBException(ErrorCodes.INVALID_URI, 
"Invalid URL: " + uri);
                }
  
                /* Chop off driver prefix, and '://' */
                uri = uri.substring(getName().length() + 3);
  
                /* Extract host name & port, if present */
                int firstSlash = uri.indexOf('/');
                if (firstSlash == -1) {
                        throw new XMLDBException(ErrorCodes.INVALID_URI);
                }
  
                String collPath = uri.substring(firstSlash);
  
                // The path must start with a /
                if (collPath.startsWith("/")) {
                        // find the database name. We just skip the first slash
                        int colIndex = collPath.indexOf('/', 1);
  
                        // We assume there's no collection specified
                        String colName = "/";
  
                        // if colIndex isn't -1 then we need to pick out the db 
and collection
                        if (colIndex != -1) {
                                // The rest of the name locates the collection
                                colName = collPath.substring(colIndex);
  
                                if (colName.equals("")) {
                                        colName = "/";
                                }
                        }
  
                        try {
                                return new CollectionImpl(db, colName);
                        }
                        catch (XMLDBException xmldbe) {
                                if (xmldbe.errorCode == 
ErrorCodes.NO_SUCH_COLLECTION) {
                                        return null;
                                }
                                else {
                                        throw xmldbe;
                                }
                        }
                }
                else {
                        throw new XMLDBException(ErrorCodes.INVALID_URI, 
"Collection name must begin with a '/'");
                }
        }
  
        public boolean acceptsURI(String uri) throws XMLDBException {
                return ((uri != null) && uri.startsWith(getName() + "://"));
        }
  
        public String getConformanceLevel() throws XMLDBException {
                return CONFORMANCE_LEVEL;
        }
  }
  
  
  
  1.9       +24 -34    
xml-xindice/java/src/org/apache/xindice/client/xmldb/embed/DatabaseImpl.java
  
  Index: DatabaseImpl.java
  ===================================================================
  RCS file: 
/home/cvs/xml-xindice/java/src/org/apache/xindice/client/xmldb/embed/DatabaseImpl.java,v
  retrieving revision 1.8
  retrieving revision 1.9
  diff -u -r1.8 -r1.9
  --- DatabaseImpl.java 14 Mar 2003 10:24:18 -0000      1.8
  +++ DatabaseImpl.java 9 Jul 2003 16:35:12 -0000       1.9
  @@ -63,6 +63,7 @@
   import org.apache.xindice.core.Database;
   import org.apache.xindice.server.Xindice;
   import org.apache.xindice.util.Configuration;
  +import org.apache.xindice.util.ReadOnlyException;
   import org.apache.xindice.util.XindiceException;
   import org.apache.xindice.xml.dom.DOMParser;
   
  @@ -107,11 +108,23 @@
       * use the Configurable interface and only create the database when the
       * getCollection method is called.
       */
  -   public DatabaseImpl()
  -         throws FileNotFoundException,
  -         XindiceException {
  +     public DatabaseImpl() throws FileNotFoundException, XindiceException {
         Configuration config;
  +             config = loadConfiguration();
   
  +             this.db = Database.getDatabase(config);
  +
  +             if (null == this.db) {
  +                     log.fatal("Unable to configure database");
  +
  +                     throw new XindiceException("Unable to configure 
database");
  +             } else if (log.isInfoEnabled()) {
  +                     log.info("Database name: '" + this.db.getName() + "'");
  +             }
  +     }
  +
  +     protected Configuration loadConfiguration() throws 
FileNotFoundException, XindiceException, ReadOnlyException {
  +             Configuration config;
         String configFile = 
System.getProperty(Xindice.PROP_XINDICE_CONFIGURATION);
         if (configFile != null && !configFile.equals("")) {
            if (log.isInfoEnabled()) {
  @@ -120,8 +133,7 @@
            FileInputStream configXMLFile = new FileInputStream(new 
File(configFile));
   
            config = new Configuration(DOMParser.toDocument(configXMLFile), 
false);
  -      }
  -      else {
  +             } else {
            if (log.isInfoEnabled()) {
               log.info("No configuration file specified, going with the 
default configuration");
            }
  @@ -129,21 +141,7 @@
         }
   
         config = config.getChild("root-collection", false);
  -
  -      /* First try to find an existing Database by name.  If it doesn't 
exist,
  -       * we create one and in both cases we configure them with the current
  -       * configuration */
  -      String dbname = config.getAttribute(Database.NAME);
  -
  -      this.db = Database.getDatabase(dbname);
  -      if (this.db == null) {
  -         this.db = new Database();
  -      }
  -
  -      if (log.isInfoEnabled()) {
  -         log.info("Database name: '" + dbname + "'");
  -      }
  -      db.setConfig(config);
  +             return config;
      }
   
      /**
  @@ -187,14 +185,11 @@
       *  <code>ErrroCodes.PERMISSION_DENIED</code> If the <code>username</code>
       *    and <code>password</code> were not accepted by the database.
       */
  -    public Collection getCollection(String uri, String userName, String 
password)
  -            throws XMLDBException {
  -                
  +     public Collection getCollection(String uri, String userName, String 
password) throws XMLDBException {
           /* TODO: introduce authentication some day */
                   
           if (!acceptsURI(uri)) {
  -            throw new XMLDBException(ErrorCodes.INVALID_URI, "Invalid URL: "
  -                    + uri);
  +                     throw new XMLDBException(ErrorCodes.INVALID_URI, 
"Invalid URL: " + uri);
           }
   
           /* Chop off driver prefix, and '://' */
  @@ -231,18 +226,15 @@
              
                   try {
              return new CollectionImpl(db, colName);
  -                }
  -                catch(XMLDBException e) {
  +                     } catch (XMLDBException e) {
                 if(e.errorCode == ErrorCodes.NO_SUCH_COLLECTION) {
                    // per getCollection contract, return null if not found
                    return null;
                 }
                          throw e;
                   }
  -        }
  -        else {
  -           throw new XMLDBException(ErrorCodes.INVALID_URI,
  -                                    "Collection name must begin with a '/'" 
);
  +             } else {
  +                     throw new XMLDBException(ErrorCodes.INVALID_URI, 
"Collection name must begin with a '/'");
           }
       }
   
  @@ -256,7 +248,6 @@
       *  specific errors that occur.<br />
       */
       public String getName() throws XMLDBException {
  -
           return DRIVER_NAME;
       }
           
  @@ -271,7 +262,6 @@
       *  specific errors that occur.<br />
       */
       public String getConformanceLevel() throws XMLDBException {
  -
           return CONFORMANCE_LEVEL;
       }
       
  
  
  

Reply via email to