Merged V2.2 to HEAD

8397: Fix for AR-2003, AR-2127, AR-2128 (Hibernate patch)


git-svn-id: https://svn.alfresco.com/repos/alfresco-enterprise/alfresco/HEAD/root@8506 c4b6b30b-aa2e-2d43-bbcb-ca4b014f7261
This commit is contained in:
Derek Hulley
2008-03-11 12:33:25 +00:00
parent dc9c207c88
commit fcf5487c5a
22 changed files with 1969 additions and 242 deletions

View File

@@ -34,6 +34,8 @@ import org.alfresco.repo.avm.AVMNodeConverter;
import org.alfresco.repo.avm.AVMRepository;
import org.alfresco.repo.domain.AccessControlListDAO;
import org.alfresco.repo.domain.DbAccessControlList;
import org.alfresco.repo.domain.hibernate.AclDaoComponentImpl.Indirection;
import org.alfresco.repo.search.AVMSnapShotTriggeredIndexingMethodInterceptor;
import org.alfresco.repo.security.authentication.AuthenticationUtil;
import org.alfresco.repo.security.authentication.AuthenticationUtil.RunAsWork;
import org.alfresco.repo.security.permissions.ACLType;
@@ -69,6 +71,10 @@ public class AVMAccessControlListDAO implements AccessControlListDAO
private AclDaoComponent aclDaoComponent;
private AVMSnapShotTriggeredIndexingMethodInterceptor avmSnapShotTriggeredIndexingMethodInterceptor;
private HibernateSessionHelper hibernateSessionHelper;
/**
* Default constructory.
*/
@@ -91,6 +97,16 @@ public class AVMAccessControlListDAO implements AccessControlListDAO
this.aclDaoComponent = aclDaoComponent;
}
public void setAvmSnapShotTriggeredIndexingMethodInterceptor(AVMSnapShotTriggeredIndexingMethodInterceptor avmSnapShotTriggeredIndexingMethodInterceptor)
{
this.avmSnapShotTriggeredIndexingMethodInterceptor = avmSnapShotTriggeredIndexingMethodInterceptor;
}
public void setHibernateSessionHelper(HibernateSessionHelper hibernateSessionHelper)
{
this.hibernateSessionHelper = hibernateSessionHelper;
}
public Long getIndirectAcl(NodeRef nodeRef)
{
Pair<Integer, String> avmVersionPath = AVMNodeConverter.ToAVMVersionPath(nodeRef);
@@ -233,37 +249,46 @@ public class AVMAccessControlListDAO implements AccessControlListDAO
{
inherited = aclDaoComponent.getInheritedAccessControlList(after);
}
updateChangedAclsImpl(startingPoint, changes, SetMode.ALL, inherited, after);
Map<Long, Set<Long>> indirections = buildIndirections();
updateChangedAclsImpl(startingPoint, changes, SetMode.ALL, inherited, after, indirections);
}
private void updateChangedAclsImpl(NodeRef startingPoint, List<AclChange> changes, SetMode mode, Long inherited, Long setAcl)
private void updateChangedAclsImpl(NodeRef startingPoint, List<AclChange> changes, SetMode mode, Long inherited, Long setAcl, Map<Long, Set<Long>> indirections)
{
HashMap<Long, Long> changeMap = new HashMap<Long, Long>();
HashSet<Long> unchangedSet = new HashSet<Long>();
for (AclChange change : changes)
hibernateSessionHelper.mark();
try
{
if (change.getBefore() == null)
HashMap<Long, Long> changeMap = new HashMap<Long, Long>();
HashSet<Long> unchangedSet = new HashSet<Long>();
for (AclChange change : changes)
{
// null is treated using the inherited acl
if (change.getBefore() == null)
{
// null is treated using the inherited acl
}
else if (!change.getBefore().equals(change.getAfter()))
{
changeMap.put(change.getBefore(), change.getAfter());
}
else
{
unchangedSet.add(change.getBefore());
}
}
else if (!change.getBefore().equals(change.getAfter()))
{
changeMap.put(change.getBefore(), change.getAfter());
}
else
{
unchangedSet.add(change.getBefore());
}
}
unchangedSet.add(inherited);
unchangedSet.add(setAcl);
unchangedSet.add(inherited);
unchangedSet.add(setAcl);
if (inherited != null)
{
updateReferencingLayeredAcls(startingPoint, inherited);
if (inherited != null)
{
updateReferencingLayeredAcls(startingPoint, inherited, indirections);
}
updateInheritedChangedAcls(startingPoint, changeMap, unchangedSet, inherited, mode, indirections);
updateLayeredAclsChangedByInheritance(changes, changeMap, unchangedSet, indirections);
}
finally
{
hibernateSessionHelper.resetAndRemoveMark();
}
updateInheritedChangedAcls(startingPoint, changeMap, unchangedSet, inherited, mode);
updateLayeredAclsChangedByInheritance(changes, changeMap, unchangedSet);
}
public void forceCopy(NodeRef nodeRef)
@@ -283,10 +308,33 @@ public class AVMAccessControlListDAO implements AccessControlListDAO
{
throw new InvalidNodeRefException(nodeRef);
}
}
private void updateReferencingLayeredAcls(NodeRef node, Long inherited)
private Map<Long, Set<Long>> buildIndirections()
{
Map<Long, Set<Long>> answer = new HashMap<Long, Set<Long>>();
List<Indirection> indirections = aclDaoComponent.getAvmIndirections();
for (Indirection indirection : indirections)
{
AVMNodeDescriptor toDesc = fAVMService.lookup(indirection.getToVersion(), indirection.getTo(), true);
if (toDesc != null)
{
Long toId = Long.valueOf(toDesc.getId());
Set<Long> referees = answer.get(toId);
if (referees == null)
{
referees = new HashSet<Long>();
answer.put(toId, referees);
}
referees.add(indirection.getFrom());
}
}
return answer;
}
private void updateReferencingLayeredAcls(NodeRef node, Long inherited, Map<Long, Set<Long>> indirections)
{
Pair<Integer, String> avmVersionPath = AVMNodeConverter.ToAVMVersionPath(node);
int version = avmVersionPath.getFirst();
@@ -304,42 +352,39 @@ public class AVMAccessControlListDAO implements AccessControlListDAO
}
else
{
List<Pair<Integer, String>> paths = fAVMService.getHeadPaths(descriptor);
for (Pair<Integer, String> current : paths)
Set<Long> avmNodeIds = indirections.get(Long.valueOf(descriptor.getId()));
if (avmNodeIds != null)
{
List<Long> avmNodeIds = aclDaoComponent.getAvmNodesByIndirection(current.getSecond());
for (Long id : avmNodeIds)
{
// need to fix up inheritance as is has changed
AVMNodeDescriptor layerDesc = new AVMNodeDescriptor(null, null, 0, null, null, null, 0, 0, 0, id, null, 0, null, 0, false, 0, false, 0, 0);
List<Pair<Integer, String>> layerPaths = fAVMRepository.getHeadPaths(layerDesc);
// Update all locations with the updated ACL
for (Pair<Integer, String> layerPath : layerPaths)
{
AVMNodeDescriptor test = fAVMService.lookup(-1, layerPath.getSecond());
if (test.isPrimary())
DbAccessControlList target = getAclAsSystem(-1, layerPath.getSecond());
if (target != null)
{
DbAccessControlList target = getAclAsSystem(-1, layerPath.getSecond());
if (target != null)
if (target.getAclType() == ACLType.LAYERED)
{
if (target.getAclType() == ACLType.LAYERED)
{
fAVMService.forceCopy(layerPath.getSecond());
fAVMService.forceCopy(layerPath.getSecond());
List<AclChange> layeredChanges = aclDaoComponent.mergeInheritedAccessControlList(inherited, target.getId());
NodeRef layeredNode = AVMNodeConverter.ToNodeRef(-1, layerPath.getSecond());
for (AclChange change : layeredChanges)
List<AclChange> layeredChanges = aclDaoComponent.mergeInheritedAccessControlList(inherited, target.getId());
NodeRef layeredNode = AVMNodeConverter.ToNodeRef(-1, layerPath.getSecond());
for (AclChange change : layeredChanges)
{
if (change.getBefore().equals(target.getId()))
{
if (change.getBefore().equals(target.getId()))
Long newInherited = null;
if (change.getAfter() != null)
{
Long newInherited = null;
if (change.getAfter() != null)
{
newInherited = aclDaoComponent.getInheritedAccessControlList(change.getAfter());
}
updateChangedAclsImpl(layeredNode, layeredChanges, SetMode.DIRECT_ONLY, newInherited, change.getAfter());
break;
newInherited = aclDaoComponent.getInheritedAccessControlList(change.getAfter());
}
updateChangedAclsImpl(layeredNode, layeredChanges, SetMode.DIRECT_ONLY, newInherited, change.getAfter(), indirections);
break;
}
}
}
@@ -355,7 +400,7 @@ public class AVMAccessControlListDAO implements AccessControlListDAO
}
}
private void updateLayeredAclsChangedByInheritance(List<AclChange> changes, HashMap<Long, Long> changeMap, Set<Long> unchanged)
private void updateLayeredAclsChangedByInheritance(List<AclChange> changes, HashMap<Long, Long> changeMap, Set<Long> unchanged, Map<Long, Set<Long>> indirections)
{
for (AclChange change : changes)
{
@@ -375,14 +420,16 @@ public class AVMAccessControlListDAO implements AccessControlListDAO
// No need to force COW - any inherited ACL will have COWED if the top ACL required it
setAclAsSystem(path.getSecond(), aclDaoComponent.getDbAccessControlList(change.getAfter()));
NodeRef layeredNode = AVMNodeConverter.ToNodeRef(-1, path.getSecond());
updateInheritedChangedAcls(layeredNode, changeMap, unchanged, aclDaoComponent.getInheritedAccessControlList(change.getAfter()), SetMode.DIRECT_ONLY);
updateInheritedChangedAcls(layeredNode, changeMap, unchanged, aclDaoComponent.getInheritedAccessControlList(change.getAfter()), SetMode.DIRECT_ONLY,
indirections);
}
}
}
}
}
private void updateInheritedChangedAcls(NodeRef startingPoint, HashMap<Long, Long> changeMap, Set<Long> unchanged, Long unsetAcl, SetMode mode)
private void updateInheritedChangedAcls(NodeRef startingPoint, HashMap<Long, Long> changeMap, Set<Long> unchanged, Long unsetAcl, SetMode mode,
Map<Long, Set<Long>> indirections)
{
// Walk children and fix up any that reference the given list ..
Pair<Integer, String> avmVersionPath = AVMNodeConverter.ToAVMVersionPath(startingPoint);
@@ -404,9 +451,10 @@ public class AVMAccessControlListDAO implements AccessControlListDAO
if (descriptor.isLayeredDirectory())
{
setInheritanceForDirectChildren(descriptor, changeMap, aclDaoComponent.getInheritedAccessControlList(getAclAsSystem(-1, descriptor.getPath()).getId()));
setInheritanceForDirectChildren(descriptor, changeMap, aclDaoComponent.getInheritedAccessControlList(getAclAsSystem(-1, descriptor.getPath()).getId()),
indirections);
}
fixUpAcls(descriptor, changeMap, unchanged, unsetAcl, mode);
fixUpAcls(descriptor, changeMap, unchanged, unsetAcl, mode, indirections);
}
}
catch (AVMException e)
@@ -415,9 +463,9 @@ public class AVMAccessControlListDAO implements AccessControlListDAO
}
}
private void fixUpAcls(AVMNodeDescriptor descriptor, Map<Long, Long> changes, Set<Long> unchanged, Long unsetAcl, SetMode mode)
private void fixUpAcls(AVMNodeDescriptor descriptor, Map<Long, Long> changes, Set<Long> unchanged, Long unsetAcl, SetMode mode, Map<Long, Set<Long>> indirections)
{
DbAccessControlList acl = getAclAsSystem(-1, descriptor.getPath());
DbAccessControlList acl = getAclAsSystem(-1, descriptor.getPath());
Long id = null;
if (acl != null)
{
@@ -429,7 +477,7 @@ public class AVMAccessControlListDAO implements AccessControlListDAO
// No need to force COW - ACL should have COWed if required
setAclAsSystem(descriptor.getPath(), aclDaoComponent.getDbAccessControlList(unsetAcl));
NodeRef nodeRef = AVMNodeConverter.ToNodeRef(-1, descriptor.getPath());
updateReferencingLayeredAcls(nodeRef, unsetAcl);
updateReferencingLayeredAcls(nodeRef, unsetAcl, indirections);
}
else if (changes.containsKey(id))
{
@@ -466,16 +514,24 @@ public class AVMAccessControlListDAO implements AccessControlListDAO
}
for (AVMNodeDescriptor child : children.values())
{
fixUpAcls(child, changes, unchanged, unsetAcl, mode);
hibernateSessionHelper.mark();
try
{
fixUpAcls(child, changes, unchanged, unsetAcl, mode, indirections);
}
finally
{
hibernateSessionHelper.resetAndRemoveMark();
}
}
}
}
private void setInheritanceForDirectChildren(AVMNodeDescriptor descriptor, Map<Long, Long> changeMap, Long mergeFrom)
private void setInheritanceForDirectChildren(AVMNodeDescriptor descriptor, Map<Long, Long> changeMap, Long mergeFrom, Map<Long, Set<Long>> indirections)
{
List<AclChange> changes = new ArrayList<AclChange>();
setFixedAcls(descriptor, mergeFrom, changes, SetMode.DIRECT_ONLY, false);
setFixedAcls(descriptor, mergeFrom, changes, SetMode.DIRECT_ONLY, false, indirections);
for (AclChange change : changes)
{
if (!change.getBefore().equals(change.getAfter()))
@@ -498,9 +554,10 @@ public class AVMAccessControlListDAO implements AccessControlListDAO
String path = avmVersionPath.getSecond();
try
{
Map<Long, Set<Long>> indirections = buildIndirections();
List<AclChange> changes = new ArrayList<AclChange>();
AVMNodeDescriptor descriptor = fAVMService.lookup(version, path);
setFixedAcls(descriptor, mergeFrom, changes, SetMode.ALL, false);
setFixedAcls(descriptor, mergeFrom, changes, SetMode.ALL, false, indirections);
return changes;
}
@@ -510,7 +567,7 @@ public class AVMAccessControlListDAO implements AccessControlListDAO
}
}
public void setFixedAcls(AVMNodeDescriptor descriptor, Long mergeFrom, List<AclChange> changes, SetMode mode, boolean set)
public void setFixedAcls(AVMNodeDescriptor descriptor, Long mergeFrom, List<AclChange> changes, SetMode mode, boolean set, Map<Long, Set<Long>> indirections)
{
if (descriptor == null)
{
@@ -527,7 +584,7 @@ public class AVMAccessControlListDAO implements AccessControlListDAO
if (previous == null)
{
NodeRef nodeRef = AVMNodeConverter.ToNodeRef(-1, descriptor.getPath());
updateReferencingLayeredAcls(nodeRef, mergeFrom);
updateReferencingLayeredAcls(nodeRef, mergeFrom, indirections);
}
}
@@ -554,8 +611,15 @@ public class AVMAccessControlListDAO implements AccessControlListDAO
if (acl == null)
{
setFixedAcls(child, mergeFrom, changes, mode, true);
hibernateSessionHelper.mark();
try
{
setFixedAcls(child, mergeFrom, changes, mode, true, indirections);
}
finally
{
hibernateSessionHelper.resetAndRemoveMark();
}
}
else if (acl.getAclType() == ACLType.LAYERED)
{
@@ -573,16 +637,32 @@ public class AVMAccessControlListDAO implements AccessControlListDAO
{
if (change.getBefore().equals(acl.getId()))
{
setAclAsSystem(child.getPath(), aclDaoComponent.getDbAccessControlList(change.getAfter()));
setFixedAcls(child, aclDaoComponent.getInheritedAccessControlList(change.getAfter()), newChanges, SetMode.DIRECT_ONLY, false);
changes.addAll(newChanges);
break;
hibernateSessionHelper.mark();
try
{
setAclAsSystem(child.getPath(), aclDaoComponent.getDbAccessControlList(change.getAfter()));
setFixedAcls(child, aclDaoComponent.getInheritedAccessControlList(change.getAfter()), newChanges, SetMode.DIRECT_ONLY, false, indirections);
changes.addAll(newChanges);
break;
}
finally
{
hibernateSessionHelper.resetAndRemoveMark();
}
}
}
}
else
{
setFixedAcls(child, mergeFrom, changes, mode, true);
hibernateSessionHelper.mark();
try
{
setFixedAcls(child, mergeFrom, changes, mode, true, indirections);
}
finally
{
hibernateSessionHelper.resetAndRemoveMark();
}
}
}
@@ -599,11 +679,31 @@ public class AVMAccessControlListDAO implements AccessControlListDAO
{
CounterSet result = new CounterSet();
List<AVMStoreDescriptor> stores = fAVMService.getStores();
Map<Long, Set<Long>> indirections = buildIndirections();
for (AVMStoreDescriptor store : stores)
{
AVMNodeDescriptor root = fAVMService.getStoreRoot(-1, store.getName());
CounterSet update = fixOldAvmAcls(root);
result.add(update);
CounterSet update;
switch (avmSnapShotTriggeredIndexingMethodInterceptor.getStoreType(store.getName()))
{
case AUTHOR:
case AUTHOR_PREVIEW:
case AUTHOR_WORKFLOW:
case AUTHOR_WORKFLOW_PREVIEW:
case STAGING:
case STAGING_PREVIEW:
case WORKFLOW:
case WORKFLOW_PREVIEW:
AVMNodeDescriptor www = fAVMService.lookup(-1, store.getName() + ":/www");
update = fixOldAvmAcls(www, false, indirections);
result.add(update);
break;
case UNKNOWN:
default:
update = fixOldAvmAcls(root, true, indirections);
result.add(update);
}
}
HashMap<ACLType, Integer> toReturn = new HashMap<ACLType, Integer>();
@@ -614,20 +714,32 @@ public class AVMAccessControlListDAO implements AccessControlListDAO
toReturn.put(ACLType.OLD, Integer.valueOf(result.get(ACLType.OLD).getCounter()));
toReturn.put(ACLType.SHARED, Integer.valueOf(result.get(ACLType.SHARED).getCounter()));
return toReturn;
}
private CounterSet fixOldAvmAcls(AVMNodeDescriptor node)
private CounterSet fixOldAvmAcls(AVMNodeDescriptor node, boolean searchDirectories, Map<Long, Set<Long>> indirections)
{
hibernateSessionHelper.mark();
try
{
return fixOldAvmAclsImpl(node, searchDirectories, indirections);
}
finally
{
hibernateSessionHelper.resetAndRemoveMark();
}
}
private CounterSet fixOldAvmAclsImpl(AVMNodeDescriptor node, boolean searchDirectories, Map<Long, Set<Long>> indirections)
{
CounterSet result = new CounterSet();
// Do the children first
if (node.isDirectory())
if (searchDirectories && node.isDirectory())
{
Map<String, AVMNodeDescriptor> children = fAVMRepository.getListingDirect(node, true);
for (AVMNodeDescriptor child : children.values())
{
CounterSet update = fixOldAvmAcls(child);
CounterSet update = fixOldAvmAcls(child, searchDirectories, indirections);
result.add(update);
}
}
@@ -660,7 +772,7 @@ public class AVMAccessControlListDAO implements AccessControlListDAO
List<AclChange> changes = new ArrayList<AclChange>();
setFixedAcls(node, aclDaoComponent.getInheritedAccessControlList(id), changes, SetMode.DIRECT_ONLY, false);
setFixedAcls(node, aclDaoComponent.getInheritedAccessControlList(id), changes, SetMode.DIRECT_ONLY, false, indirections);
for (AclChange change : changes)
{
@@ -706,7 +818,7 @@ public class AVMAccessControlListDAO implements AccessControlListDAO
}
List<AclChange> changes = new ArrayList<AclChange>();
setFixedAcls(node, aclDaoComponent.getInheritedAccessControlList(getAclAsSystem(-1, node.getPath()).getId()), changes, SetMode.DIRECT_ONLY, false);
setFixedAcls(node, aclDaoComponent.getInheritedAccessControlList(getAclAsSystem(-1, node.getPath()).getId()), changes, SetMode.DIRECT_ONLY, false, indirections);
for (AclChange change : changes)
{
@@ -746,7 +858,7 @@ public class AVMAccessControlListDAO implements AccessControlListDAO
}
List<AclChange> changes = new ArrayList<AclChange>();
setFixedAcls(node, aclDaoComponent.getInheritedAccessControlList(getAclAsSystem(-1, node.getPath()).getId()), changes, SetMode.DIRECT_ONLY, false);
setFixedAcls(node, aclDaoComponent.getInheritedAccessControlList(getAclAsSystem(-1, node.getPath()).getId()), changes, SetMode.DIRECT_ONLY, false, indirections);
for (AclChange change : changes)
{
@@ -815,47 +927,55 @@ public class AVMAccessControlListDAO implements AccessControlListDAO
counter += i;
}
}
private DbAccessControlList getStoreAclAsSystem(final String storeName)
{
return AuthenticationUtil.runAs(new RunAsWork<DbAccessControlList>(){
return AuthenticationUtil.runAs(new RunAsWork<DbAccessControlList>()
{
public DbAccessControlList doWork() throws Exception
{
return fAVMRepository.getStoreAcl(storeName);
}}, AuthenticationUtil.getSystemUserName());
}
}, AuthenticationUtil.getSystemUserName());
}
private void setStoreAclAsSystem(final String storeName, final DbAccessControlList acl)
{
AuthenticationUtil.runAs(new RunAsWork<Object>(){
AuthenticationUtil.runAs(new RunAsWork<Object>()
{
public Object doWork() throws Exception
{
fAVMRepository.setStoreAcl(storeName, acl);
return null;
}}, AuthenticationUtil.getSystemUserName());
}
}, AuthenticationUtil.getSystemUserName());
}
private DbAccessControlList getAclAsSystem(final int version, final String path)
{
return AuthenticationUtil.runAs(new RunAsWork<DbAccessControlList>(){
return AuthenticationUtil.runAs(new RunAsWork<DbAccessControlList>()
{
public DbAccessControlList doWork() throws Exception
{
return fAVMRepository.getACL(version, path);
}}, AuthenticationUtil.getSystemUserName());
}
}, AuthenticationUtil.getSystemUserName());
}
private void setAclAsSystem(final String path, final DbAccessControlList acl)
{
AuthenticationUtil.runAs(new RunAsWork<Object>(){
AuthenticationUtil.runAs(new RunAsWork<Object>()
{
public Object doWork() throws Exception
{
fAVMRepository.setACL(path, acl);
return null;
}}, AuthenticationUtil.getSystemUserName());
}
}, AuthenticationUtil.getSystemUserName());
}
public DbAccessControlList getAccessControlList(StoreRef storeRef)
@@ -869,7 +989,7 @@ public class AVMAccessControlListDAO implements AccessControlListDAO
throw new InvalidStoreRefException(storeRef);
}
}
public void setAccessControlList(StoreRef storeRef, DbAccessControlList acl)
{
try
@@ -881,6 +1001,5 @@ public class AVMAccessControlListDAO implements AccessControlListDAO
throw new InvalidStoreRefException(storeRef);
}
}
}

View File

@@ -25,6 +25,7 @@
package org.alfresco.repo.domain.hibernate;
import java.io.Serializable;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.Collections;
import java.util.HashSet;
@@ -32,6 +33,7 @@ import java.util.List;
import java.util.Set;
import java.util.zip.CRC32;
import org.alfresco.error.AlfrescoRuntimeException;
import org.alfresco.repo.cache.SimpleCache;
import org.alfresco.repo.domain.DbAccessControlEntry;
import org.alfresco.repo.domain.DbAccessControlList;
@@ -60,8 +62,10 @@ import org.alfresco.service.namespace.QName;
import org.alfresco.util.GUID;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.hibernate.HibernateException;
import org.hibernate.Query;
import org.hibernate.Session;
import org.jgroups.tests.DeadlockTest.InRpc;
import org.springframework.orm.hibernate3.HibernateCallback;
import org.springframework.orm.hibernate3.support.HibernateDaoSupport;
@@ -92,12 +96,15 @@ public class AclDaoComponentImpl extends HibernateDaoSupport implements AclDaoCo
static String QUERY_GET_AVM_NODES_BY_ACL = "permission.FindAvmNodesByACL";
static String QUERY_GET_AVM_NODES_BY_INDIRECTION = "permission.FindAvmNodesIndirection";
static String QUERY_GET_LATEST_ACL_BY_ACLID = "permission.FindLatestAclByGuid";
static String QUERY_GET_LAYERED_DIRECTORIES = "permission.GetLayeredDirectories";
static String QUERY_GET_LAYERED_FILES = "permission.GetLayeredFiles";
/** Access to QName entities */
private QNameDAO qnameDAO;
/** a transactionally-safe cache to be injected */
private SimpleCache<Long, AccessControlList> aclCache;
@@ -1217,9 +1224,9 @@ public class AclDaoComponentImpl extends HibernateDaoSupport implements AclDaoCo
};
DbAuthority authority = null;
List<DbAuthority> authorities = (List<DbAuthority>) getHibernateTemplate().execute(callback);
for(DbAuthority found : authorities)
for (DbAuthority found : authorities)
{
if(found.getAuthority().equals(ace.getAuthority()))
if (found.getAuthority().equals(ace.getAuthority()))
{
authority = found;
break;
@@ -1239,7 +1246,7 @@ public class AclDaoComponentImpl extends HibernateDaoSupport implements AclDaoCo
final QName permissionQName = ace.getPermission().getQName();
final String permissionName = ace.getPermission().getName();
final QNameEntity permissionQNameEntity = qnameDAO.getOrCreateQNameEntity(permissionQName);
callback = new HibernateCallback()
{
public Object doInHibernate(Session session)
@@ -1312,14 +1319,13 @@ public class AclDaoComponentImpl extends HibernateDaoSupport implements AclDaoCo
return changes;
}
private long getCrc(String str)
{
CRC32 crc = new CRC32();
crc.update(str.getBytes());
return crc.getValue();
}
public List<AclChange> enableInheritance(Long id, Long parent)
{
List<AclChange> changes = new ArrayList<AclChange>();
@@ -1538,22 +1544,6 @@ public class AclDaoComponentImpl extends HibernateDaoSupport implements AclDaoCo
return avmNodeIds;
}
@SuppressWarnings("unchecked")
public List<Long> getAvmNodesByIndirection(final String indirection)
{
HibernateCallback callback = new HibernateCallback()
{
public Object doInHibernate(Session session)
{
Query query = session.getNamedQuery(QUERY_GET_AVM_NODES_BY_INDIRECTION);
query.setParameter("indirection", indirection);
return query.list();
}
};
List<Long> avmNodeIds = (List<Long>) getHibernateTemplate().execute(callback);
return avmNodeIds;
}
@SuppressWarnings("unchecked")
private List<AclChange> disableInheritanceImpl(Long id, boolean setInheritedOnAcl, DbAccessControlList acl)
{
@@ -1748,14 +1738,6 @@ public class AclDaoComponentImpl extends HibernateDaoSupport implements AclDaoCo
return ((Boolean) getHibernateTemplate().execute(callback)).booleanValue();
}
/**
* Just flushes the session
*/
public void flush()
{
getSession().flush();
}
/**
* NO-OP
*/
@@ -1832,4 +1814,155 @@ public class AclDaoComponentImpl extends HibernateDaoSupport implements AclDaoCo
}
}
/**
* Get the total number of head nodes in the repository
*
* @return
*/
public Long getAVMHeadNodeCount()
{
try
{
Session session = getSession();
session.connection().setTransactionIsolation(1);
Query query = getSession().getNamedQuery("permission.GetAVMHeadNodeCount");
Long answer = (Long) query.uniqueResult();
return answer;
}
catch (SQLException e)
{
throw new AlfrescoRuntimeException("Failed to set TX isolation level");
}
}
public Long getMaxAclId()
{
try
{
Session session = getSession();
session.connection().setTransactionIsolation(1);
Query query = getSession().getNamedQuery("permission.GetMaxAclId");
Long answer = (Long) query.uniqueResult();
return answer;
}
catch (SQLException e)
{
throw new AlfrescoRuntimeException("Failed to set TX isolation level");
}
}
public Long getAVMNodeCountWithNewACLS(Long above)
{
try
{
Session session = getSession();
session.connection().setTransactionIsolation(1);
Query query = getSession().getNamedQuery("permission.GetAVMHeadNodeCountWherePermissionsHaveChanged");
query.setParameter("above", above);
Long answer = (Long) query.uniqueResult();
return answer;
}
catch (SQLException e)
{
throw new AlfrescoRuntimeException("Failed to set TX isolation level");
}
}
@SuppressWarnings("unchecked")
public List<Indirection> getLayeredDirectories()
{
HibernateCallback callback = new HibernateCallback()
{
public Object doInHibernate(Session session)
{
Query query = session.getNamedQuery(QUERY_GET_LAYERED_DIRECTORIES);
return query.list();
}
};
List<Object[]> results = (List<Object[]>) getHibernateTemplate().execute(callback);
ArrayList<Indirection> indirections = new ArrayList<Indirection>(results.size());
for(Object[] row : results)
{
Long from = (Long)row[0];
String to = (String) row[1];
Integer version = (Integer) row[2];
indirections.add(new Indirection(from, to, version));
}
return indirections;
}
@SuppressWarnings("unchecked")
public List<Indirection> getLayeredFiles()
{
HibernateCallback callback = new HibernateCallback()
{
public Object doInHibernate(Session session)
{
Query query = session.getNamedQuery(QUERY_GET_LAYERED_FILES);
return query.list();
}
};
List<Object[]> results = (List<Object[]>) getHibernateTemplate().execute(callback);
ArrayList<Indirection> indirections = new ArrayList<Indirection>(results.size());
for(Object[] row : results)
{
Long from = (Long)row[0];
String to = (String) row[1];
Integer version = (Integer) row[2];
indirections.add(new Indirection(from, to, version));
}
return indirections;
}
public List<Indirection> getAvmIndirections()
{
List<Indirection> dirList = getLayeredDirectories();
List<Indirection> fileList = getLayeredFiles();
ArrayList<Indirection> answer = new ArrayList<Indirection>(dirList.size() + fileList.size());
answer.addAll(dirList);
answer.addAll(fileList);
return answer;
}
public void flush()
{
getSession().flush();
}
public static class Indirection
{
Long from;
String to;
Integer toVersion;
Indirection(Long from, String to, Integer toVersion)
{
this.from = from;
this.to = to;
this.toVersion = toVersion;
}
public Long getFrom()
{
return from;
}
public String getTo()
{
return to;
}
public Integer getToVersion()
{
return toVersion;
}
}
}

View File

@@ -0,0 +1,22 @@
package org.alfresco.repo.domain.hibernate;
import org.hibernate.HibernateException;
import org.hibernate.event.LoadEvent;
import org.hibernate.event.LoadEventListener;
import org.hibernate.proxy.HibernateProxy;
import net.sf.cglib.proxy.Enhancer;
public class HibernateLoadListener implements LoadEventListener
{
public void onLoad(LoadEvent event, LoadType loadType) throws HibernateException
{
Object obj = event.getResult();
if (obj instanceof HibernateProxy) {
Enhancer.registerCallbacks(obj.getClass(),null);
}
}
}

View File

@@ -0,0 +1,120 @@
/*
* Copyright (C) 2005-2007 Alfresco Software Limited.
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
* As a special exception to the terms and conditions of version 2.0 of
* the GPL, you may redistribute this Program in connection with Free/Libre
* and Open Source Software ("FLOSS") applications as described in Alfresco's
* FLOSS exception. You should have recieved a copy of the text describing
* the FLOSS exception, and it is also available here:
* http://www.alfresco.com/legal/licensing"
*/
package org.alfresco.repo.domain.hibernate;
import java.util.List;
import org.alfresco.repo.transaction.AlfrescoTransactionSupport;
import org.springframework.orm.hibernate3.support.HibernateDaoSupport;
/**
* Utililty support against hibernate sessions. Supported by a super event listener which is registered on the even
* listener of the hibernate session.
*
* @author andyh
*/
public class HibernateSessionHelper extends HibernateDaoSupport implements HibernateSessionSupport
{
/**
*
*/
private static final long serialVersionUID = -2532286150392812816L;
private static final String HIBERNATE_SESSION_EVENT_LISTENER = "HibernateSessionEventListener";
public void mark()
{
HibernateSessionHelperResourceProvider resource = getResource();
resource.mark(getSession());
}
public void mark(String label)
{
HibernateSessionHelperResourceProvider resource = getResource();
resource.mark(getSession(), label);
}
public void reset()
{
HibernateSessionHelperResourceProvider resource = getResource();
resource.reset(getSession());
}
public void reset(String label)
{
HibernateSessionHelperResourceProvider resource = getResource();
resource.reset(getSession(), label);
}
public void removeMark()
{
HibernateSessionHelperResourceProvider resource = getResource();
resource.removeMark(getSession());
}
public void removeMark(String label)
{
HibernateSessionHelperResourceProvider resource = getResource();
resource.removeMark(getSession(), label);
}
public void resetAndRemoveMark()
{
HibernateSessionHelperResourceProvider resource = getResource();
resource.resetAndRemoveMark(getSession());
}
public void resetAndRemoveMark(String label)
{
HibernateSessionHelperResourceProvider resource = getResource();
resource.resetAndRemoveMark(getSession(), label);
}
public List<String> getMarks()
{
HibernateSessionHelperResourceProvider resource = getResource();
return resource.getMarks(getSession());
}
public String getCurrentMark()
{
HibernateSessionHelperResourceProvider resource = getResource();
return resource.getCurrentMark();
}
public static HibernateSessionHelperResourceProvider getResource()
{
HibernateSessionHelperResourceProvider listener = (HibernateSessionHelperResourceProvider) AlfrescoTransactionSupport.getResource(HIBERNATE_SESSION_EVENT_LISTENER);
if (listener == null)
{
listener = new HibernateSessionHelperResource();
AlfrescoTransactionSupport.bindResource(HIBERNATE_SESSION_EVENT_LISTENER, listener);
}
return listener;
}
}

View File

@@ -0,0 +1,269 @@
/*
* Copyright (C) 2005-2007 Alfresco Software Limited.
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
* As a special exception to the terms and conditions of version 2.0 of
* the GPL, you may redistribute this Program in connection with Free/Libre
* and Open Source Software ("FLOSS") applications as described in Alfresco's
* FLOSS exception. You should have recieved a copy of the text describing
* the FLOSS exception, and it is also available here:
* http://www.alfresco.com/legal/licensing"
*/
package org.alfresco.repo.domain.hibernate;
import java.util.ArrayList;
import java.util.HashSet;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Set;
import org.alfresco.util.GUID;
import org.hibernate.CacheMode;
import org.hibernate.Session;
import org.hibernate.engine.EntityKey;
import com.sun.corba.se.spi.legacy.connection.GetEndPointInfoAgainException;
/**
* Support to (optionally) listen to hibernate events generated by a hibernate session. The tracking is bound to a
* transaction resource
*
* @author andyh
*/
public class HibernateSessionHelperResource implements HibernateSessionHelperResourceProvider
{
LinkedHashMap<String, Set<EntityKey>> marks = new LinkedHashMap<String, Set<EntityKey>>();
String currentMark = null;
HibernateSessionHelperResource()
{
}
public String getCurrentMark()
{
return currentMark;
}
public List<String> getMarks(Session session)
{
ArrayList<String> answer = new ArrayList<String>(marks.size());
for (String key : marks.keySet())
{
answer.add(key);
}
return answer;
}
public void mark(Session session)
{
Thread thread = Thread.currentThread();
String guid = GUID.generate();
mark(session, guid);
}
@SuppressWarnings("unchecked")
public void mark(Session session, String label)
{
session.flush();
if (label == null)
{
throw new HibernateSessionHelperResourceException("Null key is not supported");
}
if (marks.containsKey(label))
{
throw new HibernateSessionHelperResourceException("Key already exists - " + label);
}
if (marks.size() == 0)
{
SessionSizeResourceManager.setDisableInTransaction();
}
HashSet<EntityKey> mark = new HashSet<EntityKey>((Set<EntityKey>) session.getStatistics().getEntityKeys());
marks.put(label, mark);
currentMark = label;
//System.out.println("Mark "+marks.size()+" "+currentMark);
}
public void removeMark(Session session)
{
if (currentMark != null)
{
removeMark(session, currentMark);
}
else
{
throw new HibernateSessionHelperResourceException("No current mark");
}
}
public void removeMark(Session session, String label)
{
if (label == null)
{
throw new HibernateSessionHelperResourceException("Null key is not supported");
}
if (!marks.containsKey(label))
{
throw new HibernateSessionHelperResourceException("Key does not exist - " + label);
}
if (marks.size() > 0)
{
marks.remove(label);
if (label.equals(currentMark))
{
currentMark = getLastMarkOrNull();
}
}
if (marks.size() == 0)
{
SessionSizeResourceManager.setEnableInTransaction();
}
}
public void reset(Session session)
{
if (currentMark != null)
{
doResetAndRemove(session, currentMark, false);
}
else
{
throw new HibernateSessionHelperResourceException("No current mark");
}
}
public void reset(Session session, String label)
{
doResetAndRemove(session, label, false);
}
public void resetAndRemoveMark(Session session)
{
if (currentMark != null)
{
doResetAndRemove(session, currentMark, true);
}
else
{
throw new HibernateSessionHelperResourceException("No current mark");
}
}
public void resetAndRemoveMark(Session session, String label)
{
doResetAndRemove(session, label, true);
}
@SuppressWarnings("unchecked")
private void doResetAndRemove(Session session, String label, boolean remove)
{
if (label == null)
{
throw new HibernateSessionHelperResourceException("Null key is not supported");
}
if (!marks.containsKey(label))
{
throw new HibernateSessionHelperResourceException("Key does not exist - " + label);
}
if (marks.size() > 0)
{
session.flush();
Set<EntityKey> check = marks.get(label);
Set<EntityKey> current = new HashSet<EntityKey>((Set<EntityKey>) session.getStatistics().getEntityKeys());
Set<Object> toEvict = new HashSet<Object>(Math.max((int) (current.size() / .75f) + 1, 16));
for (EntityKey key : current)
{
if (!check.contains(key))
{
if (!key.getEntityName().startsWith("org.alfresco"))
{
System.out.println("Oops: " + key.getEntityName());
}
if(key.getEntityName().equals(QNameEntityImpl.class.getName()))
{
//System.out.println("Skipping: " + key.getEntityName());
continue;
}
Object val = session.get(key.getEntityName(), key.getIdentifier());
if (val != null)
{
toEvict.add(val);
}
}
}
for (Object evitee : toEvict)
{
session.evict(evitee);
}
String last;
while ((last = getLastMarkOrNull()) != null)
{
if (!label.equals(last))
{
marks.remove(last);
}
else
{
if (remove)
{
marks.remove(last);
}
break;
}
}
currentMark = getLastMarkOrNull();
if (marks.size() == 0)
{
SessionSizeResourceManager.setEnableInTransaction();
}
//System.out.println("Removed "+marks.size()+" "+label);
}
}
private String getLastMarkOrNull()
{
String mark = null;
for (String key : marks.keySet())
{
mark = key;
}
return mark;
}
}

View File

@@ -0,0 +1,37 @@
package org.alfresco.repo.domain.hibernate;
import org.alfresco.error.AlfrescoRuntimeException;
public class HibernateSessionHelperResourceException extends AlfrescoRuntimeException
{
/**
*
*/
private static final long serialVersionUID = 2935681199033295625L;
public HibernateSessionHelperResourceException(String msgId, Object[] msgParams, Throwable cause)
{
super(msgId, msgParams, cause);
// TODO Auto-generated constructor stub
}
public HibernateSessionHelperResourceException(String msgId, Object[] msgParams)
{
super(msgId, msgParams);
// TODO Auto-generated constructor stub
}
public HibernateSessionHelperResourceException(String msgId, Throwable cause)
{
super(msgId, cause);
// TODO Auto-generated constructor stub
}
public HibernateSessionHelperResourceException(String msgId)
{
super(msgId);
// TODO Auto-generated constructor stub
}
}

View File

@@ -0,0 +1,52 @@
/*
* Copyright (C) 2005-2007 Alfresco Software Limited.
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
* As a special exception to the terms and conditions of version 2.0 of
* the GPL, you may redistribute this Program in connection with Free/Libre
* and Open Source Software ("FLOSS") applications as described in Alfresco's
* FLOSS exception. You should have recieved a copy of the text describing
* the FLOSS exception, and it is also available here:
* http://www.alfresco.com/legal/licensing"
*/
package org.alfresco.repo.domain.hibernate;
import java.util.List;
import org.hibernate.Session;
public interface HibernateSessionHelperResourceProvider
{
public void mark(Session session);
public void mark(Session session, String label);
public void reset(Session session);
public void reset(Session session, String label);
public void removeMark(Session session);
public void removeMark(Session session, String label);
public void resetAndRemoveMark(Session session);
public void resetAndRemoveMark(Session session, String label);
public List<String> getMarks(Session session);
public String getCurrentMark();
}

View File

@@ -0,0 +1,570 @@
package org.alfresco.repo.domain.hibernate;
import java.io.Serializable;
import java.util.HashSet;
import java.util.Set;
import org.alfresco.repo.domain.NodeKey;
import org.alfresco.repo.domain.NodeStatus;
import org.alfresco.repo.domain.Server;
import org.alfresco.repo.domain.StoreKey;
import org.alfresco.repo.transaction.AlfrescoTransactionSupport;
import org.alfresco.service.cmr.repository.StoreRef;
import org.alfresco.util.BaseSpringTest;
import org.hibernate.engine.EntityKey;
import org.springframework.orm.toplink.SessionReadCallback;
public class HibernateSessionHelperTest extends BaseSpringTest
{
protected void onTearDownInTransaction()
{
// force a flush to ensure that the database updates succeed
getSession().flush();
getSession().clear();
}
public void testSimpleMark()
{
assertEquals(0, getSession().getStatistics().getEntityCount());
assertFalse(SessionSizeResourceManager.isDisableInTransaction());
StoreImpl store = new StoreImpl();
StoreKey storeKey = new StoreKey(StoreRef.PROTOCOL_WORKSPACE,
"TestWorkspace@" + getName() + " - " + System.currentTimeMillis());
store.setKey(storeKey);
// persist so that it is present in the hibernate cache
getSession().save(store);
assertEquals(1, getSession().getStatistics().getEntityCount());
Server server = (Server) getSession().get(ServerImpl.class, new Long(1));
if (server == null)
{
server = new ServerImpl();
server.setIpAddress("" + "i_" + System.currentTimeMillis());
getSession().save(server);
}
assertEquals(2, getSession().getStatistics().getEntityCount());
HibernateSessionHelper helper = (HibernateSessionHelper)getApplicationContext().getBean("hibernateSessionHelper");
assertFalse(SessionSizeResourceManager.isDisableInTransaction());
helper.mark();
assertTrue(SessionSizeResourceManager.isDisableInTransaction());
assertEquals(1, helper.getMarks().size());
TransactionImpl transaction = new TransactionImpl();
transaction.setServer(server);
transaction.setChangeTxnId(AlfrescoTransactionSupport.getTransactionId());
Serializable txID = getSession().save(transaction);
assertEquals(3, getSession().getStatistics().getEntityCount());
helper.reset();
assertEquals(2, getSession().getStatistics().getEntityCount());
getSession().get(TransactionImpl.class, txID);
assertEquals(3, getSession().getStatistics().getEntityCount());
assertTrue(SessionSizeResourceManager.isDisableInTransaction());
helper.resetAndRemoveMark();
assertFalse(SessionSizeResourceManager.isDisableInTransaction());
assertEquals(0, helper.getMarks().size());
assertEquals(2, getSession().getStatistics().getEntityCount());
}
public void testNestedMarks()
{
assertEquals(0, getSession().getStatistics().getEntityCount());
assertFalse(SessionSizeResourceManager.isDisableInTransaction());
StoreImpl store = new StoreImpl();
StoreKey storeKey = new StoreKey(StoreRef.PROTOCOL_WORKSPACE,
"TestWorkspace@" + getName() + " - " + System.currentTimeMillis());
store.setKey(storeKey);
// persist so that it is present in the hibernate cache
getSession().save(store);
assertEquals(1, getSession().getStatistics().getEntityCount());
Server server = (Server) getSession().get(ServerImpl.class, new Long(1));
if (server == null)
{
server = new ServerImpl();
server.setIpAddress("" + "i_" + System.currentTimeMillis());
getSession().save(server);
}
TransactionImpl transaction = new TransactionImpl();
transaction.setServer(server);
transaction.setChangeTxnId(AlfrescoTransactionSupport.getTransactionId());
Serializable txID = getSession().save(transaction);
assertEquals(3, getSession().getStatistics().getEntityCount());
HibernateSessionHelper helper = (HibernateSessionHelper)getApplicationContext().getBean("hibernateSessionHelper");
assertFalse(SessionSizeResourceManager.isDisableInTransaction());
helper.mark();
assertTrue(SessionSizeResourceManager.isDisableInTransaction());
assertEquals(1, helper.getMarks().size());
NodeKey key1 = new NodeKey(store.getKey(), "1");
createNodeStatus(transaction, key1);
assertEquals(4, getSession().getStatistics().getEntityCount());
helper.mark();
assertTrue(SessionSizeResourceManager.isDisableInTransaction());
assertEquals(2, helper.getMarks().size());
NodeKey key2 = new NodeKey(store.getKey(), "2");
createNodeStatus(transaction, key2);
assertEquals(5, getSession().getStatistics().getEntityCount());
helper.mark();
assertTrue(SessionSizeResourceManager.isDisableInTransaction());
assertEquals(3, helper.getMarks().size());
NodeKey key3 = new NodeKey(store.getKey(), "3");
createNodeStatus(transaction, key3);
assertEquals(6, getSession().getStatistics().getEntityCount());
helper.mark();
assertTrue(SessionSizeResourceManager.isDisableInTransaction());
assertEquals(4, helper.getMarks().size());
NodeKey key4 = new NodeKey(store.getKey(), "4");
createNodeStatus(transaction, key4);
assertEquals(7, getSession().getStatistics().getEntityCount());
helper.mark();
assertTrue(SessionSizeResourceManager.isDisableInTransaction());
assertEquals(5, helper.getMarks().size());
NodeKey key5 = new NodeKey(store.getKey(), "5");
createNodeStatus(transaction, key5);
assertEquals(8, getSession().getStatistics().getEntityCount());
helper.reset();
assertEquals(7, getSession().getStatistics().getEntityCount());
assertTrue(SessionSizeResourceManager.isDisableInTransaction());
assertEquals(5, helper.getMarks().size());
assertFalse(sessionContainsNodeStatus(key5));
assertTrue(sessionContainsNodeStatus(key4));
assertTrue(sessionContainsNodeStatus(key3));
assertTrue(sessionContainsNodeStatus(key2));
assertTrue(sessionContainsNodeStatus(key1));
getSession().get(NodeStatusImpl.class, key5);
assertEquals(8, getSession().getStatistics().getEntityCount());
assertTrue(SessionSizeResourceManager.isDisableInTransaction());
assertEquals(5, helper.getMarks().size());
assertTrue(sessionContainsNodeStatus(key5));
assertTrue(sessionContainsNodeStatus(key4));
assertTrue(sessionContainsNodeStatus(key3));
assertTrue(sessionContainsNodeStatus(key2));
assertTrue(sessionContainsNodeStatus(key1));
helper.reset();
assertEquals(7, getSession().getStatistics().getEntityCount());
assertTrue(SessionSizeResourceManager.isDisableInTransaction());
assertEquals(5, helper.getMarks().size());
assertFalse(sessionContainsNodeStatus(key5));
assertTrue(sessionContainsNodeStatus(key4));
assertTrue(sessionContainsNodeStatus(key3));
assertTrue(sessionContainsNodeStatus(key2));
assertTrue(sessionContainsNodeStatus(key1));
getSession().get(NodeStatusImpl.class, key5);
assertEquals(8, getSession().getStatistics().getEntityCount());
assertTrue(SessionSizeResourceManager.isDisableInTransaction());
assertEquals(5, helper.getMarks().size());
assertTrue(sessionContainsNodeStatus(key5));
assertTrue(sessionContainsNodeStatus(key4));
assertTrue(sessionContainsNodeStatus(key3));
assertTrue(sessionContainsNodeStatus(key2));
assertTrue(sessionContainsNodeStatus(key1));
helper.resetAndRemoveMark();
assertEquals(7, getSession().getStatistics().getEntityCount());
assertTrue(SessionSizeResourceManager.isDisableInTransaction());
assertEquals(4, helper.getMarks().size());
assertFalse(sessionContainsNodeStatus(key5));
assertTrue(sessionContainsNodeStatus(key4));
assertTrue(sessionContainsNodeStatus(key3));
assertTrue(sessionContainsNodeStatus(key2));
assertTrue(sessionContainsNodeStatus(key1));
helper.resetAndRemoveMark();
assertEquals(6, getSession().getStatistics().getEntityCount());
assertTrue(SessionSizeResourceManager.isDisableInTransaction());
assertEquals(3, helper.getMarks().size());
assertFalse(sessionContainsNodeStatus(key5));
assertFalse(sessionContainsNodeStatus(key4));
assertTrue(sessionContainsNodeStatus(key3));
assertTrue(sessionContainsNodeStatus(key2));
assertTrue(sessionContainsNodeStatus(key1));
helper.resetAndRemoveMark();
assertEquals(5, getSession().getStatistics().getEntityCount());
assertTrue(SessionSizeResourceManager.isDisableInTransaction());
assertEquals(2, helper.getMarks().size());
assertFalse(sessionContainsNodeStatus(key5));
assertFalse(sessionContainsNodeStatus(key4));
assertFalse(sessionContainsNodeStatus(key3));
assertTrue(sessionContainsNodeStatus(key2));
assertTrue(sessionContainsNodeStatus(key1));
helper.resetAndRemoveMark();
assertEquals(4, getSession().getStatistics().getEntityCount());
assertTrue(SessionSizeResourceManager.isDisableInTransaction());
assertEquals(1, helper.getMarks().size());
assertFalse(sessionContainsNodeStatus(key5));
assertFalse(sessionContainsNodeStatus(key4));
assertFalse(sessionContainsNodeStatus(key3));
assertFalse(sessionContainsNodeStatus(key2));
assertTrue(sessionContainsNodeStatus(key1));
helper.resetAndRemoveMark();
assertEquals(3, getSession().getStatistics().getEntityCount());
assertFalse(SessionSizeResourceManager.isDisableInTransaction());
assertEquals(0, helper.getMarks().size());
assertFalse(sessionContainsNodeStatus(key5));
assertFalse(sessionContainsNodeStatus(key4));
assertFalse(sessionContainsNodeStatus(key3));
assertFalse(sessionContainsNodeStatus(key2));
assertFalse(sessionContainsNodeStatus(key1));
try
{
helper.reset();
fail("can not reset");
}
catch(HibernateSessionHelperResourceException hshre)
{
}
}
public void testNamedMarks()
{
assertEquals(0, getSession().getStatistics().getEntityCount());
assertFalse(SessionSizeResourceManager.isDisableInTransaction());
StoreImpl store = new StoreImpl();
StoreKey storeKey = new StoreKey(StoreRef.PROTOCOL_WORKSPACE,
"TestWorkspace@" + getName() + " - " + System.currentTimeMillis());
store.setKey(storeKey);
// persist so that it is present in the hibernate cache
getSession().save(store);
assertEquals(1, getSession().getStatistics().getEntityCount());
Server server = (Server) getSession().get(ServerImpl.class, new Long(1));
if (server == null)
{
server = new ServerImpl();
server.setIpAddress("" + "i_" + System.currentTimeMillis());
getSession().save(server);
}
assertEquals(2, getSession().getStatistics().getEntityCount());
HibernateSessionHelper helper = (HibernateSessionHelper)getApplicationContext().getBean("hibernateSessionHelper");
assertFalse(SessionSizeResourceManager.isDisableInTransaction());
helper.mark("One");
assertTrue(SessionSizeResourceManager.isDisableInTransaction());
assertEquals(1, helper.getMarks().size());
TransactionImpl transaction = new TransactionImpl();
transaction.setServer(server);
transaction.setChangeTxnId(AlfrescoTransactionSupport.getTransactionId());
Serializable txID = getSession().save(transaction);
assertEquals(3, getSession().getStatistics().getEntityCount());
helper.reset("One");
assertEquals(2, getSession().getStatistics().getEntityCount());
getSession().get(TransactionImpl.class, txID);
assertEquals(3, getSession().getStatistics().getEntityCount());
assertTrue(SessionSizeResourceManager.isDisableInTransaction());
helper.resetAndRemoveMark("One");
assertFalse(SessionSizeResourceManager.isDisableInTransaction());
assertEquals(0, helper.getMarks().size());
assertEquals(2, getSession().getStatistics().getEntityCount());
}
public void testNestedNamedMarks()
{
assertEquals(0, getSession().getStatistics().getEntityCount());
assertFalse(SessionSizeResourceManager.isDisableInTransaction());
StoreImpl store = new StoreImpl();
StoreKey storeKey = new StoreKey(StoreRef.PROTOCOL_WORKSPACE,
"TestWorkspace@" + getName() + " - " + System.currentTimeMillis());
store.setKey(storeKey);
// persist so that it is present in the hibernate cache
getSession().save(store);
assertEquals(1, getSession().getStatistics().getEntityCount());
Server server = (Server) getSession().get(ServerImpl.class, new Long(1));
if (server == null)
{
server = new ServerImpl();
server.setIpAddress("" + "i_" + System.currentTimeMillis());
getSession().save(server);
}
TransactionImpl transaction = new TransactionImpl();
transaction.setServer(server);
transaction.setChangeTxnId(AlfrescoTransactionSupport.getTransactionId());
Serializable txID = getSession().save(transaction);
assertEquals(3, getSession().getStatistics().getEntityCount());
HibernateSessionHelper helper = (HibernateSessionHelper)getApplicationContext().getBean("hibernateSessionHelper");
assertNull(helper.getCurrentMark());
assertFalse(SessionSizeResourceManager.isDisableInTransaction());
helper.mark("One");
assertEquals("One", helper.getCurrentMark());
assertTrue(SessionSizeResourceManager.isDisableInTransaction());
assertEquals(1, helper.getMarks().size());
NodeKey key1 = new NodeKey(store.getKey(), "1");
createNodeStatus(transaction, key1);
assertEquals(4, getSession().getStatistics().getEntityCount());
helper.mark("Two");
assertEquals("Two", helper.getCurrentMark());
assertTrue(SessionSizeResourceManager.isDisableInTransaction());
assertEquals(2, helper.getMarks().size());
NodeKey key2 = new NodeKey(store.getKey(), "2");
createNodeStatus(transaction, key2);
assertEquals(5, getSession().getStatistics().getEntityCount());
helper.mark("Three");
assertEquals("Three", helper.getCurrentMark());
assertTrue(SessionSizeResourceManager.isDisableInTransaction());
assertEquals(3, helper.getMarks().size());
NodeKey key3 = new NodeKey(store.getKey(), "3");
createNodeStatus(transaction, key3);
assertEquals(6, getSession().getStatistics().getEntityCount());
helper.mark("Four");
assertEquals("Four", helper.getCurrentMark());
assertTrue(SessionSizeResourceManager.isDisableInTransaction());
assertEquals(4, helper.getMarks().size());
NodeKey key4 = new NodeKey(store.getKey(), "4");
createNodeStatus(transaction, key4);
assertEquals(7, getSession().getStatistics().getEntityCount());
helper.mark("Five");
assertEquals("Five", helper.getCurrentMark());
assertTrue(SessionSizeResourceManager.isDisableInTransaction());
assertEquals(5, helper.getMarks().size());
NodeKey key5 = new NodeKey(store.getKey(), "5");
createNodeStatus(transaction, key5);
assertEquals(8, getSession().getStatistics().getEntityCount());
helper.reset("Five");
assertEquals(7, getSession().getStatistics().getEntityCount());
assertTrue(SessionSizeResourceManager.isDisableInTransaction());
assertEquals(5, helper.getMarks().size());
assertFalse(sessionContainsNodeStatus(key5));
assertTrue(sessionContainsNodeStatus(key4));
assertTrue(sessionContainsNodeStatus(key3));
assertTrue(sessionContainsNodeStatus(key2));
assertTrue(sessionContainsNodeStatus(key1));
getSession().get(NodeStatusImpl.class, key5);
assertEquals(8, getSession().getStatistics().getEntityCount());
assertTrue(SessionSizeResourceManager.isDisableInTransaction());
assertEquals(5, helper.getMarks().size());
assertTrue(sessionContainsNodeStatus(key5));
assertTrue(sessionContainsNodeStatus(key4));
assertTrue(sessionContainsNodeStatus(key3));
assertTrue(sessionContainsNodeStatus(key2));
assertTrue(sessionContainsNodeStatus(key1));
helper.reset("Five");
assertEquals(7, getSession().getStatistics().getEntityCount());
assertTrue(SessionSizeResourceManager.isDisableInTransaction());
assertEquals(5, helper.getMarks().size());
assertFalse(sessionContainsNodeStatus(key5));
assertTrue(sessionContainsNodeStatus(key4));
assertTrue(sessionContainsNodeStatus(key3));
assertTrue(sessionContainsNodeStatus(key2));
assertTrue(sessionContainsNodeStatus(key1));
getSession().get(NodeStatusImpl.class, key5);
assertEquals(8, getSession().getStatistics().getEntityCount());
assertTrue(SessionSizeResourceManager.isDisableInTransaction());
assertEquals(5, helper.getMarks().size());
assertTrue(sessionContainsNodeStatus(key5));
assertTrue(sessionContainsNodeStatus(key4));
assertTrue(sessionContainsNodeStatus(key3));
assertTrue(sessionContainsNodeStatus(key2));
assertTrue(sessionContainsNodeStatus(key1));
assertEquals("Five", helper.getCurrentMark());
helper.resetAndRemoveMark("Five");
assertEquals("Four", helper.getCurrentMark());
assertEquals(7, getSession().getStatistics().getEntityCount());
assertTrue(SessionSizeResourceManager.isDisableInTransaction());
assertEquals(4, helper.getMarks().size());
assertFalse(sessionContainsNodeStatus(key5));
assertTrue(sessionContainsNodeStatus(key4));
assertTrue(sessionContainsNodeStatus(key3));
assertTrue(sessionContainsNodeStatus(key2));
assertTrue(sessionContainsNodeStatus(key1));
helper.resetAndRemoveMark("Three");
assertEquals("Two", helper.getCurrentMark());
assertEquals(5, getSession().getStatistics().getEntityCount());
assertTrue(SessionSizeResourceManager.isDisableInTransaction());
assertEquals(2, helper.getMarks().size());
assertFalse(sessionContainsNodeStatus(key5));
assertFalse(sessionContainsNodeStatus(key4));
assertFalse(sessionContainsNodeStatus(key3));
assertTrue(sessionContainsNodeStatus(key2));
assertTrue(sessionContainsNodeStatus(key1));
helper.resetAndRemoveMark("One");
assertNull(helper.getCurrentMark());
assertEquals(3, getSession().getStatistics().getEntityCount());
assertFalse(SessionSizeResourceManager.isDisableInTransaction());
assertEquals(0, helper.getMarks().size());
assertFalse(sessionContainsNodeStatus(key5));
assertFalse(sessionContainsNodeStatus(key4));
assertFalse(sessionContainsNodeStatus(key3));
assertFalse(sessionContainsNodeStatus(key2));
assertFalse(sessionContainsNodeStatus(key1));
try
{
helper.reset("One");
fail("can not reset");
}
catch(HibernateSessionHelperResourceException hshre)
{
}
}
public void voidTestRemove()
{
assertEquals(0, getSession().getStatistics().getEntityCount());
assertFalse(SessionSizeResourceManager.isDisableInTransaction());
StoreImpl store = new StoreImpl();
StoreKey storeKey = new StoreKey(StoreRef.PROTOCOL_WORKSPACE,
"TestWorkspace@" + getName() + " - " + System.currentTimeMillis());
store.setKey(storeKey);
// persist so that it is present in the hibernate cache
getSession().save(store);
assertEquals(1, getSession().getStatistics().getEntityCount());
Server server = (Server) getSession().get(ServerImpl.class, new Long(1));
if (server == null)
{
server = new ServerImpl();
server.setIpAddress("" + "i_" + System.currentTimeMillis());
getSession().save(server);
}
TransactionImpl transaction = new TransactionImpl();
transaction.setServer(server);
transaction.setChangeTxnId(AlfrescoTransactionSupport.getTransactionId());
Serializable txID = getSession().save(transaction);
assertEquals(3, getSession().getStatistics().getEntityCount());
HibernateSessionHelper helper = (HibernateSessionHelper)getApplicationContext().getBean("hibernateSessionHelper");
assertFalse(SessionSizeResourceManager.isDisableInTransaction());
helper.mark("One");
helper.mark("Two");
helper.mark("Three");
helper.mark("Four");
helper.mark("Five");
assertTrue(SessionSizeResourceManager.isDisableInTransaction());
assertEquals(5, helper.getMarks().size());
assertEquals("Five", helper.getCurrentMark());
helper.removeMark();
assertTrue(SessionSizeResourceManager.isDisableInTransaction());
assertEquals(4, helper.getMarks().size());
assertEquals("Four", helper.getCurrentMark());
helper.removeMark("One");
assertTrue(SessionSizeResourceManager.isDisableInTransaction());
assertEquals(3, helper.getMarks().size());
assertEquals("Four", helper.getCurrentMark());
helper.removeMark();
assertTrue(SessionSizeResourceManager.isDisableInTransaction());
assertEquals(2, helper.getMarks().size());
assertEquals("Three", helper.getCurrentMark());
helper.removeMark("Two");
assertTrue(SessionSizeResourceManager.isDisableInTransaction());
assertEquals(1, helper.getMarks().size());
assertEquals("Three", helper.getCurrentMark());
helper.removeMark("Three");
assertFalse(SessionSizeResourceManager.isDisableInTransaction());
assertEquals(0, helper.getMarks().size());
assertNull(helper.getCurrentMark());
}
private NodeStatus createNodeStatus(TransactionImpl transaction, NodeKey key)
{
NodeStatus nodeStatus = new NodeStatusImpl();
nodeStatus.setKey(key);
nodeStatus.setTransaction(transaction);
getSession().save(nodeStatus);
return nodeStatus;
}
@SuppressWarnings("unchecked")
private boolean sessionContainsNodeStatus(NodeKey nodeKey)
{
Set<EntityKey> keys = (Set<EntityKey>)getSession().getStatistics().getEntityKeys();
for(EntityKey key : keys)
{
if(key.getEntityName().equals(NodeStatusImpl.class.getName()))
{
if(key.getIdentifier().equals(nodeKey))
{
return true;
}
}
}
return false;
}
}

View File

@@ -0,0 +1,50 @@
/*
* Copyright (C) 2005-2007 Alfresco Software Limited.
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
* As a special exception to the terms and conditions of version 2.0 of
* the GPL, you may redistribute this Program in connection with Free/Libre
* and Open Source Software ("FLOSS") applications as described in Alfresco's
* FLOSS exception. You should have recieved a copy of the text describing
* the FLOSS exception, and it is also available here:
* http://www.alfresco.com/legal/licensing"
*/
package org.alfresco.repo.domain.hibernate;
import java.util.List;
public interface HibernateSessionSupport
{
public void mark();
public void mark(String label);
public void reset();
public void reset(String label);
public void removeMark();
public void removeMark(String label);
public void resetAndRemoveMark();
public void resetAndRemoveMark(String label);
public List<String> getMarks();
public String getCurrentMark();
}

View File

@@ -378,6 +378,53 @@
where acl.aclId = :aclId and latest = true
</query>
<!-- Note this query will not count correctly and is only an estimate -->
<!-- It assumes there are no pending changes in layers -->
<query name="permission.GetAVMHeadNodeCount">
<![CDATA[
select count(*)
from HistoryLinkImpl hl
right outer join hl.ancestor an
where hl.ancestor is null
]]>
</query>
<query name="permission.GetAVMHeadNodeCountWherePermissionsHaveChanged">
<![CDATA[
select count(*)
from org.alfresco.repo.avm.AVMNodeImpl node
where node.acl.id > :above
]]>
</query>
<query name="permission.GetMaxAclId">
<![CDATA[
select
max(acl.id)
from
org.alfresco.repo.domain.hibernate.DbAccessControlListImpl as acl
]]>
</query>
<query name="permission.GetLayeredDirectories">
<![CDATA[
select
node.id, node.indirection, node.indirectionVersion
from org.alfresco.repo.avm.LayeredDirectoryNodeImpl node
where node.primaryIndirection = true
]]>
</query>
<query name="permission.GetLayeredFiles">
<![CDATA[
select
node.id, node.indirection, node.indirectionVersion
from org.alfresco.repo.avm.LayeredFileNodeImpl node
]]>
</query>
<!--
<query name="permission.GetAccessControlEntriesForAuthority">

View File

@@ -71,6 +71,15 @@ public class SessionSizeResourceManager extends HibernateDaoSupport implements M
{
AlfrescoTransactionSupport.bindResource(KEY_DISABLE_IN_TRANSACTION, Boolean.TRUE);
}
/**
* Enable resource management for the duration of the current transaction. This is temporary
* and relies on an active transaction.
*/
public static void setEnableInTransaction()
{
AlfrescoTransactionSupport.bindResource(KEY_DISABLE_IN_TRANSACTION, Boolean.FALSE);
}
/**
* @return Returns true if the resource management must be ignored in the current transaction.