You are viewing a plain text version of this content. The canonical link for it is here.
Posted to slide-dev@jakarta.apache.org by re...@apache.org on 2001/01/11 01:41:52 UTC

cvs commit: jakarta-slide/src/share/org/apache/slide/store AbstractStore.java

remm        01/01/10 16:41:52

  Modified:    src/share/org/apache/slide/store AbstractStore.java
  Log:
  - Samarter about function calling on the substores. That will prevent one
    substore to be called multiple times.
  - Automatic enlistment / delistment of stores in the current transaction.
  
  Revision  Changes    Path
  1.2       +267 -57   jakarta-slide/src/share/org/apache/slide/store/AbstractStore.java
  
  Index: AbstractStore.java
  ===================================================================
  RCS file: /home/cvs/jakarta-slide/src/share/org/apache/slide/store/AbstractStore.java,v
  retrieving revision 1.1
  retrieving revision 1.2
  diff -u -r1.1 -r1.2
  --- AbstractStore.java	2001/01/10 18:49:36	1.1
  +++ AbstractStore.java	2001/01/11 00:41:51	1.2
  @@ -1,7 +1,7 @@
   /*
  - * $Header: /home/cvs/jakarta-slide/src/share/org/apache/slide/store/AbstractStore.java,v 1.1 2001/01/10 18:49:36 remm Exp $
  - * $Revision: 1.1 $
  - * $Date: 2001/01/10 18:49:36 $
  + * $Header: /home/cvs/jakarta-slide/src/share/org/apache/slide/store/AbstractStore.java,v 1.2 2001/01/11 00:41:51 remm Exp $
  + * $Revision: 1.2 $
  + * $Date: 2001/01/11 00:41:51 $
    *
    * ====================================================================
    *
  @@ -68,6 +68,11 @@
   import java.util.Vector;
   import java.io.FileWriter;
   import java.io.IOException;
  +import javax.transaction.TransactionManager;
  +import javax.transaction.Transaction;
  +import javax.transaction.xa.XAResource;
  +import javax.transaction.xa.XAException;
  +import javax.transaction.xa.Xid;
   import org.apache.slide.common.*;
   import org.apache.slide.structure.*;
   import org.apache.slide.security.*;
  @@ -75,12 +80,14 @@
   import org.apache.slide.content.*;
   import org.apache.slide.util.ObjectCache;
   import org.apache.slide.util.HashMapObjectCache;
  +import org.apache.slide.transaction.SlideTransactionManager;
  +import org.apache.slide.transaction.SlideTransaction;
   
   /**
    * Abstract implementation of a store. Handles all caching operations.
    * 
    * @author <a href="mailto:remm@apache.org">Remy Maucherat</a>
  - * @version $Revision: 1.1 $
  + * @version $Revision: 1.2 $
    */
   public abstract class AbstractStore extends ServiceImpl 
       implements Store {
  @@ -135,6 +142,12 @@
       protected ContentStore contentStore;
       
       
  +    /**
  +     * Active resource manager list.
  +     */
  +    protected Service resourceManagers[] = new Service[0];
  +    
  +    
       // ---------------------------------------------------- ServiceImpl Methods
       
       
  @@ -145,12 +158,9 @@
           
           super.setNamespace(namespace);
           
  -        lockStore.setNamespace(namespace);
  -        nodeStore.setNamespace(namespace);
  -        securityStore.setNamespace(namespace);
  -        revisionDescriptorsStore.setNamespace(namespace);
  -        revisionDescriptorStore.setNamespace(namespace);
  -        contentStore.setNamespace(namespace);
  +        for (int i = 0; i < resourceManagers.length; i++) {
  +            resourceManagers[i].setNamespace(namespace);
  +        }
           
       }
       
  @@ -183,12 +193,9 @@
       public void connect()
           throws ServiceConnectionFailedException {
           
  -        lockStore.connect();
  -        nodeStore.connect();
  -        securityStore.connect();
  -        revisionDescriptorsStore.connect();
  -        revisionDescriptorStore.connect();
  -        contentStore.connect();
  +        for (int i = 0; i < resourceManagers.length; i++) {
  +            resourceManagers[i].connect();
  +        }
           
       }
       
  @@ -201,12 +208,9 @@
       public void disconnect()
           throws ServiceDisconnectionFailedException {
           
  -        lockStore.disconnect();
  -        nodeStore.disconnect();
  -        securityStore.disconnect();
  -        revisionDescriptorsStore.disconnect();
  -        revisionDescriptorStore.disconnect();
  -        contentStore.disconnect();
  +        for (int i = 0; i < resourceManagers.length; i++) {
  +            resourceManagers[i].disconnect();
  +        }
           
       }
       
  @@ -232,41 +236,34 @@
               // Should never happen ...
               t.printStackTrace();
           }
  +        
  +        if (lockStore == null) {
  +            setLockStore((LockStore) defaultStore);
  +        }
           
  -        if (lockStore != null) {
  -            lockStore.initialize(token);
  -        } else {
  -            lockStore = (LockStore) defaultStore;
  +        if (nodeStore == null) {
  +            setNodeStore((NodeStore) defaultStore);
           }
           
  -        if (nodeStore != null) {
  -            nodeStore.initialize(token);
  -        } else {
  -            nodeStore = (NodeStore) defaultStore;
  +        if (securityStore == null) {
  +            setSecurityStore((SecurityStore) defaultStore);
           }
           
  -        if (securityStore != null) {
  -            securityStore.initialize(token);
  -        } else {
  -            securityStore = (SecurityStore) defaultStore;
  +        if (revisionDescriptorsStore == null) {
  +            setRevisionDescriptorsStore
  +                ((RevisionDescriptorsStore) defaultStore);
           }
           
  -        if (revisionDescriptorsStore != null) {
  -            revisionDescriptorsStore.initialize(token);
  -        } else {
  -            revisionDescriptorsStore = (RevisionDescriptorsStore) defaultStore;
  +        if (revisionDescriptorStore == null) {
  +            setRevisionDescriptorStore((RevisionDescriptorStore) defaultStore);
           }
           
  -        if (revisionDescriptorStore != null) {
  -            revisionDescriptorStore.initialize(token);
  -        } else {
  -            revisionDescriptorStore = (RevisionDescriptorStore) defaultStore;
  +        if (contentStore == null) {
  +            setContentStore((ContentStore) defaultStore);
           }
           
  -        if (contentStore != null) {
  -            contentStore.initialize(token);
  -        } else {
  -            contentStore = (ContentStore) defaultStore;
  +        for (int i = 0; i < resourceManagers.length; i++) {
  +            resourceManagers[i].initialize(token);
           }
           
       }
  @@ -280,12 +277,9 @@
       public void reset()
           throws ServiceResetFailedException {
           
  -        lockStore.reset();
  -        nodeStore.reset();
  -        securityStore.reset();
  -        revisionDescriptorsStore.reset();
  -        revisionDescriptorStore.reset();
  -        contentStore.reset();
  +        for (int i = 0; i < resourceManagers.length; i++) {
  +            resourceManagers[i].reset();
  +        }
           
       }
       
  @@ -299,22 +293,125 @@
       public boolean isConnected()
           throws ServiceAccessException {
           
  -        return (lockStore.isConnected() && nodeStore.isConnected() &&
  -                securityStore.isConnected() && 
  -                revisionDescriptorsStore.isConnected() &&
  -                revisionDescriptorStore.isConnected());
  +        for (int i = 0; i < resourceManagers.length; i++) {
  +            if (!resourceManagers[i].isConnected())
  +                return false;
  +        }
  +        return true;
           
       }
       
       
  -    // ----------------------------------------------- DescriptorsStore Methods
  +    // ----------------------------------------------------- XAResource Methods
       
       
       /**
  +     * Commit the global transaction specified by xid.
  +     * 
  +     * @param xid A global transaction identifier
  +     * @param onePhase If true, the resource manager should use a one-phase 
  +     * commit protocol to commit the work done on behalf of xid.
  +     * @exception XAException An error has occurred. Possible XAExceptions 
  +     * are XA_HEURHAZ, XA_HEURCOM, XA_HEURRB, XA_HEURMIX, XAER_RMERR, 
  +     * XAER_RMFAIL, XAER_NOTA, XAER_INVAL, or XAER_PROTO. If the resource 
  +     * manager did not commit the transaction and the paramether onePhase is 
  +     * set to true, the resource manager may throw one of the XA_RB* 
  +     * exceptions. Upon return, the resource manager has rolled back the 
  +     * branch's work and has released all held resources.
  +     */
  +    public void commit(Xid xid, boolean onePhase)
  +        throws XAException {
  +        super.commit(xid, onePhase);
  +    }
  +
  +    
  +    /**
  +     * Ends the work performed on behalf of a transaction branch.
  +     * 
  +     * @param xid A global transaction identifier that is the same as what 
  +     * was used previously in the start method.
  +     * @param flags One of TMSUCCESS, TMFAIL, or TMSUSPEND
  +     * @exception XAException An error has occurred. Possible XAException 
  +     * values are XAER_RMERR, XAER_RMFAILED, XAER_NOTA, XAER_INVAL, 
  +     * XAER_PROTO, or XA_RB*.
  +     */
  +    public void end(Xid xid, int flags)
  +        throws XAException {
  +        super.end(xid, flags);
  +    }    
  +    
  +    
  +    /**
  +     * Tell the resource manager to forget about a heuristically completed 
  +     * transaction branch.
  +     * 
  +     * @param xid A global transaction identifier
  +     * @exception XAException An error has occurred. Possible exception values
  +     * are XAER_RMERR, XAER_RMFAIL, XAER_NOTA, XAER_INVAL, or XAER_PROTO.
  +     */
  +    public void forget(Xid xid)
  +        throws XAException {
  +        super.forget(xid);
  +    }
  +    
  +    
  +    /**
  +     * Ask the resource manager to prepare for a transaction commit of the 
  +     * transaction specified in xid.
  +     * 
  +     * @param xid A global transaction identifier
  +     * @return A value indicating the resource manager's vote on the outcome 
  +     * of the transaction. The possible values are: XA_RDONLY or XA_OK. If 
  +     * the resource manager wants to roll back the transaction, it should do 
  +     * so by raising an appropriate XAException in the prepare method.
  +     * @exception XAException An error has occurred. Possible exception 
  +     * values are: XA_RB*, XAER_RMERR, XAER_RMFAIL, XAER_NOTA, XAER_INVAL, 
  +     * or XAER_PROTO.
  +     */
  +    public int prepare(Xid xid)
  +        throws XAException {
  +        return super.prepare(xid);
  +    }
  +    
  +    
  +    /**
  +     * Inform the resource manager to roll back work done on behalf of a 
  +     * transaction branch.
  +     * 
  +     * @param xid A global transaction identifier
  +     * @exception XAException An error has occurred
  +     */
  +    public void rollback(Xid xid)
  +        throws XAException {
  +        super.rollback(xid);
  +    }
  +    
  +    
  +    /**
  +     * Start work on behalf of a transaction branch specified in xid.
  +     * 
  +     * @param xid A global transaction identifier to be associated with the 
  +     * resource
  +     * @param flags One of TMNOFLAGS, TMJOIN, or TMRESUME
  +     * @exception XAException An error has occurred. Possible exceptions are 
  +     * XA_RB*, XAER_RMERR, XAER_RMFAIL, XAER_DUPID, XAER_OUTSIDE, XAER_NOTA, 
  +     * XAER_INVAL, or XAER_PROTO.
  +     */
  +    public void start(Xid xid, int flags)
  +        throws XAException {
  +        super.start(xid, flags);
  +    }
  +    
  +    
  +    // ---------------------------------------------------------- Store Methods
  +    
  +    
  +    /**
        * Set the node store associated with this store.
        */
       public void setNodeStore(NodeStore nodeStore) {
           this.nodeStore = nodeStore;
  +        addResourceManager(nodeStore);
       }
       
       
  @@ -323,6 +420,7 @@
        */
       public void setSecurityStore(SecurityStore securityStore) {
           this.securityStore = securityStore;
  +        addResourceManager(securityStore);
       }
       
       
  @@ -331,6 +429,7 @@
        */
       public void setLockStore(LockStore lockStore) {
           this.lockStore = lockStore;
  +        addResourceManager(lockStore);
       }
       
       
  @@ -340,6 +439,7 @@
       public void setRevisionDescriptorsStore
           (RevisionDescriptorsStore revisionDescriptorsStore) {
           this.revisionDescriptorsStore = revisionDescriptorsStore;
  +        addResourceManager(revisionDescriptorsStore);
       }
       
       
  @@ -349,6 +449,7 @@
       public void setRevisionDescriptorStore
           (RevisionDescriptorStore revisionDescriptorStore) {
           this.revisionDescriptorStore = revisionDescriptorStore;
  +        addResourceManager(revisionDescriptorStore);
       }
       
       
  @@ -357,6 +458,7 @@
        */
       public void setContentStore(ContentStore contentStore) {
           this.contentStore = contentStore;
  +        addResourceManager(contentStore);
       }
       
       
  @@ -386,7 +488,9 @@
           throws ServiceAccessException, ObjectNotFoundException {
           ObjectNode tempObject = object.cloneObject();
           tempObject.validate(uri.toString());
  +        enlist(nodeStore);
           nodeStore.storeObject(uri, tempObject);
  +        delist(nodeStore);
       }
       
       
  @@ -403,7 +507,9 @@
           throws ServiceAccessException, ObjectAlreadyExistsException {
           ObjectNode tempObject = object.cloneObject();
           tempObject.validate(uri.toString());
  +        enlist(nodeStore);
           nodeStore.createObject(uri, tempObject);
  +        delist(nodeStore);
       }
       
       
  @@ -417,7 +523,9 @@
       public void removeObject(Uri uri, ObjectNode object)
           throws ServiceAccessException, ObjectNotFoundException {
           object.validate(uri.toString());
  +        enlist(nodeStore);
           nodeStore.removeObject(uri, object);
  +        delist(nodeStore);
       }
       
       
  @@ -431,7 +539,9 @@
           throws ServiceAccessException {
           NodePermission tempPermission = permission.cloneObject();
           tempPermission.validate(uri.toString());
  +        enlist(securityStore);
           securityStore.grantPermission(uri, tempPermission);
  +        delist(securityStore);
       }
       
       
  @@ -444,7 +554,9 @@
       public void revokePermission(Uri uri, NodePermission permission)
           throws ServiceAccessException {
           permission.validate(uri.toString());
  +        enlist(securityStore);
           securityStore.revokePermission(uri, permission);
  +        delist(securityStore);
       }
       
       
  @@ -456,7 +568,9 @@
        */
       public void revokePermissions(Uri uri)
           throws ServiceAccessException {
  +        enlist(securityStore);
           securityStore.revokePermissions(uri);
  +        delist(securityStore);
       }
       
       
  @@ -482,7 +596,9 @@
       public void putLock(Uri uri, NodeLock lock)
           throws ServiceAccessException {
           lock.validate(uri.toString());
  +        enlist(lockStore);
           lockStore.putLock(uri, lock);
  +        delist(lockStore);
       }
       
       
  @@ -496,7 +612,9 @@
       public void renewLock(Uri uri, NodeLock lock)
           throws ServiceAccessException, LockTokenNotFoundException {
           lock.validate(uri.toString());
  +        enlist(lockStore);
           lockStore.renewLock(uri, lock);
  +        delist(lockStore);
       }
       
       
  @@ -510,7 +628,9 @@
       public void removeLock(Uri uri, NodeLock lock)
           throws ServiceAccessException, LockTokenNotFoundException {
           lock.validate(uri.toString());
  +        enlist(lockStore);
           lockStore.removeLock(uri, lock);
  +        delist(lockStore);
       }
       
       
  @@ -524,7 +644,9 @@
       public void killLock(Uri uri, NodeLock lock)
           throws ServiceAccessException, LockTokenNotFoundException {
           lock.validate(uri.toString());
  +        enlist(lockStore);
           lockStore.killLock(uri, lock);
  +        delist(lockStore);
       }
       
       
  @@ -569,8 +691,10 @@
           (Uri uri, NodeRevisionDescriptors revisionDescriptors)
           throws ServiceAccessException {
           revisionDescriptors.validate(uri.toString());
  +        enlist(revisionDescriptorsStore);
           revisionDescriptorsStore.createRevisionDescriptors
               (uri, revisionDescriptors);
  +        delist(revisionDescriptorsStore);
       }
       
       
  @@ -587,8 +711,10 @@
           (Uri uri, NodeRevisionDescriptors revisionDescriptors)
           throws ServiceAccessException, RevisionDescriptorNotFoundException {
           revisionDescriptors.validate(uri.toString());
  +        enlist(revisionDescriptorsStore);
           revisionDescriptorsStore.storeRevisionDescriptors
               (uri, revisionDescriptors);
  +        delist(revisionDescriptorsStore);
       }
       
       
  @@ -600,7 +726,9 @@
        */
       public void removeRevisionDescriptors(Uri uri)
           throws ServiceAccessException {
  +        enlist(revisionDescriptorsStore);
           revisionDescriptorsStore.removeRevisionDescriptors(uri);
  +        delist(revisionDescriptorsStore);
       }
       
       
  @@ -632,8 +760,10 @@
           (Uri uri, NodeRevisionDescriptor revisionDescriptor)
           throws ServiceAccessException {
           revisionDescriptor.validate();
  +        enlist(revisionDescriptorStore);
           revisionDescriptorStore.createRevisionDescriptor
               (uri, revisionDescriptor);
  +        delist(revisionDescriptorStore);
       }
       
       
  @@ -650,8 +780,10 @@
           (Uri uri, NodeRevisionDescriptor revisionDescriptor)
           throws ServiceAccessException, RevisionDescriptorNotFoundException {
           revisionDescriptor.validate();
  +        enlist(revisionDescriptorStore);
           revisionDescriptorStore.storeRevisionDescriptor
               (uri, revisionDescriptor);
  +        delist(revisionDescriptorStore);
       }
       
       
  @@ -665,7 +797,9 @@
       public void removeRevisionDescriptor(Uri uri, NodeRevisionNumber number)
           throws ServiceAccessException {
           number.validate();
  +        enlist(revisionDescriptorStore);
           revisionDescriptorStore.removeRevisionDescriptor(uri, number);
  +        delist(revisionDescriptorStore);
       }
       
       
  @@ -698,8 +832,10 @@
           throws ServiceAccessException, RevisionAlreadyExistException {
           revisionDescriptor.validate();
           revisionContent.validate();
  +        enlist(contentStore);
           contentStore.createRevisionContent(uri, revisionDescriptor, 
                                              revisionContent);
  +        delist(contentStore);
       }
       
       
  @@ -716,8 +852,10 @@
           throws ServiceAccessException, RevisionNotFoundException {
           revisionDescriptor.validate();
           revisionContent.validate();
  +        enlist(contentStore);
           contentStore.storeRevisionContent(uri, revisionDescriptor, 
                                             revisionContent);
  +        delist(contentStore);
       }
       
       
  @@ -731,8 +869,80 @@
                                         NodeRevisionNumber revisionNumber)
           throws ServiceAccessException {
           revisionNumber.validate();
  +        enlist(contentStore);
           contentStore.removeRevisionContent(uri, revisionNumber);
  +        delist(contentStore);
       }
   
   
  +    // ------------------------------------------------------ Protected Methods
  +    
  +    
  +    /**
  +     * Add a new resource manager.
  +     * 
  +     * @param service New resource manager
  +     */
  +    protected void addResourceManager(Service service) {
  +        // First check if the new store isn't already in the array
  +        for (int i = 0; i < resourceManagers.length; i++) {
  +            try {
  +                if (resourceManagers[i].isSameRM(service))
  +                    return;
  +            } catch (XAException e) {
  +            }
  +        }
  +        Service results[] = new Service[resourceManagers.length + 1];
  +        System.arraycopy(resourceManagers, 0, results, 0, 
  +                         resourceManagers.length);
  +        results[resourceManagers.length] = service;
  +        resourceManagers = results;
  +    }
  +    
  +    
  +    /**
  +     * Enlist the resource manager in the current transaction.
  +     */
  +    protected void enlist() {
  +        enlist(this);
  +    }
  +    
  +    
  +    /**
  +     * Enlist the resource manager in the current transaction.
  +     */
  +    protected void enlist(Service service) {
  +        // Note: No exception is thrown
  +        try {
  +            namespace.getTransactionManager()
  +                .getTransaction().enlistResource(service);
  +        } catch (Exception e) {
  +            // Something went wrong.
  +            // FIXME: Log the error
  +        }
  +    }
  +    
  +    
  +    /**
  +     * Delist (suspend) the resource manager in the current transaction.
  +     */
  +    protected void delist() {
  +        delist(this);
  +    }
  +    
  +    
  +    /**
  +     * Delist (suspend) the resource manager in the current transaction.
  +     */
  +    protected void delist(Service service) {
  +        try {
  +            namespace.getTransactionManager()
  +                .getTransaction().delistResource(service, TMSUSPEND);
  +        } catch (Exception e) {
  +            // Something went wrong.
  +            // FIXME: Log the error
  +        }
  +    }
  +    
  +    
   }