From 43a69ac371e08810b5eba28b47f2696e734d46ba Mon Sep 17 00:00:00 2001 From: David Caruana Date: Thu, 15 Jun 2006 17:58:03 +0000 Subject: [PATCH] Fix AR-649. git-svn-id: https://svn.alfresco.com/repos/alfresco-enterprise/alfresco/HEAD/root@3121 c4b6b30b-aa2e-2d43-bbcb-ca4b014f7261 --- config/alfresco/hibernate-context.xml | 9 ++- .../PermissionsDaoComponentImpl.java | 65 ++++++++++++++++++- .../HibernateNodeDaoServiceImpl.java | 3 +- .../AlfrescoTransactionSupport.java | 32 +++++---- .../repo/transaction/TransactionalDao.java | 26 ++++++++ ....java => TransactionalDaoInterceptor.java} | 17 +++-- 6 files changed, 121 insertions(+), 31 deletions(-) create mode 100644 source/java/org/alfresco/repo/transaction/TransactionalDao.java rename source/java/org/alfresco/repo/transaction/{NodeDaoServiceTransactionInterceptor.java => TransactionalDaoInterceptor.java} (70%) diff --git a/config/alfresco/hibernate-context.xml b/config/alfresco/hibernate-context.xml index 3c6cd954d5..fc2befda7b 100644 --- a/config/alfresco/hibernate-context.xml +++ b/config/alfresco/hibernate-context.xml @@ -105,11 +105,16 @@ - - + + + + + + + org.alfresco.repo.node.db.NodeDaoService diff --git a/source/java/org/alfresco/repo/domain/hibernate/PermissionsDaoComponentImpl.java b/source/java/org/alfresco/repo/domain/hibernate/PermissionsDaoComponentImpl.java index 96b5dfb136..08f324b5f8 100644 --- a/source/java/org/alfresco/repo/domain/hibernate/PermissionsDaoComponentImpl.java +++ b/source/java/org/alfresco/repo/domain/hibernate/PermissionsDaoComponentImpl.java @@ -35,10 +35,12 @@ import org.alfresco.repo.security.permissions.impl.PermissionsDaoComponent; import org.alfresco.repo.security.permissions.impl.SimpleNodePermissionEntry; import org.alfresco.repo.security.permissions.impl.SimplePermissionEntry; import org.alfresco.repo.security.permissions.impl.SimplePermissionReference; +import org.alfresco.repo.transaction.TransactionalDao; import org.alfresco.service.cmr.repository.InvalidNodeRefException; import org.alfresco.service.cmr.repository.NodeRef; import org.alfresco.service.cmr.security.AccessStatus; import org.alfresco.service.namespace.QName; +import org.alfresco.util.GUID; import org.hibernate.Query; import org.hibernate.Session; import org.springframework.orm.hibernate3.HibernateCallback; @@ -52,7 +54,7 @@ import org.springframework.orm.hibernate3.support.HibernateDaoSupport; * * @author andyh */ -public class PermissionsDaoComponentImpl extends HibernateDaoSupport implements PermissionsDaoComponent +public class PermissionsDaoComponentImpl extends HibernateDaoSupport implements PermissionsDaoComponent, TransactionalDao { private static final boolean INHERIT_PERMISSIONS_DEFAULT = true; public static final String QUERY_GET_PERMISSION = "permission.GetPermission"; @@ -61,11 +63,70 @@ public class PermissionsDaoComponentImpl extends HibernateDaoSupport implements private NodeDaoService nodeDaoService; + /** a uuid identifying this unique instance */ + private String uuid; + + /** + * + */ public PermissionsDaoComponentImpl() { - super(); + this.uuid = GUID.generate(); } + /** + * Checks equality by type and uuid + */ + public boolean equals(Object obj) + { + if (obj == null) + { + return false; + } + else if (!(obj instanceof PermissionsDaoComponentImpl)) + { + return false; + } + PermissionsDaoComponentImpl that = (PermissionsDaoComponentImpl) obj; + return this.uuid.equals(that.uuid); + } + + /** + * @see #uuid + */ + public int hashCode() + { + return uuid.hashCode(); + } + + /** + * Does this Session contain any changes which must be + * synchronized with the store? + * + * @return true => changes are pending + */ + public boolean isDirty() + { + // create a callback for the task + HibernateCallback callback = new HibernateCallback() + { + public Object doInHibernate(Session session) + { + return session.isDirty(); + } + }; + // execute the callback + return ((Boolean)getHibernateTemplate().execute(callback)).booleanValue(); + } + + /** + * Just flushes the session + */ + public void flush() + { + getSession().flush(); + } + public void setNodeDaoService(NodeDaoService nodeDaoService) { this.nodeDaoService = nodeDaoService; diff --git a/source/java/org/alfresco/repo/node/db/hibernate/HibernateNodeDaoServiceImpl.java b/source/java/org/alfresco/repo/node/db/hibernate/HibernateNodeDaoServiceImpl.java index a9f298b566..3c582044ac 100644 --- a/source/java/org/alfresco/repo/node/db/hibernate/HibernateNodeDaoServiceImpl.java +++ b/source/java/org/alfresco/repo/node/db/hibernate/HibernateNodeDaoServiceImpl.java @@ -35,6 +35,7 @@ import org.alfresco.repo.domain.hibernate.NodeStatusImpl; import org.alfresco.repo.domain.hibernate.StoreImpl; import org.alfresco.repo.node.db.NodeDaoService; import org.alfresco.repo.transaction.AlfrescoTransactionSupport; +import org.alfresco.repo.transaction.TransactionalDao; import org.alfresco.service.cmr.dictionary.InvalidTypeException; import org.alfresco.service.cmr.repository.AssociationRef; import org.alfresco.service.cmr.repository.ChildAssociationRef; @@ -54,7 +55,7 @@ import org.springframework.orm.hibernate3.support.HibernateDaoSupport; * * @author Derek Hulley */ -public class HibernateNodeDaoServiceImpl extends HibernateDaoSupport implements NodeDaoService +public class HibernateNodeDaoServiceImpl extends HibernateDaoSupport implements NodeDaoService, TransactionalDao { private static final String QUERY_GET_ALL_STORES = "store.GetAllStores"; private static final String QUERY_GET_CONTENT_DATA_STRINGS = "node.GetContentDataStrings"; diff --git a/source/java/org/alfresco/repo/transaction/AlfrescoTransactionSupport.java b/source/java/org/alfresco/repo/transaction/AlfrescoTransactionSupport.java index c2df1a06a9..357ceea309 100644 --- a/source/java/org/alfresco/repo/transaction/AlfrescoTransactionSupport.java +++ b/source/java/org/alfresco/repo/transaction/AlfrescoTransactionSupport.java @@ -24,10 +24,8 @@ import java.util.Map; import java.util.Set; import org.alfresco.error.AlfrescoRuntimeException; -import org.alfresco.repo.node.db.NodeDaoService; import org.alfresco.repo.node.integrity.IntegrityChecker; import org.alfresco.repo.search.impl.lucene.LuceneIndexerAndSearcher; -import org.alfresco.repo.search.impl.lucene.LuceneIndexerAndSearcherFactory; import org.alfresco.service.cmr.rule.RuleService; import org.alfresco.util.GUID; import org.apache.commons.logging.Log; @@ -107,8 +105,8 @@ public abstract class AlfrescoTransactionSupport { TransactionSynchronizationImpl synch = getSynchronization(); - Set services = synch.getNodeDaoServices(); - for (NodeDaoService service : services) + Set services = synch.getDaoServices(); + for (TransactionalDao service : services) { if (service.isDirty()) { @@ -196,20 +194,20 @@ public abstract class AlfrescoTransactionSupport * This method can be called repeatedly as long as the service being bound * implements equals and hashCode. * - * @param nodeDaoService + * @param daoService */ - public static void bindNodeDaoService(NodeDaoService nodeDaoService) + public static void bindDaoService(TransactionalDao daoService) { // get transaction-local synchronization TransactionSynchronizationImpl synch = getSynchronization(); // bind the service in - boolean bound = synch.getNodeDaoServices().add(nodeDaoService); + boolean bound = synch.getDaoServices().add(daoService); // done if (logger.isDebugEnabled()) { - logBoundService(nodeDaoService, bound); + logBoundService(daoService, bound); } } @@ -321,7 +319,7 @@ public abstract class AlfrescoTransactionSupport *

* The flush may include: *

    - *
  • {@link NodeDaoService#flush()}
  • + *
  • {@link TransactionalDao#flush()}
  • *
  • {@link RuleService#executePendingRules()}
  • *
  • {@link IntegrityChecker#checkIntegrity()}
  • *
@@ -425,7 +423,7 @@ public abstract class AlfrescoTransactionSupport private static class TransactionSynchronizationImpl extends TransactionSynchronizationAdapter { private final String txnId; - private final Set nodeDaoServices; + private final Set daoServices; private final Set integrityCheckers; private final Set lucenes; private final Set listeners; @@ -439,7 +437,7 @@ public abstract class AlfrescoTransactionSupport public TransactionSynchronizationImpl(String txnId) { this.txnId = txnId; - nodeDaoServices = new HashSet(3); + daoServices = new HashSet(3); integrityCheckers = new HashSet(3); lucenes = new HashSet(3); listeners = new HashSet(5); @@ -452,12 +450,12 @@ public abstract class AlfrescoTransactionSupport } /** - * @return Returns a set of NodeDaoService instances that will be called + * @return Returns a set of TransactionalDao instances that will be called * during end-of-transaction processing */ - public Set getNodeDaoServices() + public Set getDaoServices() { - return nodeDaoServices; + return daoServices; } /** @@ -500,7 +498,7 @@ public abstract class AlfrescoTransactionSupport StringBuilder sb = new StringBuilder(50); sb.append("TransactionSychronizationImpl") .append("[ txnId=").append(txnId) - .append(", node service=").append(nodeDaoServices.size()) + .append(", daos=").append(daoServices.size()) .append(", integrity=").append(integrityCheckers.size()) .append(", indexers=").append(lucenes.size()) .append(", resources=").append(resources) @@ -525,9 +523,9 @@ public abstract class AlfrescoTransactionSupport listener.flush(); } // flush changes - for (NodeDaoService nodeDaoServices : getNodeDaoServices()) + for (TransactionalDao daoService : getDaoServices()) { - nodeDaoServices.flush(); + daoService.flush(); } } diff --git a/source/java/org/alfresco/repo/transaction/TransactionalDao.java b/source/java/org/alfresco/repo/transaction/TransactionalDao.java new file mode 100644 index 0000000000..e0bcf9f155 --- /dev/null +++ b/source/java/org/alfresco/repo/transaction/TransactionalDao.java @@ -0,0 +1,26 @@ +package org.alfresco.repo.transaction; + + +/** + * Contract for a DAO to interact with a transaction. + * + * @author davidc + */ +public interface TransactionalDao +{ + /** + * Allows the dao to flush any consuming resources. This mechanism is + * used primarily during long-lived transactions to ensure that system resources + * are not used up. + *

+ * This method must not be used for implementing business logic. + */ + void flush(); + + /** + * Are there any pending changes which must be synchronized with the store? + * + * @return true => changes are pending + */ + public boolean isDirty(); +} diff --git a/source/java/org/alfresco/repo/transaction/NodeDaoServiceTransactionInterceptor.java b/source/java/org/alfresco/repo/transaction/TransactionalDaoInterceptor.java similarity index 70% rename from source/java/org/alfresco/repo/transaction/NodeDaoServiceTransactionInterceptor.java rename to source/java/org/alfresco/repo/transaction/TransactionalDaoInterceptor.java index 406f766c85..ccbe27a94e 100644 --- a/source/java/org/alfresco/repo/transaction/NodeDaoServiceTransactionInterceptor.java +++ b/source/java/org/alfresco/repo/transaction/TransactionalDaoInterceptor.java @@ -17,7 +17,6 @@ package org.alfresco.repo.transaction; import org.alfresco.error.AlfrescoRuntimeException; -import org.alfresco.repo.node.db.NodeDaoService; import org.aopalliance.intercept.MethodInterceptor; import org.aopalliance.intercept.MethodInvocation; import org.springframework.beans.factory.InitializingBean; @@ -31,16 +30,16 @@ import org.springframework.beans.factory.InitializingBean; * * @author Derek Hulley */ -public class NodeDaoServiceTransactionInterceptor implements MethodInterceptor, InitializingBean +public class TransactionalDaoInterceptor implements MethodInterceptor, InitializingBean { - private NodeDaoService nodeDaoService; + private TransactionalDao daoService; /** - * @param nodeDaoService the NodeDaoService to register + * @param daoService the NodeDaoService to register */ - public void setNodeDaoService(NodeDaoService nodeDaoService) + public void setDaoService(TransactionalDao daoService) { - this.nodeDaoService = nodeDaoService; + this.daoService = daoService; } /** @@ -48,15 +47,15 @@ public class NodeDaoServiceTransactionInterceptor implements MethodInterceptor, */ public void afterPropertiesSet() throws Exception { - if (nodeDaoService == null) + if (daoService == null) { - throw new AlfrescoRuntimeException("NodeDaoService is required: " + this); + throw new AlfrescoRuntimeException("TransactionalDao is required: " + this); } } public Object invoke(MethodInvocation invocation) throws Throwable { - AlfrescoTransactionSupport.bindNodeDaoService(nodeDaoService); + AlfrescoTransactionSupport.bindDaoService(daoService); // propogate the call return invocation.proceed(); }