You are viewing a plain text version of this content. The canonical link for it is here.
Posted to ojb-dev@db.apache.org by th...@apache.org on 2004/01/17 17:57:34 UTC

cvs commit: db-ojb build.xml

thma        2004/01/17 08:57:34

  Modified:    src/java/org/apache/ojb/odmg/locking
                        PersistentLockMapImpl.java LockMap.java
                        LockMapFactory.java InMemoryLockMapImpl.java
               src/test/org/apache/ojb OJB.properties
               src/java/org/apache/ojb/broker/util/configuration/impl
                        OjbConfiguration.java
               .        build.xml
  Added:       src/java/org/apache/ojb/odmg/locking LockServerServlet.java
                        RemoteLockMapImpl.java
               src/test/org/apache/ojb web.xml
  Log:
  1st check in of the new Servlet based distributed LockServer.
  It's been junit tested already, and there seem to be no problems!
  
  Revision  Changes    Path
  1.10      +14 -4     db-ojb/src/java/org/apache/ojb/odmg/locking/PersistentLockMapImpl.java
  
  Index: PersistentLockMapImpl.java
  ===================================================================
  RCS file: /home/cvs/db-ojb/src/java/org/apache/ojb/odmg/locking/PersistentLockMapImpl.java,v
  retrieving revision 1.9
  retrieving revision 1.10
  diff -u -r1.9 -r1.10
  --- PersistentLockMapImpl.java	13 Dec 2003 14:34:23 -0000	1.9
  +++ PersistentLockMapImpl.java	17 Jan 2004 16:57:34 -0000	1.10
  @@ -1,7 +1,3 @@
  -/*
  - * Created by: thma
  - * Date: May 4, 2001
  - */
   package org.apache.ojb.odmg.locking;
   
   /* ====================================================================
  @@ -68,11 +64,16 @@
   import org.apache.ojb.broker.query.Criteria;
   import org.apache.ojb.broker.query.Query;
   import org.apache.ojb.broker.query.QueryFactory;
  +import org.apache.ojb.broker.util.configuration.Configuration;
  +import org.apache.ojb.broker.util.configuration.ConfigurationException;
   import org.apache.ojb.broker.util.logging.Logger;
   import org.apache.ojb.broker.util.logging.LoggerFactory;
   import org.apache.ojb.odmg.TransactionImpl;
   import org.apache.ojb.odmg.TxManagerFactory;
   
  +/**
  + * @deprecated Using this class is not safe! Please use the RemoteLockMapImpl instead.
  + */
   public class PersistentLockMapImpl implements LockMap
   {
       private Logger log = LoggerFactory.getLogger(PersistentLockMapImpl.class);
  @@ -345,4 +346,13 @@
               if (log.isDebugEnabled()) log.debug("Removed " + count + " timedout locks");
           }
       }
  +    /* (non-Javadoc)
  +     * @see org.apache.ojb.broker.util.configuration.Configurable#configure(org.apache.ojb.broker.util.configuration.Configuration)
  +     */
  +    public void configure(Configuration pConfig) throws ConfigurationException
  +    {
  +        // noop
  +
  +    }
  +
   }
  
  
  
  1.4       +1 -1      db-ojb/src/java/org/apache/ojb/odmg/locking/LockMap.java
  
  Index: LockMap.java
  ===================================================================
  RCS file: /home/cvs/db-ojb/src/java/org/apache/ojb/odmg/locking/LockMap.java,v
  retrieving revision 1.3
  retrieving revision 1.4
  diff -u -r1.3 -r1.4
  --- LockMap.java	11 Dec 2003 19:16:21 -0000	1.3
  +++ LockMap.java	17 Jan 2004 16:57:34 -0000	1.4
  @@ -1 +1 @@
  -/*

 * Created by: thma

 * Date: May 4, 2001

 */

package org.apache.ojb.odmg.locking;


/* ====================================================================
 * The Apache Software License, Version 1.1
 *
 * Copyright (c) 2001 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 "Apache" and "Apache Software Foundation" and
 *    "Apache ObjectRelationalBridge" 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",
 *    "Apache ObjectRelationalBridge", 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.  For more
 * information on the Apache Software Foundation, please see
 * <http://www.apache.org/>.
 */

import org.apache.ojb.odmg.TransactionImpl;



import java.util.Collection;

public interface LockMap
{
    /**
     * returns the LockEntry for the Writer of object obj.
     * If now writer exists, null is returned.
     */
    public LockEntry getWriter(Object obj);

    /**
     * returns a collection of Reader LockEntries for object obj.
     * If now LockEntries could be found an empty Vector is returned.
     */
    public Collection getReaders(Object obj);

    /**
     * Add a reader lock entry for transaction tx on object obj
     * to the persistent storage.
     */
    public boolean addReader(TransactionImpl tx, Object obj);

    /**
     * remove a reader lock entry for transaction tx on object obj
     * from the persistent storage.
     */
    public void removeReader(TransactionImpl tx, Object obj);

    /**
     * remove a writer lock entry for transaction tx on object obj
     * from the persistent storage.
     */
    public void removeWriter(LockEntry writer);

    /**
     * upgrade a reader lock entry for transaction tx on object obj
     * and write it to the persistent storage.
     */
    public boolean upgradeLock(LockEntry reader);

    /**
     * generate a writer lock entry for transaction tx on object obj
     * and write it to the persistent storage.
     */
    public boolean setWriter(TransactionImpl tx, Object obj);

    /**
     * check if there is a reader lock entry for transaction tx on object obj
     * in the persistent storage.
     */
    public boolean hasReadLock(TransactionImpl tx, Object obj);
}
  \ No newline at end of file
  +/*

 * Created by: thma

 * Date: May 4, 2001

 */

package org.apache.ojb.odmg.locking;


/* ====================================================================
 * The Apache Software License, Version 1.1
 *
 * Copyright (c) 2001 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 "Apache" and "Apache Software Foundation" and
 *    "Apache ObjectRelationalBridge" 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",
 *    "Apache ObjectRelationalBridge", 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.  For more
 * information on the Apache Software Foundation, please see
 * <http://www.apache.org/>.
 */

import org.apache.ojb.broker.util.configuration.Configurable;
import org.apache.ojb.odmg.TransactionImpl;

import java.util.Collection;

public interface LockMap extends Configurable
{
    /**
     * returns the LockEntry for the Writer of object obj.
     * If now writer exists, null is returned.
     */
    public LockEntry getWriter(Object obj);

    /**
     * returns a collection of Reader LockEntries for object obj.
     * If now LockEntries could be found an empty Vector is returned.
     */
    public Collection getReaders(Object obj);

    /**
     * Add a reader lock entry for transaction tx on object obj
     * to the persistent storage.
     */
    public boolean addReader(TransactionImpl tx, Object obj);

    /**
     * remove a reader lock entry for transaction tx on object obj
     * from the persistent storage.
     */
    public void removeReader(TransactionImpl tx, Object obj);

    /**
     * remove a writer lock entry for transaction tx on object obj
     * from the persistent storage.
     */
    public void removeWriter(LockEntry writer);

    /**
     * upgrade a reader lock entry for transaction tx on object obj
     * and write it to the persistent storage.
     */
    public boolean upgradeLock(LockEntry reader);

    /**
     * generate a writer lock entry for transaction tx on object obj
     * and write it to the persistent storage.
     */
    public boolean setWriter(TransactionImpl tx, Object obj);

    /**
     * check if there is a reader lock entry for transaction tx on object obj
     * in the persistent storage.
     */
    public boolean hasReadLock(TransactionImpl tx, Object obj);
}
  \ No newline at end of file
  
  
  
  1.4       +7 -4      db-ojb/src/java/org/apache/ojb/odmg/locking/LockMapFactory.java
  
  Index: LockMapFactory.java
  ===================================================================
  RCS file: /home/cvs/db-ojb/src/java/org/apache/ojb/odmg/locking/LockMapFactory.java,v
  retrieving revision 1.3
  retrieving revision 1.4
  diff -u -r1.3 -r1.4
  --- LockMapFactory.java	30 Sep 2002 16:57:08 -0000	1.3
  +++ LockMapFactory.java	17 Jan 2004 16:57:34 -0000	1.4
  @@ -59,6 +59,7 @@
    */
   
   import org.apache.ojb.broker.PersistenceBrokerFactory;
  +import org.apache.ojb.broker.util.configuration.Configurator;
   
   public class LockMapFactory
   {
  @@ -82,14 +83,16 @@
       {
           try
           {
  -            LockingConfiguration config =
  -                (LockingConfiguration) PersistenceBrokerFactory.getConfigurator().getConfigurationFor(null);
  +        	Configurator configurator = PersistenceBrokerFactory.getConfigurator();
  +            LockingConfiguration config = (LockingConfiguration) configurator.getConfigurationFor(null);
               Class clazz = config.getLockMapClass();
  -            return (LockMap) clazz.newInstance();
  +            LockMap map = (LockMap) clazz.newInstance();
  +            configurator.configure(map);
  +            return map;
           }
           catch (Exception e)
           {
  -            return new PersistentLockMapImpl();
  +            return new InMemoryLockMapImpl();
           }
       }
   
  
  
  
  1.12      +102 -33   db-ojb/src/java/org/apache/ojb/odmg/locking/InMemoryLockMapImpl.java
  
  Index: InMemoryLockMapImpl.java
  ===================================================================
  RCS file: /home/cvs/db-ojb/src/java/org/apache/ojb/odmg/locking/InMemoryLockMapImpl.java,v
  retrieving revision 1.11
  retrieving revision 1.12
  diff -u -r1.11 -r1.12
  --- InMemoryLockMapImpl.java	3 Oct 2003 14:23:49 -0000	1.11
  +++ InMemoryLockMapImpl.java	17 Jan 2004 16:57:34 -0000	1.12
  @@ -56,6 +56,8 @@
   
   import org.apache.ojb.broker.Identity;
   import org.apache.ojb.broker.PersistenceBroker;
  +import org.apache.ojb.broker.util.configuration.Configuration;
  +import org.apache.ojb.broker.util.configuration.ConfigurationException;
   import org.apache.ojb.odmg.TransactionImpl;
   import org.apache.ojb.odmg.TxManagerFactory;
   
  @@ -97,20 +99,25 @@
        */
       public LockEntry getWriter(Object obj)
       {
  -    	checkTimedOutLocks();
  +        PersistenceBroker broker = getBroker();
  +        Identity oid = new Identity(obj, broker); 
  +        return getWriter(oid);
  +    }
  +
  +    public LockEntry getWriter(Identity oid)
  +    {
  +        checkTimedOutLocks();
           /* TODO: smarter solution in future */
           // fix/workaround
           // When Identity needs new id's we must overgive
           // the a target broker when run with multiple databases
           // using H/L sequence manager
  -        PersistenceBroker broker = getBroker();
  -        Identity oid = new Identity(obj, broker);
  -		ObjectLocks objectLocks = null;
  -		synchronized(locktable)
  -		{
  -	        objectLocks = (ObjectLocks) locktable.get(oid.toString());
  -		}
  -		if (objectLocks == null)
  +        ObjectLocks objectLocks = null;
  +        synchronized(locktable)
  +        {
  +            objectLocks = (ObjectLocks) locktable.get(oid.toString());
  +        }
  +        if (objectLocks == null)
           {
               return null;
           }
  @@ -135,9 +142,12 @@
       public Collection getReaders(Object obj)
       {
       	checkTimedOutLocks();
  -
           Identity oid = new Identity(obj,getBroker());
  +        return getReaders(oid);
  +    }
   
  +    public Collection getReaders(Identity oid)
  +    {
           ObjectLocks objectLocks = null;
           synchronized (locktable)
           {
  @@ -168,6 +178,12 @@
                   LockStrategyFactory.getIsolationLevel(obj),
                   LockEntry.LOCK_READ);
   
  +        addReaderInternal(reader);
  +        return true;
  +    }
  +
  +    void addReaderInternal(LockEntry reader)
  +    {
           ObjectLocks objectLocks = null;
           /**
            * MBAIRD: We need to synchronize the get/put so we don't have two threads
  @@ -175,15 +191,15 @@
            */
           synchronized (locktable)
           {
  -        	objectLocks = (ObjectLocks) locktable.get(oid.toString());
  -	        if (objectLocks == null)
  -	        {
  -	            objectLocks = new ObjectLocks();
  -	            locktable.put(oid.toString(), objectLocks);
  -	        }
  +        	String oidString = reader.getOidString();
  +        	objectLocks = (ObjectLocks) locktable.get(oidString);
  +            if (objectLocks == null)
  +            {
  +                objectLocks = new ObjectLocks();
  +                locktable.put(oidString, objectLocks);
  +            }
           }
           objectLocks.addReader(reader);
  -        return true;
       }
   
       /**
  @@ -196,6 +212,12 @@
   
           Identity oid = new Identity(obj, getBroker());
           String oidString = oid.toString();
  +        String txGuid = tx.getGUID();
  +        removeReaderInternal(oidString, txGuid);
  +    }
  +
  +    private void removeReaderInternal(String oidString, String txGuid)
  +    {
           ObjectLocks objectLocks = null;
           synchronized (locktable)
           {
  @@ -215,7 +237,7 @@
           	synchronized (locktable)
           	{
           		Map readers = objectLocks.getReaders();
  -        		readers.remove(tx.getGUID());
  +        		readers.remove(txGuid);
               	if ((objectLocks.getWriter() == null) && (readers.size() == 0))
               	{
               		locktable.remove(oidString);
  @@ -224,6 +246,13 @@
           }
       }
   
  +	void removeReaderByLock(LockEntry lock)
  +	{
  +		String oidString = lock.getOidString();
  +		String txGuid = lock.getTransactionId();
  +		removeReaderInternal(oidString, txGuid);
  +	}
  +	
       /**
        * remove a writer lock entry for transaction tx on object obj
        * from the persistent storage.
  @@ -310,25 +339,36 @@
                   System.currentTimeMillis(),
                   LockStrategyFactory.getIsolationLevel(obj),
                   LockEntry.LOCK_WRITE);
  +        String oidString = oid.toString();
  +        setWriterInternal(writer, oidString);
  +        return true;
  +    }
   
  -		ObjectLocks objectLocks = null;
  +    private void setWriterInternal(LockEntry writer, String oidString)
  +    {
  +        ObjectLocks objectLocks = null;
           /**
            * MBAIRD: We need to synchronize the get/put so we don't have two threads
            * competing to check if something is locked and double-locking it.
            */
  -		synchronized (locktable)
  -		{
  -	        objectLocks = (ObjectLocks) locktable.get(oid.toString());
  -	        if (objectLocks == null)
  -	        {
  -	            objectLocks = new ObjectLocks();
  -	            locktable.put(oid.toString(), objectLocks);
  -	        }
  -		}
  +        synchronized (locktable)
  +        {
  +            objectLocks = (ObjectLocks) locktable.get(oidString);
  +            if (objectLocks == null)
  +            {
  +                objectLocks = new ObjectLocks();
  +                locktable.put(oidString, objectLocks);
  +            }
  +        }
           objectLocks.setWriter(writer);
  -        return true;
       }
   
  +	void setWriterByLock(LockEntry writer)
  +	{
  +		String oidString = writer.getOidString();
  +		setWriterInternal(writer, oidString);
  +	}
  +
       /**
        * check if there is a reader lock entry for transaction tx on object obj
        * in the persistent storage.
  @@ -338,19 +378,26 @@
           checkTimedOutLocks();
   
           Identity oid = new Identity(obj,getBroker());
  +        String oidString = oid.toString();
  +		String txGuid = tx.getGUID();
  +        return hasReadLockInternal(oidString, txGuid);
  +    }
  +
  +    private boolean hasReadLockInternal(String oidString, String txGuid)
  +    {
           ObjectLocks objectLocks = null;
           synchronized (locktable)
           {
  -        	objectLocks = (ObjectLocks) locktable.get(oid.toString());
  +        	objectLocks = (ObjectLocks) locktable.get(oidString);
           }
  -
  +        
           if (objectLocks == null)
           {
               return false;
           }
           else
           {
  -            String txGuid = tx.getGUID();
  +            
               LockEntry reader = objectLocks.getReader(txGuid);
               if (reader != null)
               {
  @@ -363,6 +410,13 @@
           }
       }
   
  +	boolean hasReadLock(LockEntry entry)
  +	{
  +		String oidString = entry.getOidString();
  +		String txGuid = entry.getTransactionId();
  +		return hasReadLockInternal(oidString,txGuid);
  +	}
  +
       private void checkTimedOutLocks()
       {
           if (System.currentTimeMillis() - m_lastCleanupAt > CLEANUP_FREQUENCY)
  @@ -433,4 +487,19 @@
   	        }
       	}
       }
  +    
  +    /* (non-Javadoc)
  +     * @see org.apache.ojb.broker.util.configuration.Configurable#configure(org.apache.ojb.broker.util.configuration.Configuration)
  +     */
  +    public void configure(Configuration pConfig) throws ConfigurationException
  +    {
  +        // noop
  +
  +    }
  +    
  +    int getSize()
  +    {
  +    	return locktable.size();
  +    }
  +
   }
  
  
  
  1.1                  db-ojb/src/java/org/apache/ojb/odmg/locking/LockServerServlet.java
  
  Index: LockServerServlet.java
  ===================================================================
  package org.apache.ojb.odmg.locking;
  
  /* ====================================================================
   * The Apache Software License, Version 1.1
   *
   * Copyright (c) 2001 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 "Apache" and "Apache Software Foundation" and
   *    "Apache ObjectRelationalBridge" 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",
   *    "Apache ObjectRelationalBridge", 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.  For more
   * information on the Apache Software Foundation, please see
   * <http://www.apache.org/>.
   */
  
  
  import java.io.ByteArrayInputStream;
  import java.io.IOException;
  import java.io.InputStream;
  import java.io.ObjectInputStream;
  import java.io.ObjectOutputStream;
  import java.io.PrintWriter;
  import java.util.ArrayList;
  import java.util.Collection;
  
  import javax.servlet.ServletException;
  import javax.servlet.http.HttpServlet;
  import javax.servlet.http.HttpServletRequest;
  import javax.servlet.http.HttpServletResponse;
  
  import org.apache.ojb.broker.Identity;
  import org.apache.ojb.broker.PersistenceBrokerException;
  
  
  /**
   * @author Thomas Mahler
   */
  public class LockServerServlet extends HttpServlet
  {
  	private static int numRequests;
  	
  	private static InMemoryLockMapImpl lockmap = new InMemoryLockMapImpl();
  	
  	private static Throwable lastError = null;
  	
  	
  
      /* (non-Javadoc)
       * @see javax.servlet.http.HttpServlet#doGet(javax.servlet.http.HttpServletRequest, javax.servlet.http.HttpServletResponse)
       */
      protected void doGet(HttpServletRequest request, HttpServletResponse response)
          throws ServletException, IOException
      {
  		 response.setContentType("text/html");
  		 response.setHeader("Pragma", "no-cache");
  
  		 PrintWriter out = response.getWriter();
  
  		 out.println(
  			 "<html><head><title>OJB Distributed Locking Servlet Status Page</title>");
  		 out.println("</head><body><h1>OJB Distributed Locking Servlet</h1>");
  		 out.println("The servlet is running.<p>");
  
  		 if (lastError == null) {
  			 out.println("The LockServer is running.<p>");
  			 out.println("Persistent Locks: " + lockmap.getSize() + "<p>");
  			 out.println("Processed Lock Request: " + numRequests + "<p>");
  		 } else {
  			 out.println("<h2>The LockServer has a problem!</h2>");
  			 out.println("The error message is:<p>");
  			 out.println(lastError.getMessage() + "<p>");
  			 lastError.printStackTrace(out);
  			 lastError = null;
  		 }
  
  		 out.println("</body></html>");
  
      }
  
      /* (non-Javadoc)
       * @see javax.servlet.http.HttpServlet#doPost(javax.servlet.http.HttpServletRequest, javax.servlet.http.HttpServletResponse)
       */
      protected void doPost(HttpServletRequest request, HttpServletResponse response)
          throws ServletException, IOException
      {
      	// update counter
      	numRequests++;
      	    	
          try
          {
              // read request:
              byte[] req = getRequestByteArray(request);
              // first byte contains command selector 
              byte selector = req[0];
              // rest is data
              byte[] data = new byte[req.length -1];
              System.arraycopy(req,1,data,0,data.length);
              
              Object result = null;
              
              // now execute the command specified by the selector
              switch (selector)
              {
              	case 'w' :
              	{
              		result = getWriter(data);
              		break;
              	}
              	case 'r' :
              	{
              		result = getAllReaders(data);
              		break;
              	}
              	case 'a' :
              	{
              		try
                      {
                          result = addReader(data);
                      }
                      catch (Throwable t)
                      {
                          result = new Boolean(false);
                      }
              		break;
              	}
              	case 'e' :
              	{
              		try
              		{
              			result = removeReader(data);
              		}
              		catch (Throwable t)
              		{
              			result = new Boolean(false);    				
              		}
              		break;
              	}
              	case 'm' :
              	{
              		try
              		{
              			result = removeWriter(data);
              		}
              		catch (Throwable t)
              		{
              			result = new Boolean(false);    				
              		}
              		break;
              	}
              	case 'u' :
              	{
              		try
              		{
              			result = upgradeLock(data);
              		}
              		catch (Throwable t)
              		{
              			result = new Boolean(false);    				
              		}
              	}
              	case 's' :
              	{
              		try
              		{
              			result = setWriter(data);
              		}
              		catch (Throwable t)
              		{
              			result = new Boolean(false);    				
              		}
              		break;
              	}
              	case 'h' :
              	{
              		try
              		{
              			result = hasReadLock(data);
              		}
              		catch (Throwable t)
              		{
              			result = new Boolean(false);    				
              		}
              		break;
              	}
              	
              	default :
              	{
              		result = new PersistenceBrokerException("unknown command:" + selector); 		
              	}
              }
              
              ObjectOutputStream oos = new ObjectOutputStream(response.getOutputStream());
              oos.writeObject(result);
              oos.flush();
              oos.close();    
          }
          catch (Throwable t)
          {
              lastError = t;
              System.err.println(t.getMessage());
              t.printStackTrace(System.err);
          }
          
      }
      
      
      private LockEntry getWriter(byte[] data) throws IOException, ClassNotFoundException
      {
          LockEntry entry;
          Identity oid = (Identity) deserialize(data);    		
          entry = lockmap.getWriter(oid);
          return entry;
      }
  
  	private Collection getAllReaders(byte[] data) throws IOException, ClassNotFoundException
  	{
  		Collection readers;
  		Identity oid = (Identity) deserialize(data);   		
  		readers = lockmap.getReaders(oid);
  		
  		return new ArrayList(readers);
  	}
  
  	private Boolean addReader(byte[] data) throws IOException, ClassNotFoundException
  	{
  		Boolean result = new Boolean(true);
  		LockEntry lock = (LockEntry) deserialize(data); 		
          try
          {
              lockmap.addReaderInternal(lock);
          }
          catch (Throwable t)
          {
  			result = new Boolean(false);
          }
  		return result;
  	}
  
  	private Boolean removeReader(byte[] data) throws IOException, ClassNotFoundException
  	{
  		Boolean result = new Boolean(true);
  		LockEntry lock = (LockEntry) deserialize(data); 		
  		try
  		{
  			lockmap.removeReaderByLock(lock);
  		}
  		catch (Throwable t)
  		{
  			result = new Boolean(false);
  		}
  		return result;
  	}
  
  	private Boolean removeWriter(byte[] data) throws IOException, ClassNotFoundException
  	{
  		Boolean result = new Boolean(true);
  		LockEntry lock = (LockEntry) deserialize(data); 		
  		try
  		{
  			lockmap.removeWriter(lock);
  		}
  		catch (Throwable t)
  		{
  			result = new Boolean(false);
  		}
  		return result;
  	}
  
  	private Boolean upgradeLock(byte[] data) throws IOException, ClassNotFoundException
  	{
  		Boolean result = new Boolean(true);
  		LockEntry lock = (LockEntry) deserialize(data); 		
  		try
  		{
  			lockmap.upgradeLock(lock);
  		}
  		catch (Throwable t)
  		{
  			result = new Boolean(false);
  		}
  		return result;
  	}
  
  	private Boolean setWriter(byte[] data) throws IOException, ClassNotFoundException
  	{
  		Boolean result = new Boolean(true);
  		LockEntry lock = (LockEntry) deserialize(data); 		
  		try
  		{
  			lockmap.setWriterByLock(lock);
  		}
  		catch (Throwable t)
  		{
  			result = new Boolean(false);
  		}
  		return result;
  	}
  
  	private Boolean hasReadLock(byte[] data) throws IOException, ClassNotFoundException
  	{
  		Boolean result = new Boolean(true);
  		LockEntry lock = (LockEntry) deserialize(data); 		
  		try
  		{
  			lockmap.hasReadLock(lock);
  		}
  		catch (Throwable t)
  		{
  			result = new Boolean(false);
  		}
  		return result;
  	}
  
  	
  	private Object deserialize(byte[] anArray) throws IOException, ClassNotFoundException
  	{
  		ByteArrayInputStream bais = new ByteArrayInputStream(anArray);
  		ObjectInputStream ois = new ObjectInputStream(bais);
  		Object result = ois.readObject();
  		ois.close();
  		bais.close();
  		return result;
  	}
  
      
      private byte[] getRequestByteArray(HttpServletRequest request)
          throws IOException
      {
          InputStream is = request.getInputStream();
          byte[] block = new byte[4096];
          byte[] req = null;
          int len = 0;
          
          len = is.read(block,0,block.length);
          if (len <= 0)
          {
          	return null;
          }
          else
          {
          	req = new byte[len];
          	System.arraycopy(block,0,req,0,len);
          }
          
          while (len > 0)
          {
  			len = is.read(block,0,block.length);
  			if (len <= 0)
  			{
  				break;
  			}
  			else
  			{
  				byte[] fresh = new byte[req.length + len];
  				System.arraycopy(req,0,fresh,0,req.length);
  				System.arraycopy(block,0,fresh,req.length,len);
  				req = fresh;
  			}
          }
          return req;
      }
  
  }
  
  
  
  1.1                  db-ojb/src/java/org/apache/ojb/odmg/locking/RemoteLockMapImpl.java
  
  Index: RemoteLockMapImpl.java
  ===================================================================
  package org.apache.ojb.odmg.locking;
  
  /* ====================================================================
   * The Apache Software License, Version 1.1
   *
   * Copyright (c) 2001 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 "Apache" and "Apache Software Foundation" and
   *    "Apache ObjectRelationalBridge" 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",
   *    "Apache ObjectRelationalBridge", 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.  For more
   * information on the Apache Software Foundation, please see
   * <http://www.apache.org/>.
   */
  
  import java.io.BufferedOutputStream;
  import java.io.ByteArrayOutputStream;
  import java.io.IOException;
  import java.io.InputStream;
  import java.io.ObjectInputStream;
  import java.io.ObjectOutputStream;
  import java.net.HttpURLConnection;
  import java.net.MalformedURLException;
  import java.net.ProtocolException;
  import java.net.URL;
  import java.util.Collection;
  
  import org.apache.ojb.broker.Identity;
  import org.apache.ojb.broker.PersistenceBroker;
  import org.apache.ojb.broker.PersistenceBrokerException;
  import org.apache.ojb.broker.util.configuration.Configurable;
  import org.apache.ojb.broker.util.configuration.Configuration;
  import org.apache.ojb.broker.util.configuration.ConfigurationException;
  import org.apache.ojb.broker.util.logging.Logger;
  import org.apache.ojb.broker.util.logging.LoggerFactory;
  import org.apache.ojb.odmg.TransactionImpl;
  import org.apache.ojb.odmg.TxManagerFactory;
  
  /**
   * Servlet based lock mechanism for usage in distributed environment.
   * @author Thomas Mahler
   * @version $Id: RemoteLockMapImpl.java,v 1.1 2004/01/17 16:57:34 thma Exp $
   */
  public class RemoteLockMapImpl implements LockMap, Configurable
  {
  	private Logger log = LoggerFactory.getLogger(RemoteLockMapImpl.class);
  	
  	private static URL lockservlet = null;
  
  	/**
  	 * obtain a PersistenceBroker instance.
  	 */
  	private PersistenceBroker getBroker()
  	{
  		return TxManagerFactory.instance().getCurrentTransaction().getBroker();
  	}
  
  	/**
  	 * returns the LockEntry for the Writer of object obj.
  	 * If now writer exists, null is returned.
  	 */
  	public LockEntry getWriter(Object obj)
  	{
  		PersistenceBroker broker = getBroker();
  		Identity oid = new Identity(obj, broker);
  		
          LockEntry result = null;
          try
          {
          	result = getWriterRemote(oid);
          }
          catch (Throwable e)
          {
          	log.error(e);
          }
  		return result;
  	}
  
      private LockEntry getWriterRemote(Identity oid)
          throws
              MalformedURLException,
              IOException,
              ProtocolException,
              ClassNotFoundException
      {
      	byte selector = 'w';
          byte[] requestBarr = buildRequestArray(oid, selector);
          
          HttpURLConnection conn = getHttpUrlConnection();
          
          //post request
          BufferedOutputStream out = new BufferedOutputStream(conn.getOutputStream());
          out.write(requestBarr,0,requestBarr.length);
          out.flush();
          out.close();		
          
          // read result from 
          InputStream in = conn.getInputStream();
          ObjectInputStream ois = new ObjectInputStream(in);
          LockEntry result = (LockEntry) ois.readObject();
          
          // cleanup
          ois.close();
          conn.disconnect();
          return result;
      }
  
      private HttpURLConnection getHttpUrlConnection()
          throws MalformedURLException, IOException, ProtocolException
      {
          URL lockserver = getLockserverUrl();
          HttpURLConnection conn= (HttpURLConnection) lockserver.openConnection();
          
          conn.setDoInput(true);
          conn.setDoOutput(true);
          conn.setRequestMethod("POST");
          conn.setAllowUserInteraction(false);
          conn.setUseCaches(false);
          return conn;
      }
  
      private byte[] buildRequestArray(Object object, byte selector) throws IOException
      {
          byte[] serialObj = serialize(object);
          int len = serialObj.length; 
          byte[] requestBarr = new byte[len + 1];
          requestBarr[0] = selector;
          System.arraycopy(serialObj,0,requestBarr,1,len);
          return requestBarr;
      }
  
  
      private URL getLockserverUrl() throws MalformedURLException
      {
          return lockservlet;
      }
  
  
  
  	/**
  	 * returns a collection of Reader LockEntries for object obj.
  	 * If now LockEntries could be found an empty Vector is returned.
  	 */
  	public Collection getReaders(Object obj)
  	{
  		Collection result = null;
          try
          {
              Identity oid = new Identity(obj, getBroker());
              byte selector = 'r';
              byte[] requestBarr = buildRequestArray(oid, selector);
              
              HttpURLConnection conn = getHttpUrlConnection();
              
              //post request
              BufferedOutputStream out = new BufferedOutputStream(conn.getOutputStream());
              out.write(requestBarr,0,requestBarr.length);
              out.flush();		
              
              // read result from 
              InputStream in = conn.getInputStream();
              ObjectInputStream ois = new ObjectInputStream(in);
              result = (Collection) ois.readObject();
              
              // cleanup
              ois.close();
              out.close();
              conn.disconnect();		
          }
          catch (Throwable t)
          {
              throw new PersistenceBrokerException(t);
          }
          return result;
  	}
  
  
  	/**
  	 * Add a reader lock entry for transaction tx on object obj
  	 * to the persistent storage.
  	 */
  	public boolean addReader(TransactionImpl tx, Object obj)
  	{
  		try
  		{
  			LockEntry lock = new LockEntry(new Identity(obj,getBroker()).toString(),
  					tx.getGUID(),
  					System.currentTimeMillis(),
  					LockStrategyFactory.getIsolationLevel(obj),
  					LockEntry.LOCK_READ);
              addReaderRemote(lock);
  			return true;
  		}
  		catch (Throwable t)
  		{
  			log.error("Cannot store LockEntry for object " + obj + " in transaction " + tx, t);
  			return false;
  		}
  	}
  
      private void addReaderRemote(LockEntry lock) throws IOException, ClassNotFoundException
      {
  		byte selector = 'a';
  		byte[] requestBarr = buildRequestArray(lock,selector);
          
  		HttpURLConnection conn = getHttpUrlConnection();
          
  		//post request
  		BufferedOutputStream out = new BufferedOutputStream(conn.getOutputStream());
  		out.write(requestBarr,0,requestBarr.length);
  		out.flush();		
          
  		// read result from 
  		InputStream in = conn.getInputStream();
  		ObjectInputStream ois = new ObjectInputStream(in);
  		Boolean result = (Boolean) ois.readObject();
          
  		// cleanup
  		ois.close();
  		out.close();
  		conn.disconnect();
  		if (! result.booleanValue())
  		{
  			throw new PersistenceBrokerException("could not add reader!");		
  		}
      }
  
  	public byte[] serialize(Object obj) throws IOException
  	{
  		ByteArrayOutputStream bao = new ByteArrayOutputStream();
  		ObjectOutputStream oos = new ObjectOutputStream(bao);
  		oos.writeObject(obj);
  		oos.close();
  		bao.close();
  		byte[] result = bao.toByteArray();
  		return result;
  	}
  
  	/**
  	 * remove a reader lock entry for transaction tx on object obj
  	 * from the persistent storage.
  	 */
  	public void removeReader(TransactionImpl tx, Object obj)
  	{
  		try
  		{
  			LockEntry lock = new LockEntry(new Identity(obj,getBroker()).toString(), tx.getGUID());
              removeReaderRemote(lock);
  		}
  		catch (Throwable t)
  		{
  			log.error("Cannot remove LockEntry for object " + obj + " in transaction " + tx);
  		}
  	}
  
      private void removeReaderRemote(LockEntry lock) throws IOException, ClassNotFoundException
      {
  		byte selector = 'e';
  		byte[] requestBarr = buildRequestArray(lock,selector);
          
  		HttpURLConnection conn = getHttpUrlConnection();
          
  		//post request
  		BufferedOutputStream out = new BufferedOutputStream(conn.getOutputStream());
  		out.write(requestBarr,0,requestBarr.length);
  		out.flush();		
          
  		// read result from 
  		InputStream in = conn.getInputStream();
  		ObjectInputStream ois = new ObjectInputStream(in);
  		Boolean result = (Boolean) ois.readObject();
          
  		// cleanup
  		ois.close();
  		out.close();
  		conn.disconnect();
  		if (! result.booleanValue())
  		{
  			throw new PersistenceBrokerException("could not remove reader!");		
  		}
  
      }
  
  	/**
  	 * remove a writer lock entry for transaction tx on object obj
  	 * from the persistent storage.
  	 */
  	public void removeWriter(LockEntry writer)
  	{
  		try
  		{
  			removeWriterRemote(writer);
  		}
  		catch (Throwable t)
  		{
  			log.error("Cannot remove LockEntry", t);
  		}
  	}
  
  	private void removeWriterRemote(LockEntry lock) throws IOException, ClassNotFoundException
  	{
  		byte selector = 'm';
  		byte[] requestBarr = buildRequestArray(lock,selector);
          
  		HttpURLConnection conn = getHttpUrlConnection();
          
  		//post request
  		BufferedOutputStream out = new BufferedOutputStream(conn.getOutputStream());
  		out.write(requestBarr,0,requestBarr.length);
  		out.flush();		
          
  		// read result from 
  		InputStream in = conn.getInputStream();
  		ObjectInputStream ois = new ObjectInputStream(in);
  		Boolean result = (Boolean) ois.readObject();
          
  		// cleanup
  		ois.close();
  		out.close();
  		conn.disconnect();
  		if (! result.booleanValue())
  		{
  			throw new PersistenceBrokerException("could not remove writer!");		
  		}
  
  	}
  
  	/**
  	 * upgrade a reader lock entry for transaction tx on object obj
  	 * and write it to the persistent storage.
  	 */
  	public boolean upgradeLock(LockEntry reader)
  	{
  		try
  		{
  			upgradeLockRemote(reader);
  			reader.setLockType(LockEntry.LOCK_WRITE);
  			return true;
  		}
  		catch (Throwable t)
  		{
  			log.error("Cannot upgrade LockEntry " + reader, t);
  			return false;
  		}
  	}
  
  	private void upgradeLockRemote(LockEntry lock) throws IOException, ClassNotFoundException
  	{
  		byte selector = 'u';
  		byte[] requestBarr = buildRequestArray(lock,selector);
          
  		HttpURLConnection conn = getHttpUrlConnection();
          
  		//post request
  		BufferedOutputStream out = new BufferedOutputStream(conn.getOutputStream());
  		out.write(requestBarr,0,requestBarr.length);
  		out.flush();		
          
  		// read result from 
  		InputStream in = conn.getInputStream();
  		ObjectInputStream ois = new ObjectInputStream(in);
  		Boolean result = (Boolean) ois.readObject();
          
  		// cleanup
  		ois.close();
  		out.close();
  		conn.disconnect();
  		if (! result.booleanValue())
  		{
  			throw new PersistenceBrokerException("could not remove writer!");		
  		}
  
  	}
  
  	/**
  	 * generate a writer lock entry for transaction tx on object obj
  	 * and write it to the persistent storage.
  	 */
  	public boolean setWriter(TransactionImpl tx, Object obj)
  	{
  		try
  		{
  			LockEntry lock = new LockEntry(new Identity(obj,getBroker()).toString(),
  					tx.getGUID(),
  					System.currentTimeMillis(),
  					LockStrategyFactory.getIsolationLevel(obj),
  					LockEntry.LOCK_WRITE);
  
  			setWriterRemote(lock);
  			return true;
  		}
  		catch (Throwable t)
  		{
  			log.error("Cannot set LockEntry for object " + obj + " in transaction " + tx);
  			return false;
  		}
  	}
  
  	private void setWriterRemote(LockEntry lock) throws IOException, ClassNotFoundException
  	{
  		byte selector = 's';
  		byte[] requestBarr = buildRequestArray(lock,selector);
          
  		HttpURLConnection conn = getHttpUrlConnection();
          
  		//post request
  		BufferedOutputStream out = new BufferedOutputStream(conn.getOutputStream());
  		out.write(requestBarr,0,requestBarr.length);
  		out.flush();		
          
  		// read result from 
  		InputStream in = conn.getInputStream();
  		ObjectInputStream ois = new ObjectInputStream(in);
  		Boolean result = (Boolean) ois.readObject();
          
  		// cleanup
  		ois.close();
  		out.close();
  		conn.disconnect();
  		if (! result.booleanValue())
  		{
  			throw new PersistenceBrokerException("could not set writer!");		
  		}
  
  	}
  
  	/**
  	 * check if there is a reader lock entry for transaction tx on object obj
  	 * in the persistent storage.
  	 */
  	public boolean hasReadLock(TransactionImpl tx, Object obj)
  	{
  		try
  		{
  			LockEntry lock = new LockEntry(new Identity(obj,getBroker()).toString(), tx.getGUID());
  			boolean result = hasReadLockRemote(lock);			
  			return result;
  		}
  		catch (Throwable t)
  		{
  			log.error("Cannot check read lock for object " + obj + " in transaction " + tx, t);
  			return false;
  		}
  	}
  
  	private boolean hasReadLockRemote(LockEntry lock) throws IOException, ClassNotFoundException
  	{
  		byte selector = 'h';
  		byte[] requestBarr = buildRequestArray(lock,selector);
          
  		HttpURLConnection conn = getHttpUrlConnection();
          
  		//post request
  		BufferedOutputStream out = new BufferedOutputStream(conn.getOutputStream());
  		out.write(requestBarr,0,requestBarr.length);
  		out.flush();		
          
  		// read result from 
  		InputStream in = conn.getInputStream();
  		ObjectInputStream ois = new ObjectInputStream(in);
  		Boolean result = (Boolean) ois.readObject();
          
  		// cleanup
  		ois.close();
  		out.close();
  		conn.disconnect();
  		return result.booleanValue();
  	}
  
  
  
  	
      /**
       * @see org.apache.ojb.broker.util.configuration.Configurable#configure(org.apache.ojb.broker.util.configuration.Configuration)
       */
      public void configure(Configuration pConfig) throws ConfigurationException
      {
          String url = pConfig.getString("LockServletUrl","http://127.0.0.1:8080/ojb-lockserver");
          try
          {
              lockservlet = new URL(url);
          }
          catch (MalformedURLException e)
          {
              throw new ConfigurationException("Invalid LockServlet Url was specified: " + url, e);
          }
  
      }
  
  }
  
  
  1.62      +16 -5     db-ojb/src/test/org/apache/ojb/OJB.properties
  
  Index: OJB.properties
  ===================================================================
  RCS file: /home/cvs/db-ojb/src/test/org/apache/ojb/OJB.properties,v
  retrieving revision 1.61
  retrieving revision 1.62
  diff -u -r1.61 -r1.62
  --- OJB.properties	11 Jan 2004 01:26:31 -0000	1.61
  +++ OJB.properties	17 Jan 2004 16:57:34 -0000	1.62
  @@ -214,12 +214,16 @@
   # The LockMapClass entry tells OJB which concrete LockMap
   # implementation is to be used.
   # If OJB is running on multiple concurrent clients it is recommended
  -# to use the PersistentLockMapImpl. It guarantees to provide
  -# Lockamanagement across multiple JVMs.
  +# to use the RemoteLockMapImpl. It guarantees to provide
  +# Lockmanagement across multiple JVMs. 
  +# This Implemenation relies on a Servlet based Lockserver. To use it you have to
  +# deploy the ojb-lockserver.war into a Servlet engine.
  +# and you have to set the Property LockServletUrl to point to this servlet.
  +# (see LockServletUrl section below).
   # If OJB is running in a single JVM (e.g. in a desktop app, or in a servlet
   # engine) it is save to use the InMemoryLockMapImpl. Using it will result
   # in a large performance gain.
  -# LockMapClass=org.apache.ojb.odmg.locking.PersistentLockMapImpl
  +#LockMapClass=org.apache.ojb.odmg.locking.RemoteLockMapImpl
   LockMapClass=org.apache.ojb.odmg.locking.InMemoryLockMapImpl
   #
   # The LockTimeout entry defines the maximum time in milliseconds
  @@ -236,6 +240,13 @@
   ImplicitLocking=true
   #ImplicitLocking=false
   #
  +#
  +# The LockServletUrl entry points to the Lockserver servlet.
  +# This Servlet is addressed by all distributed JVMs if the RemoteLockMapImpl
  +# is used.
  +LockServletUrl=http://127.0.0.1:8080/ojb-lockserver
  +#
  +#
   # The LockAssociations entry defines the behaviour for the OJB
   # implicit locking feature. If set to WRITE (default) acquiring a write-
   # lock on a given object x implies write locks on all objects associated
  @@ -300,7 +311,7 @@
   # Special Logger categories used in test suite and tutorials
   #
   # Logger for the ODMG Implementation
  -ODMG.LogLevel=WARN
  +ODMG.LogLevel=DEBUG
   # Logger for the JDO RI Implementation
   JDO.LogLevel=DEBUG
   # Logger for the performance tests
  
  
  
  1.1                  db-ojb/src/test/org/apache/ojb/web.xml
  
  Index: web.xml
  ===================================================================
  <?xml version="1.0" encoding="ISO-8859-1"?>
  
  <!DOCTYPE web-app
      PUBLIC "-//Sun Microsystems, Inc.//DTD Web Application 2.3//EN"
      "http://java.sun.com/dtd/web-app_2_3.dtd">
  
  <web-app>
  
    <display-name>OJB ODMG Lock Server</display-name>
    <description>
       OJB ODMG Lock Server
    </description>
  
    <servlet>
      <servlet-name>lockserver</servlet-name>
      <servlet-class>org.apache.ojb.odmg.locking.LockServerServlet</servlet-class>
      <init-param>
        <param-name>debug</param-name>
        <param-value>0</param-value>
      </init-param>
  
  
      <!--load-on-startup>1</load-on-startup-->
    </servlet>
  
    <!-- The mapping for the webdav servlet -->
    <servlet-mapping>
      <servlet-name>lockserver</servlet-name>
      <url-pattern>/</url-pattern>
    </servlet-mapping>
  
    <!-- Establish the default list of welcome files -->
    <welcome-file-list>
      <welcome-file>index.jsp</welcome-file>
      <welcome-file>index.html</welcome-file>
      <welcome-file>index.htm</welcome-file>
    </welcome-file-list>
  
  
  </web-app>
  
  
  
  1.31      +3 -3      db-ojb/src/java/org/apache/ojb/broker/util/configuration/impl/OjbConfiguration.java
  
  Index: OjbConfiguration.java
  ===================================================================
  RCS file: /home/cvs/db-ojb/src/java/org/apache/ojb/broker/util/configuration/impl/OjbConfiguration.java,v
  retrieving revision 1.30
  retrieving revision 1.31
  diff -u -r1.30 -r1.31
  --- OjbConfiguration.java	9 Oct 2003 15:05:40 -0000	1.30
  +++ OjbConfiguration.java	17 Jan 2004 16:57:34 -0000	1.31
  @@ -77,7 +77,7 @@
   import org.apache.ojb.odmg.locking.LockManagerDefaultImpl;
   import org.apache.ojb.odmg.locking.LockMap;
   import org.apache.ojb.odmg.locking.LockingConfiguration;
  -import org.apache.ojb.odmg.locking.PersistentLockMapImpl;
  +import org.apache.ojb.odmg.locking.InMemoryLockMapImpl;
   
   /**
    * This class contains the runtime configuration of the OJB
  @@ -284,7 +284,7 @@
           lockManagerClass = getClass("LockManagerClass", LockManagerDefaultImpl.class, LockManager.class);
   
           // load LockMap Class
  -        lockMapClass = getClass("LockMapClass", PersistentLockMapImpl.class, LockMap.class);
  +        lockMapClass = getClass("LockMapClass", InMemoryLockMapImpl.class, LockMap.class);
   
           // load Logger Class
           loggerClass = getClass("LoggerClass", PoorMansLoggerImpl.class, Logger.class);
  
  
  
  1.110     +45 -3     db-ojb/build.xml
  
  Index: build.xml
  ===================================================================
  RCS file: /home/cvs/db-ojb/build.xml,v
  retrieving revision 1.109
  retrieving revision 1.110
  diff -u -r1.109 -r1.110
  --- build.xml	31 Dec 2003 15:39:33 -0000	1.109
  +++ build.xml	17 Jan 2004 16:57:34 -0000	1.110
  @@ -362,7 +362,7 @@
       <!-- ================================================================== -->
   
       <target name="jar" description="Builds the binary ojb-xxx.jar in the dist directory.">
  -		<ant target="main-opt"/>
  +		<ant target="main"/>
   		<ant target="jar-internal"/>
       </target>
   
  @@ -416,7 +416,7 @@
           <mkdir dir="${build.dir}/WEB-INF/classes"/>
           <mkdir dir="${build.dir}/WEB-INF/lib"/>
   
  -        <!-- 1. jakarta-ojb-xxx.jar -->
  +        <!-- 1. apache-ojb-xxx.jar -->
           <copy file="${dist}/${archive}.jar" todir="${build.dir}/WEB-INF/lib"/>
   
           <!-- 2. OJB.properties and repository*.* files -->
  @@ -455,6 +455,48 @@
           <jar jarfile="${dist}/ojb-servlet.war" basedir="${build.dir}"
                includes="WEB-INF/**"/>
       </target>
  +
  +    <!-- ================================================================== -->
  +    <!-- Build sample war-file for deployment in tomcat                     -->
  +    <!-- ================================================================== -->
  +    <target name="lockservlet-war" depends="jar, prepare-testdb"
  +            description="Builds The Lockserver servlet for deployment in tomcat">
  +        <delete file="${dist}/ojb-lockserver.war"/>
  +        <delete dir="${build.dir}/WEB-INF" verbose="false"/>
  +        <mkdir dir="${build.dir}/WEB-INF/classes"/>
  +        <mkdir dir="${build.dir}/WEB-INF/lib"/>
  +
  +        <!-- 1. apache-ojb-xxx.jar -->
  +        <copy file="${dist}/${archive}.jar" todir="${build.dir}/WEB-INF/lib"/>
  +
  +        <!-- 2. OJB.properties and repository*.* files -->
  +        <copy todir="${build.dir}/WEB-INF/classes">
  +            <fileset dir="${build.test}/ojb" includes="*.properties,*.dtd,*.xml"/>
  +        </copy>
  +        
  +        <copy todir="${build.dir}/WEB-INF">
  +            <fileset dir="${build.srctest}/org/apache/ojb" includes="web.xml"/>
  +        </copy>
  +
  +        <!-- 3. additional jar files -->
  +        <copy todir="${build.dir}/WEB-INF/lib">
  +            <fileset dir="${lib}">
  +              <include name="log4j-1.2.8.jar"/>
  +			  <include name="commons-logging.jar"/>
  +			  <include name="commons-lang-2.0.jar"/>
  +            </fileset>
  +        </copy>
  +
  +
  +		<!-- 4. the business code, that is our servlet-->
  +        <copy todir="${build.dir}/WEB-INF/classes">
  +            <fileset dir="${build.dest}" includes="org/apache/ojb/odmg/locking/**"/>
  +        </copy>
  +
  +        <jar jarfile="${dist}/ojb-lockserver.war" basedir="${build.dir}"
  +             includes="WEB-INF/**"/>
  +    </target>
  +
   
       <!-- ================================================================== -->
       <!-- Build sample jar-file for a new project                            -->
  
  
  

---------------------------------------------------------------------
To unsubscribe, e-mail: ojb-dev-unsubscribe@db.apache.org
For additional commands, e-mail: ojb-dev-help@db.apache.org