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 ar...@apache.org on 2003/12/20 13:35:40 UTC

cvs commit: db-ojb/src/java/org/apache/ojb/broker/accesslayer RsIterator.java

arminw      2003/12/20 04:35:40

  Modified:    src/test/org/apache/ojb/broker RsIteratorTest.java
               src/java/org/apache/ojb/broker/accesslayer RsIterator.java
  Log:
  (synchronize with branch)
  introduce a setAutoRelease(boolean b) method to allow User
  a better control of resource cleanup done by RsIterator class.
  Independend from the autoRelease flag on a PB.close/commitTx/abortTx
  call, all resources will be closed.
  
  To use this Method User needs to cast to RsIterator. Till OJB 1.1
  we add this method to OJBIterator interface and let PB interface return
  only OJBIterator instead of Iterator.
  
  Revision  Changes    Path
  1.5       +117 -0    db-ojb/src/test/org/apache/ojb/broker/RsIteratorTest.java
  
  Index: RsIteratorTest.java
  ===================================================================
  RCS file: /home/cvs/db-ojb/src/test/org/apache/ojb/broker/RsIteratorTest.java,v
  retrieving revision 1.4
  retrieving revision 1.5
  diff -u -r1.4 -r1.5
  --- RsIteratorTest.java	13 Dec 2003 17:50:40 -0000	1.4
  +++ RsIteratorTest.java	20 Dec 2003 12:35:40 -0000	1.5
  @@ -187,6 +187,123 @@
           }
       }
   
  +    /**
  +     * Test RsIterator cleanup on PB.abortTransaction()
  +     */
  +    public void testRsIteratorUserCleanup_1() throws Exception
  +    {
  +        String name = "testRsIteratorAutomaticCleanupCheck_" + System.currentTimeMillis();
  +        prepareTest(name);
  +
  +        Criteria criteria = new Criteria();
  +        criteria.addLike("name", name+"*");
  +        Query query = new QueryByCriteria(ObjectRepository.Component.class, criteria);
  +
  +        Iterator it = broker.getIteratorByQuery(query);
  +
  +        /*
  +        TODO: After integration of setAutoRelease into OJBIterator and changes
  +        in PB interface getIteratorXXX methods we don't need these casts any longer
  +        */
  +        if(!(it instanceof RsIterator))
  +        {
  +            // skip test
  +            return;
  +        }
  +
  +        // TODO: Remove this cast one day
  +        ((RsIterator) it).setAutoRelease(false);
  +
  +        it.hasNext();
  +        broker.beginTransaction();
  +        broker.abortTransaction();
  +        /*
  +        if tx was aborted we invalidate RsIterator instance
  +        */
  +        try
  +        {
  +            it.next();
  +            fail("We expect RsIterator has released resources on pb.commit..");
  +        }
  +        catch (RsIterator.ResourceClosedException e)
  +        {
  +            assertTrue(true);
  +        }
  +
  +
  +        it = broker.getIteratorByQuery(query);
  +        // TODO: Remove this cast one day
  +        ((RsIterator) it).setAutoRelease(false);
  +
  +        it.hasNext();
  +        it.next();
  +        broker.beginTransaction();
  +        broker.abortTransaction();
  +        /*
  +        if tx was aborted we invalidate RsIterator instance
  +        */
  +        try
  +        {
  +            it.hasNext();
  +            it.next();
  +            fail("We expect RsIterator has released resources on pb.commit..");
  +        }
  +        catch (RsIterator.ResourceClosedException e)
  +        {
  +            assertTrue(true);
  +        }
  +    }
  +
  +    /**
  +     * Test RsIterator cleanup on PB.abortTransaction()
  +     */
  +    public void testRsIteratorUserCleanup_2() throws Exception
  +    {
  +        String name = "testRsIteratorAutomaticCleanupCheck_" + System.currentTimeMillis();
  +        prepareTest(name);
  +
  +        Criteria criteria = new Criteria();
  +        criteria.addLike("name", name+"*");
  +        Query query = new QueryByCriteria(ObjectRepository.Component.class, criteria);
  +
  +        Iterator it = broker.getIteratorByQuery(query);
  +
  +        /*
  +        TODO: After integration of setAutoRelease into OJBIterator and changes
  +        in PB interface getIteratorXXX methods we don't need these casts any longer
  +        */
  +        if(!(it instanceof RsIterator))
  +        {
  +            // skip test
  +            return;
  +        }
  +
  +        // TODO: Remove this cast one day
  +        ((RsIterator) it).setAutoRelease(false);
  +
  +        while(it.hasNext())
  +        {
  +            ObjectRepository.Component c = (ObjectRepository.Component) it.next();
  +            assertNotNull(c.getId());
  +        }
  +
  +        try
  +        {
  +            ((RsIterator) it).relative(1);
  +        }
  +        catch(RsIterator.ResourceClosedException e)
  +        {
  +            fail("RsIterator should not close resources by itself");
  +        }
  +        catch (PersistenceBrokerException ignore)
  +        {
  +        }
  +
  +        // TODO: Remove this cast one day
  +        ((RsIterator) it).releaseDbResources();
  +    }
  +
  +
       private void prepareTest(String objectName)
       {
           ObjectRepository.Component c1 = new ObjectRepository.Component();
  
  
  
  1.56      +69 -15    db-ojb/src/java/org/apache/ojb/broker/accesslayer/RsIterator.java
  
  Index: RsIterator.java
  ===================================================================
  RCS file: /home/cvs/db-ojb/src/java/org/apache/ojb/broker/accesslayer/RsIterator.java,v
  retrieving revision 1.55
  retrieving revision 1.56
  diff -u -r1.55 -r1.56
  --- RsIterator.java	17 Dec 2003 20:37:02 -0000	1.55
  +++ RsIterator.java	20 Dec 2003 12:35:40 -0000	1.56
  @@ -98,12 +98,15 @@
    * @author <a href="mailto:mattbaird@yahoo.com">Matthew Baird <a>- added the
    *         support for extents mapped to single table - added the .size
    *         functionality - added cursor control
  + * 
    * @version $Id$
    */
   public class RsIterator implements OJBIterator
   {
       protected Logger logger = LoggerFactory.getLogger(this.getClass());
   
  +    private static final String INFO_MSG = "Resources already cleaned up, recommend to set" +
  +            " this flag before first use of the iterator";
       /*
   	 * arminw: to improve performance we only use this instance to fire events
   	 * and set the target object on every use TODO: Find a better solution
  @@ -168,6 +171,12 @@
       private boolean resourcesAreReleased = false;
   
       /**
  +     * Flag that indicates if the automatic resource cleanup should be
  +     * done or not. Default is <tt>true</tt>.
  +     */
  +    private boolean autoRelease = true;
  +
  +    /**
        * RsIterator constructor.
        *
        * @param queryObject query object
  @@ -212,7 +221,7 @@
           }
           catch (RuntimeException e)
           {
  -            releaseDbResources();
  +            autoReleaseDbResources();
               throw e;
           }
   
  @@ -247,14 +256,14 @@
                   setHasNext(getRsAndStmt().m_rs.next());
                   if (!getHasNext())
                   {
  -                    releaseDbResources();
  +                    autoReleaseDbResources();
                   }
               }
           }
           catch (Exception ex)
           {
               setHasNext(false);
  -            releaseDbResources();
  +            autoReleaseDbResources();
               if(ex instanceof ResourceClosedException)
               {
                   throw (ResourceClosedException)ex;
  @@ -298,7 +307,7 @@
           }
           catch (Exception ex)
           {
  -            releaseDbResources();
  +            autoReleaseDbResources();
               // ex.printStackTrace();
               if(ex instanceof ResourceClosedException)
               {
  @@ -711,7 +720,7 @@
                           setHasCalledCheck(true);
                           setHasNext(false);
                           retval = false;
  -                        releaseDbResources();
  +                        autoReleaseDbResources();
                       }
                   }
                   catch (Exception ex)
  @@ -795,6 +804,41 @@
       }
   
       /**
  +     * Internally used by this class to close used resources
  +     * as soon as possible.
  +     */
  +    protected void autoReleaseDbResources()
  +    {
  +        if(autoRelease)
  +        {
  +            releaseDbResources();
  +        }
  +    }
  +
  +    /**
  +     * Allows user to switch off/on automatic resource cleanup.
  +     * Set <tt>false</tt> to take responsibility of resource cleanup
  +     * for this class, means after use it's mandatory to call
  +     * {@link #releaseDbResources}.
  +     * <br/> By default it's <tt>true</tt> and resource cleanup is done
  +     * automatic.
  +     */
  +    public void setAutoRelease(boolean autoRelease)
  +    {
  +        /*
  +        arminw:
  +        this method should be declared in OJBIterator interface till
  +        OJB 1.1 and PersistenceBroker interface should only return
  +        OJBIterator instead of Iterator instances
  +        */
  +        if(resourcesAreReleased && !autoRelease)
  +        {
  +            logger.info(INFO_MSG);
  +        }
  +        this.autoRelease = autoRelease;
  +    }
  +
  +    /**
        * Return the DescriptorRepository
        */
       protected DescriptorRepository getDescriptorRepository()
  @@ -845,6 +889,11 @@
   
       protected void setRsAndStmt(ResultSetAndStatement rsAndStmt)
       {
  +        if(m_rsAndStmt != null)
  +        {
  +            throw new ResourceNotClosedException("Unclosed resources found, please release resources" +
  +                    " before set new ones");
  +        }
           resourcesAreReleased = false;
           m_rsAndStmt = rsAndStmt;
       }
  @@ -948,11 +997,12 @@
       public static class ResourceWrapper implements PBStateListener
       {
           /*
  +        arminw:
           we do register a PBStateListener to PB instance
           to make sure that this instance will be cleaned up at PB.close() call.
  -        If PB was in tx, we cleanup on PB.commit/abort because we create
  -        RsIterator instance within a tx.
  -        TODO: Check beforeRollback, beforeCommit method calls - is this too strict?
  +        If PB was in tx, we cleanup resources on PB.commit/abort, because
  +        commit/abort close the current used connection and all Statement/ResultSet
  +        instances will become invalid.
           */
           WeakReference ref;
   
  @@ -1007,21 +1057,25 @@
   
       public static class ResourceClosedException extends OJBRuntimeException
       {
  -        public ResourceClosedException()
  +        public ResourceClosedException(String msg)
           {
  +            super(msg);
           }
   
  -        public ResourceClosedException(String msg)
  +        public ResourceClosedException(String msg, Throwable cause)
           {
  -            super(msg);
  +            super(msg, cause);
           }
  +    }
   
  -        public ResourceClosedException(Throwable cause)
  +    public static class ResourceNotClosedException extends OJBRuntimeException
  +    {
  +        public ResourceNotClosedException(String msg)
           {
  -            super(cause);
  +            super(msg);
           }
   
  -        public ResourceClosedException(String msg, Throwable cause)
  +        public ResourceNotClosedException(String msg, Throwable cause)
           {
               super(msg, cause);
           }
  
  
  

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