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
+ }
+ }
+
+
}