Merged V3.0 to HEAD

12083: Fix for ETHREEOH-790 - when using external auth such as NTLM the Change Password and Logout features are no longer available in the Share UI.
   12085: ETHREEOH-565: Failure to generate flash preview for PPT file
   12086: ETHREEOH-903 	 Sites drop-down Favorites UI improvements
          ETHREEOH-904 	 My Sites dashlet Favorites UI improvements
          ETHREEOH-547 	 User who is not a site manager can delete sites: my sites dashlet and sites page
   12093: ETHREEOH-861, ETHREEOH-928
   12094: Remove __MACOSX folder that has appeared in Share webapp
   12096: Removed spurious files from YUI 2.6.0 distribution
   12100: ETHREEOH-929   Tightening up transport adapters field (should never be shown for ASR)
   12104: Fix for ETHREEOH-944. Admin now able to reset user home location again ((regression).
   12105: Fixed: ETHREEOH-934 Multi-clicking Site favoriate icons can cause multiple requests before others finish and effectively cause a browser lock-up until page refresh
   12106: Exception needs to be rethrown after releasing packet to the memory pool on a Winsock NetBIOS receive. ETHREEOH-628.
   12110: An i18n message didn't work for failures. Related to ETHREEOH-934 Multi-clicking Site favoriate icons can cause multiple requests before others finish and effectively cause a browser lock-up until page refresh
   12115: Added unit test to check for cm:folder-derived type support
   12116: Removed unused, old patch-related query
   12117: Merged V2.2 to V3.0
      11454: Fixed ASH-7: QName fetching is inefficient when run without L2 cache
   12118: Fixed compilation error after merge
   12119: DM User Usages - 2nd pass (fix ETHREEOH-677)
   12122: UserUsage does nothing if system is READ-ONLY.

git-svn-id: https://svn.alfresco.com/repos/alfresco-enterprise/alfresco/HEAD/root@12500 c4b6b30b-aa2e-2d43-bbcb-ca4b014f7261
This commit is contained in:
Kevin Roast
2008-12-18 17:10:36 +00:00
parent 9f42bfac4c
commit ab4bdfc013
38 changed files with 2011 additions and 948 deletions

View File

@@ -44,7 +44,6 @@ import org.alfresco.repo.domain.DbAuthority;
import org.alfresco.repo.domain.DbPermission;
import org.alfresco.repo.domain.Node;
import org.alfresco.repo.domain.QNameDAO;
import org.alfresco.repo.domain.QNameEntity;
import org.alfresco.repo.node.db.hibernate.HibernateNodeDaoServiceImpl;
import org.alfresco.repo.security.permissions.ACEType;
import org.alfresco.repo.security.permissions.ACLCopyMode;
@@ -63,6 +62,7 @@ import org.alfresco.repo.transaction.AlfrescoTransactionSupport;
import org.alfresco.service.cmr.security.AccessStatus;
import org.alfresco.service.namespace.QName;
import org.alfresco.util.GUID;
import org.alfresco.util.Pair;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.hibernate.CacheMode;
@@ -646,7 +646,7 @@ public class AclDaoComponentImpl extends HibernateDaoSupport implements AclDaoCo
for (Map<String, Object> result : results)
{
DbAccessControlListMember member = (DbAccessControlListMember) result.get("member");
if ((exclude != null) && excluder.matches(result, depth))
if ((exclude != null) && excluder.matches(qnameDAO, result, depth))
{
getHibernateTemplate().delete(member);
removed = true;
@@ -1174,10 +1174,11 @@ public class AclDaoComponentImpl extends HibernateDaoSupport implements AclDaoCo
// context.setClassContext(entry.getContext().getClassContext());
// context.setKVPContext(entry.getContext().getKvpContext());
// context.setPropertyContext(entry.getContext().getPropertyContext());
// sacEntry.setContext(context);
// }
DbPermission perm = (DbPermission) getSession().get(DbPermissionImpl.class, permissionId);
SimplePermissionReference permissionRefernce = SimplePermissionReference.getPermissionReference(perm.getTypeQName().getQName(), perm.getName());
// sacEntry.setContext(context);
// }
DbPermission perm = (DbPermission)getSession().get(DbPermissionImpl.class, permissionId);
QName permTypeQName = qnameDAO.getQName(perm.getTypeQNameId()).getSecond(); // Has an ID so must exist
SimplePermissionReference permissionRefernce = SimplePermissionReference.getPermissionReference(permTypeQName, perm.getName());
sacEntry.setPermission(permissionRefernce);
sacEntry.setPosition(position);
@@ -1400,14 +1401,14 @@ 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);
final Pair<Long, QName> permissionQNamePair = qnameDAO.getOrCreateQName(permissionQName);
callback = new HibernateCallback()
{
public Object doInHibernate(Session session)
{
Query query = session.getNamedQuery(QUERY_GET_PERMISSION);
query.setParameter("permissionTypeQName", permissionQNameEntity);
query.setParameter("permissionTypeQNameId", permissionQNamePair.getFirst());
query.setParameter("permissionName", permissionName);
return query.uniqueResult();
}
@@ -1416,7 +1417,7 @@ public class AclDaoComponentImpl extends HibernateDaoSupport implements AclDaoCo
if (permission == null)
{
DbPermissionImpl newPermission = new DbPermissionImpl();
newPermission.setTypeQName(permissionQNameEntity);
newPermission.setTypeQNameId(permissionQNamePair.getFirst());
newPermission.setName(permissionName);
permission = newPermission;
getHibernateTemplate().save(newPermission);
@@ -1750,7 +1751,8 @@ public class AclDaoComponentImpl extends HibernateDaoSupport implements AclDaoCo
entry.setContext(context);
}
DbPermission perm = member.getAccessControlEntry().getPermission();
SimplePermissionReference permissionRefernce = SimplePermissionReference.getPermissionReference(perm.getTypeQName().getQName(), perm.getName());
QName permTypeQName = qnameDAO.getQName(perm.getTypeQNameId()).getSecond(); // Has an ID so must exist
SimplePermissionReference permissionRefernce = SimplePermissionReference.getPermissionReference(permTypeQName, perm.getName());
entry.setPermission(permissionRefernce);
entry.setPosition(Integer.valueOf(0));
@@ -1804,7 +1806,7 @@ public class AclDaoComponentImpl extends HibernateDaoSupport implements AclDaoCo
this.pattern = pattern;
}
boolean matches(Map<String, Object> result, int position)
boolean matches(QNameDAO qnameDAO, Map<String, Object> result, int position)
{
if (pattern == null)
{
@@ -1848,7 +1850,8 @@ public class AclDaoComponentImpl extends HibernateDaoSupport implements AclDaoCo
{
DbPermission permission = (DbPermission) result.get("permission");
final QName patternQName = pattern.getPermission().getQName();
if ((patternQName != null) && (!patternQName.equals(permission.getTypeQName().getQName())))
final QName permTypeQName = qnameDAO.getQName(permission.getTypeQNameId()).getSecond(); // Has an ID so must exist
if ((patternQName != null) && (!patternQName.equals(permTypeQName)))
{
return false;
}

View File

@@ -30,9 +30,8 @@ import java.util.concurrent.locks.ReentrantReadWriteLock.ReadLock;
import java.util.concurrent.locks.ReentrantReadWriteLock.WriteLock;
import org.alfresco.repo.domain.ChildAssoc;
import org.alfresco.repo.domain.NamespaceEntity;
import org.alfresco.repo.domain.Node;
import org.alfresco.repo.domain.QNameEntity;
import org.alfresco.repo.domain.QNameDAO;
import org.alfresco.service.cmr.repository.ChildAssociationRef;
import org.alfresco.service.namespace.QName;
import org.alfresco.util.EqualsHelper;
@@ -48,8 +47,8 @@ public class ChildAssocImpl implements ChildAssoc, Serializable
private Long version;
private Node parent;
private Node child;
private QNameEntity typeQName;
private NamespaceEntity qnameNamespace;
private Long typeQNameId;
private Long qnameNamespaceId;
private String qnameLocalName;
private String childNodeName;
private long childNodeNameCrc;
@@ -59,6 +58,7 @@ public class ChildAssocImpl implements ChildAssoc, Serializable
private transient ReadLock refReadLock;
private transient WriteLock refWriteLock;
private transient ChildAssociationRef childAssocRef;
private transient QName typeQName;
private transient QName qname;
public ChildAssocImpl()
@@ -86,7 +86,7 @@ public class ChildAssocImpl implements ChildAssoc, Serializable
* <p>
* This method is thread-safe and lazily creates the required references, if required.
*/
public ChildAssociationRef getChildAssocRef()
public ChildAssociationRef getChildAssocRef(QNameDAO qnameDAO)
{
boolean trashReference = false;
// first check if it is available
@@ -119,10 +119,19 @@ public class ChildAssocImpl implements ChildAssoc, Serializable
// double check
if (childAssocRef == null || trashReference)
{
if (typeQName == null)
{
typeQName = qnameDAO.getQName(this.typeQNameId).getSecond();
}
if (qname == null )
{
String qnameNamespace = qnameDAO.getNamespace(qnameNamespaceId).getSecond();
qname = QName.createQName(qnameNamespace, qnameLocalName);
}
childAssocRef = new ChildAssociationRef(
this.typeQName.getQName(),
typeQName,
parent.getNodeRef(),
this.getQname(),
qname,
child.getNodeRef(),
this.isPrimary,
index);
@@ -135,12 +144,55 @@ public class ChildAssocImpl implements ChildAssoc, Serializable
}
}
/**
* {@inheritDoc}
*/
public QName getTypeQName(QNameDAO qnameDAO)
{
refReadLock.lock();
try
{
if (typeQName != null)
{
return typeQName;
}
}
finally
{
refReadLock.unlock();
}
refWriteLock.lock();
try
{
typeQName = qnameDAO.getQName(typeQNameId).getSecond();
return typeQName;
}
finally
{
refWriteLock.unlock();
}
}
public void setTypeQName(QNameDAO qnameDAO, QName typeQName)
{
Long typeQNameId = qnameDAO.getOrCreateQName(typeQName).getFirst();
refWriteLock.lock();
try
{
setTypeQNameId(typeQNameId);
}
finally
{
refWriteLock.unlock();
}
}
/**
* {@inheritDoc}
* <p>
* This method is thread-safe and lazily creates the required references, if required.
*/
public QName getQname()
public QName getQName(QNameDAO qnameDAO)
{
// first check if it is available
refReadLock.lock();
@@ -162,7 +214,8 @@ public class ChildAssocImpl implements ChildAssoc, Serializable
// double check
if (qname == null )
{
qname = QName.createQName(qnameNamespace.getUri(), qnameLocalName);
String qnameNamespace = qnameDAO.getNamespace(qnameNamespaceId).getSecond();
qname = QName.createQName(qnameNamespace, qnameLocalName);
}
return qname;
}
@@ -172,6 +225,24 @@ public class ChildAssocImpl implements ChildAssoc, Serializable
}
}
public void setQName(QNameDAO qnameDAO, QName qname)
{
String assocQNameNamespace = qname.getNamespaceURI();
String assocQNameLocalName = qname.getLocalName();
Long assocQNameNamespaceId = qnameDAO.getOrCreateNamespace(assocQNameNamespace).getFirst();
// get write lock
refWriteLock.lock();
try
{
setQnameNamespaceId(assocQNameNamespaceId);
setQnameLocalName(assocQNameLocalName);
}
finally
{
refWriteLock.unlock();
}
}
public boolean equals(Object obj)
{
if (obj == null)
@@ -187,10 +258,19 @@ public class ChildAssocImpl implements ChildAssoc, Serializable
return false;
}
ChildAssoc that = (ChildAssoc) obj;
return (EqualsHelper.nullSafeEquals(this.getTypeQName(), that.getTypeQName())
&& EqualsHelper.nullSafeEquals(this.getQname(), that.getQname())
&& EqualsHelper.nullSafeEquals(this.getChild(), that.getChild())
&& EqualsHelper.nullSafeEquals(this.getParent(), that.getParent()));
if (EqualsHelper.nullSafeEquals(id, that.getId()))
{
return true;
}
else
{
return (EqualsHelper.nullSafeEquals(this.getParent(), that.getParent())
&& EqualsHelper.nullSafeEquals(this.typeQNameId, that.getTypeQNameId())
&& EqualsHelper.nullSafeEquals(this.getChild(), that.getChild())
&& EqualsHelper.nullSafeEquals(this.qnameLocalName, that.getQnameLocalName())
&& EqualsHelper.nullSafeEquals(this.qnameNamespaceId, that.getQnameNamespaceId())
);
}
}
public int hashCode()
@@ -207,8 +287,9 @@ public class ChildAssocImpl implements ChildAssoc, Serializable
.append(", child=").append(child.getId())
.append(", child name=").append(childNodeName)
.append(", child name crc=").append(childNodeNameCrc)
.append(", assoc type=").append(getTypeQName().getQName())
.append(", assoc name=").append(getQname())
.append(", assoc type=").append(typeQNameId)
.append(", assoc qname ns=").append(qnameNamespaceId)
.append(", assoc qname localname=").append(qnameLocalName)
.append(", isPrimary=").append(isPrimary)
.append("]");
return sb.toString();
@@ -321,18 +402,19 @@ public class ChildAssocImpl implements ChildAssoc, Serializable
}
}
public QNameEntity getTypeQName()
public Long getTypeQNameId()
{
return typeQName;
return typeQNameId;
}
public void setTypeQName(QNameEntity typeQName)
public void setTypeQNameId(Long typeQNameId)
{
refWriteLock.lock();
try
{
this.typeQName = typeQName;
this.typeQNameId = typeQNameId;
this.childAssocRef = null;
this.typeQName = null;
}
finally
{
@@ -340,17 +422,17 @@ public class ChildAssocImpl implements ChildAssoc, Serializable
}
}
public NamespaceEntity getQnameNamespace()
public Long getQnameNamespaceId()
{
return qnameNamespace;
return qnameNamespaceId;
}
public void setQnameNamespace(NamespaceEntity qnameNamespace)
public void setQnameNamespaceId(Long qnameNamespaceId)
{
refWriteLock.lock();
try
{
this.qnameNamespace = qnameNamespace;
this.qnameNamespaceId = qnameNamespaceId;
this.childAssocRef = null;
this.qname = null;
}

View File

@@ -25,10 +25,13 @@
package org.alfresco.repo.domain.hibernate;
import java.io.Serializable;
import java.util.concurrent.locks.ReentrantReadWriteLock;
import java.util.concurrent.locks.ReentrantReadWriteLock.ReadLock;
import java.util.concurrent.locks.ReentrantReadWriteLock.WriteLock;
import org.alfresco.repo.domain.DbPermission;
import org.alfresco.repo.domain.DbPermissionKey;
import org.alfresco.repo.domain.QNameEntity;
import org.alfresco.repo.domain.QNameDAO;
import org.alfresco.service.namespace.QName;
import org.alfresco.util.EqualsHelper;
import org.hibernate.Session;
@@ -44,12 +47,19 @@ public class DbPermissionImpl implements DbPermission, Serializable
private Long id;
private Long version;
private QNameEntity typeQName;
private Long typeQNameId;
private String name;
private transient ReadLock refReadLock;
private transient WriteLock refWriteLock;
private transient QName typeQName;
public DbPermissionImpl()
{
super();
ReentrantReadWriteLock lock = new ReentrantReadWriteLock();
refReadLock = lock.readLock();
refWriteLock = lock.writeLock();
}
@Override
@@ -59,7 +69,7 @@ public class DbPermissionImpl implements DbPermission, Serializable
sb.append("DbPermissionImpl")
.append("[ id=").append(id)
.append(", version=").append(version)
.append(", typeQName=").append(typeQName.getQName())
.append(", typeQName=").append(typeQNameId)
.append(", name=").append(getName())
.append("]");
return sb.toString();
@@ -77,13 +87,41 @@ public class DbPermissionImpl implements DbPermission, Serializable
return false;
}
DbPermission other = (DbPermission) o;
return (EqualsHelper.nullSafeEquals(typeQName, other.getTypeQName())) && (EqualsHelper.nullSafeEquals(name, other.getName()));
return (EqualsHelper.nullSafeEquals(typeQNameId, other.getTypeQNameId()))
&& (EqualsHelper.nullSafeEquals(name, other.getName())
);
}
@Override
public int hashCode()
{
return typeQName.hashCode() + (37 * name.hashCode());
return typeQNameId.hashCode() + (37 * name.hashCode());
}
public QName getTypeQName(QNameDAO qnameDAO)
{
refReadLock.lock();
try
{
if (typeQName != null)
{
return typeQName;
}
}
finally
{
refReadLock.unlock();
}
refWriteLock.lock();
try
{
typeQName = qnameDAO.getQName(typeQNameId).getSecond();
return typeQName;
}
finally
{
refWriteLock.unlock();
}
}
public Long getId()
@@ -114,14 +152,23 @@ public class DbPermissionImpl implements DbPermission, Serializable
this.version = version;
}
public QNameEntity getTypeQName()
public Long getTypeQNameId()
{
return typeQName;
return typeQNameId;
}
public void setTypeQName(QNameEntity typeQName)
public void setTypeQNameId(Long typeQNameId)
{
this.typeQName = typeQName;
refWriteLock.lock();
try
{
this.typeQNameId = typeQNameId;
this.typeQName = null;
}
finally
{
refWriteLock.unlock();
}
}
public String getName()
@@ -136,7 +183,7 @@ public class DbPermissionImpl implements DbPermission, Serializable
public DbPermissionKey getKey()
{
return new DbPermissionKey(typeQName.getQName(), name);
return new DbPermissionKey(typeQNameId, name);
}
/**

View File

@@ -24,6 +24,7 @@
*/
package org.alfresco.repo.domain.hibernate;
import java.io.Serializable;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Map;
@@ -56,26 +57,68 @@ public class HibernateQNameDAOImpl extends HibernateDaoSupport implements QNameD
private static final String QUERY_GET_NS_BY_URI = "qname.GetNamespaceByUri";
private static final String QUERY_GET_QNAME_BY_URI_AND_LOCALNAME = "qname.GetQNameByUriAndLocalName";
private SimpleCache<QName, Long> qnameEntityCache;
public void setQnameEntityCache(SimpleCache<QName, Long> qnameEntityCache)
private static final Long CACHE_NULL_LONG = Long.MIN_VALUE;
private SimpleCache<Serializable, Serializable> namespaceEntityCache;
private SimpleCache<Serializable, Serializable> qnameEntityCache;
/**
* Set the cache that maintains the ID-Namespace mappings and vice-versa.
*
* @param namespaceEntityCache the cache
*/
public void setNamespaceEntityCache(SimpleCache<Serializable, Serializable> namespaceEntityCache)
{
this.namespaceEntityCache = namespaceEntityCache;
}
/**
* Set the cache that maintains the ID-QName mappings and vice-versa.
*
* @param qnameEntityCache the cache
*/
public void setQnameEntityCache(SimpleCache<Serializable, Serializable> qnameEntityCache)
{
this.qnameEntityCache = qnameEntityCache;
}
public NamespaceEntity getNamespaceEntity(Long id)
public Pair<Long, String> getNamespace(Long id)
{
// Check the cache
String uri = (String) namespaceEntityCache.get(id);
if (uri != null)
{
return new Pair<Long, String>(id, uri);
}
// Get it from the DB
NamespaceEntity namespaceEntity = (NamespaceEntity) getSession().get(NamespaceEntityImpl.class, id);
if (namespaceEntity == null)
{
throw new AlfrescoRuntimeException("The NamespaceEntity ID " + id + " doesn't exist.");
}
return namespaceEntity;
uri = namespaceEntity.getUri();
// Cache it
namespaceEntityCache.put(uri, id);
namespaceEntityCache.put(id, uri);
// Done
return new Pair<Long, String>(id, uri);
}
public NamespaceEntity getNamespaceEntity(final String namespaceUri)
public Pair<Long, String> getNamespace(final String namespaceUri)
{
// TODO: Use a cache if external use becomes common
// Check the cache
Long id = (Long) namespaceEntityCache.get(namespaceUri);
if (id != null)
{
if (id.equals(CACHE_NULL_LONG))
{
return null;
}
else
{
return new Pair<Long, String>(id, namespaceUri);
}
}
// Get it from the DB
HibernateCallback callback = new HibernateCallback()
{
public Object doInHibernate(Session session)
@@ -89,21 +132,35 @@ public class HibernateQNameDAOImpl extends HibernateDaoSupport implements QNameD
}
};
NamespaceEntity result = (NamespaceEntity) getHibernateTemplate().execute(callback);
// Done
return result;
}
public NamespaceEntity getOrCreateNamespaceEntity(String namespaceUri)
{
NamespaceEntity result = getNamespaceEntity(namespaceUri);
if (result == null)
{
result = newNamespaceEntity(namespaceUri);
// Cache it
namespaceEntityCache.put(namespaceUri, CACHE_NULL_LONG);
// Done
return null;
}
else
{
id = result.getId();
// Cache it
namespaceEntityCache.put(id, namespaceUri);
namespaceEntityCache.put(namespaceUri, id);
// Done
return new Pair<Long, String>(id, namespaceUri);
}
}
public Pair<Long, String> getOrCreateNamespace(String namespaceUri)
{
Pair<Long, String> result = getNamespace(namespaceUri);
if (result == null)
{
result = newNamespace(namespaceUri);
}
return result;
}
public NamespaceEntity newNamespaceEntity(String namespaceUri)
public Pair<Long, String> newNamespace(String namespaceUri)
{
if (logger.isDebugEnabled())
{
@@ -112,25 +169,29 @@ public class HibernateQNameDAOImpl extends HibernateDaoSupport implements QNameD
NamespaceEntity namespace = new NamespaceEntityImpl();
namespace.setUri(namespaceUri);
// Persist
getSession().save(namespace);
Long id = (Long) getSession().save(namespace);
// Cache it
namespaceEntityCache.put(id, namespaceUri);
namespaceEntityCache.put(namespaceUri, id);
// Done
return namespace;
return new Pair<Long, String>(id, namespaceUri);
}
public void updateNamespaceEntity(String oldNamespaceUri, String newNamespaceUri)
public void updateNamespace(String oldNamespaceUri, String newNamespaceUri)
{
// First check for clashes
if (getNamespaceEntity(newNamespaceUri) != null)
if (getNamespace(newNamespaceUri) != null)
{
throw new AlfrescoRuntimeException("Namespace URI '" + newNamespaceUri + "' already exists.");
}
// Get the old one
NamespaceEntity oldNamespaceEntity = getNamespaceEntity(oldNamespaceUri);
if (oldNamespaceEntity == null)
Pair<Long, String> oldNamespacePair = getNamespace(oldNamespaceUri);
if (oldNamespacePair == null)
{
// Nothing to rename
return;
}
NamespaceEntity oldNamespaceEntity = (NamespaceEntity) getSession().load(NamespaceEntityImpl.class, oldNamespacePair.getFirst());
oldNamespaceEntity.setUri(newNamespaceUri);
// Flush to force early failure
getSession().flush();
@@ -139,111 +200,88 @@ public class HibernateQNameDAOImpl extends HibernateDaoSupport implements QNameD
// Done
}
public QNameEntity getQNameEntity(Long id)
public Pair<Long, QName> getQName(Long id)
{
// Check the cache
QName qname = (QName) qnameEntityCache.get(id);
if (qname != null)
{
return new Pair<Long, QName>(id, qname);
}
QNameEntity qnameEntity = (QNameEntity) getSession().get(QNameEntityImpl.class, id);
if (qnameEntity == null)
{
throw new AlfrescoRuntimeException("The QNameEntity ID " + id + " doesn't exist.");
}
return qnameEntity;
qname = qnameEntity.getQName();
// Cache it
qnameEntityCache.put(id, qname);
qnameEntityCache.put(qname, id);
// Done
return new Pair<Long, QName>(id, qname);
}
public QName getQName(Long id)
public Pair<Long, QName> getQName(final QName qname)
{
// TODO: Explore caching options here
QNameEntity qnameEntity = getQNameEntity(id);
if (qnameEntity == null)
// Check the cache
Long id = (Long) qnameEntityCache.get(qname);
if (id != null)
{
return null;
}
else
{
return qnameEntity.getQName();
}
}
public QNameEntity getQNameEntity(final QName qname)
{
QNameEntity result;
// First check the cache
Long id = qnameEntityCache.get(qname);
if (id == null)
{
// It's not in the cache, so query
HibernateCallback callback = new HibernateCallback()
if (id.equals(CACHE_NULL_LONG))
{
public Object doInHibernate(Session session)
{
String namespaceUri = qname.getNamespaceURI();
String oracleSafeUri = (namespaceUri.length() == 0) ? NamespaceEntityImpl.EMPTY_URI_SUBSTITUTE : namespaceUri;
Query query = session
.getNamedQuery(HibernateQNameDAOImpl.QUERY_GET_QNAME_BY_URI_AND_LOCALNAME)
.setString("namespaceUri", oracleSafeUri)
.setString("localName", qname.getLocalName());
return query.uniqueResult();
}
};
result = (QNameEntity) getHibernateTemplate().execute(callback);
if (result != null)
{
id = result.getId();
// We found something, so we can add it to the cache
qnameEntityCache.put(qname, id);
return null;
}
else
{
qnameEntityCache.put(qname, -1L);
return new Pair<Long, QName>(id, qname);
}
}
else if (id == -1L)
QNameEntity result;
// It's not in the cache, so query
HibernateCallback callback = new HibernateCallback()
{
public Object doInHibernate(Session session)
{
String namespaceUri = qname.getNamespaceURI();
String oracleSafeUri = (namespaceUri.length() == 0) ? NamespaceEntityImpl.EMPTY_URI_SUBSTITUTE : namespaceUri;
Query query = session
.getNamedQuery(HibernateQNameDAOImpl.QUERY_GET_QNAME_BY_URI_AND_LOCALNAME)
.setString("namespaceUri", oracleSafeUri)
.setString("localName", qname.getLocalName());
return query.uniqueResult();
}
};
result = (QNameEntity) getHibernateTemplate().execute(callback);
if (result == null)
{
// Cache it
qnameEntityCache.put(qname, CACHE_NULL_LONG);
// Done
return null;
}
else
{
// Found in the cache. Load using the ID.
// Don't use the method that throws an exception as the cache might be invalid.
result = (QNameEntity) getSession().get(QNameEntityImpl.class, id);
if (result == null)
{
// It is not available, so we need to go the query route.
// But first remove the cache entry
qnameEntityCache.remove(qname);
// Recurse, but this time there is no cache entry
return getQNameEntity(qname);
}
id = result.getId();
// Cache it
qnameEntityCache.put(id, qname);
qnameEntityCache.put(qname, id);
// Done
return new Pair<Long, QName>(id, qname);
}
// Done
return result;
}
public QNameEntity getOrCreateQNameEntity(QName qname)
public Pair<Long, QName> getOrCreateQName(QName qname)
{
QNameEntity result = getQNameEntity(qname);
Pair<Long, QName> result = getQName(qname);
if (result == null)
{
result = newQNameEntity(qname);
result = newQName(qname);
}
return result;
}
public Pair<Long, QName> getOrCreateQNamePair(QName qname)
{
Long id = qnameEntityCache.get(qname);
if (id == null)
{
// It is not cached
QNameEntity qnameEntity = getOrCreateQNameEntity(qname);
id = qnameEntity.getId();
}
Pair<Long, QName> qnamePair = new Pair<Long, QName>(id, qname);
// Done
return qnamePair;
}
public QNameEntity newQNameEntity(QName qname)
public Pair<Long, QName> newQName(QName qname)
{
if (logger.isDebugEnabled())
{
@@ -251,11 +289,10 @@ public class HibernateQNameDAOImpl extends HibernateDaoSupport implements QNameD
}
final String namespaceUri = qname.getNamespaceURI();
final String localName = qname.getLocalName();
NamespaceEntity namespace = getNamespaceEntity(namespaceUri);
if (namespace == null)
{
namespace = newNamespaceEntity(namespaceUri);
}
// Get the namespace
Pair<Long, String> namespacePair = getOrCreateNamespace(namespaceUri);
NamespaceEntity namespace = (NamespaceEntity) getSession().load(NamespaceEntityImpl.class, namespacePair.getFirst());
// Create the QNameEntity
QNameEntity qnameEntity = new QNameEntityImpl();
qnameEntity.setNamespace(namespace);
qnameEntity.setLocalName(localName);
@@ -263,8 +300,9 @@ public class HibernateQNameDAOImpl extends HibernateDaoSupport implements QNameD
Long id = (Long) getSession().save(qnameEntity);
// Update the cache
qnameEntityCache.put(qname, id);
qnameEntityCache.put(id, qname);
// Done
return qnameEntity;
return new Pair<Long, QName>(id, qname);
}
public Set<QName> convertIdsToQNames(Set<Long> ids)
@@ -272,7 +310,7 @@ public class HibernateQNameDAOImpl extends HibernateDaoSupport implements QNameD
Set<QName> qnames = new HashSet<QName>(ids.size() * 2 + 1);
for (Long id : ids)
{
QName qname = getQName(id); // Never null
QName qname = getQName(id).getSecond(); // getQName(id) is never null
qnames.add(qname);
}
return qnames;
@@ -283,7 +321,7 @@ public class HibernateQNameDAOImpl extends HibernateDaoSupport implements QNameD
Map<QName, Object> qnameMap = new HashMap<QName, Object>(idMap.size() + 3);
for (Map.Entry<Long, ? extends Object> entry : idMap.entrySet())
{
QName qname = getQName(entry.getKey());
QName qname = getQName(entry.getKey()).getSecond(); // getQName(id) is never null
qnameMap.put(qname, entry.getValue());
}
return qnameMap;
@@ -303,19 +341,19 @@ public class HibernateQNameDAOImpl extends HibernateDaoSupport implements QNameD
Long qnameEntityId = null;
if (create)
{
qnameEntityId = getOrCreateQNameEntity(qname).getId();
qnameEntityId = getOrCreateQName(qname).getFirst(); // getOrCreateQName(qname) is never null
}
else
{
QNameEntity qnameEntity = getQNameEntity(qname);
if (qnameEntity == null)
Pair<Long, QName> qnamePair = getQName(qname);
if (qnamePair == null)
{
// No such qname and we are not creating one
continue;
}
else
{
qnameEntityId = qnameEntity.getId();
qnameEntityId = qnamePair.getFirst();
}
}
if (qnameEntityId != null)

View File

@@ -7,7 +7,6 @@ import java.util.Set;
import org.alfresco.model.ContentModel;
import org.alfresco.repo.domain.Node;
import org.alfresco.repo.domain.QNameDAO;
import org.alfresco.repo.domain.QNameEntity;
import org.alfresco.repo.domain.Server;
import org.alfresco.repo.domain.Store;
import org.alfresco.repo.transaction.AlfrescoTransactionSupport;
@@ -93,7 +92,7 @@ public class HibernateSessionHelperTest extends BaseSpringTest
assertFalse(SessionSizeResourceManager.isDisableInTransaction());
QNameDAO qnameDAO = (QNameDAO) getApplicationContext().getBean("qnameDAO");
QNameEntity baseQNameEntity = qnameDAO.getOrCreateQNameEntity(ContentModel.TYPE_BASE);
Long baseQNameId = qnameDAO.getOrCreateQName(ContentModel.TYPE_BASE).getFirst();
StoreImpl store = new StoreImpl();
store.setProtocol(StoreRef.PROTOCOL_WORKSPACE);
@@ -124,35 +123,35 @@ public class HibernateSessionHelperTest extends BaseSpringTest
assertTrue(SessionSizeResourceManager.isDisableInTransaction());
assertEquals(1, helper.getMarks().size());
Node n1 = createNode(transaction, store, "1", baseQNameEntity);
Node n1 = createNode(transaction, store, "1", baseQNameId);
assertEquals(5, getSession().getStatistics().getEntityCount());
helper.mark();
assertTrue(SessionSizeResourceManager.isDisableInTransaction());
assertEquals(2, helper.getMarks().size());
Node n2 = createNode(transaction, store, "2", baseQNameEntity);
Node n2 = createNode(transaction, store, "2", baseQNameId);
assertEquals(6, getSession().getStatistics().getEntityCount());
helper.mark();
assertTrue(SessionSizeResourceManager.isDisableInTransaction());
assertEquals(3, helper.getMarks().size());
Node n3 = createNode(transaction, store, "3", baseQNameEntity);
Node n3 = createNode(transaction, store, "3", baseQNameId);
assertEquals(7, getSession().getStatistics().getEntityCount());
helper.mark();
assertTrue(SessionSizeResourceManager.isDisableInTransaction());
assertEquals(4, helper.getMarks().size());
Node n4 = createNode(transaction, store, "4", baseQNameEntity);
Node n4 = createNode(transaction, store, "4", baseQNameId);
assertEquals(8, getSession().getStatistics().getEntityCount());
helper.mark();
assertTrue(SessionSizeResourceManager.isDisableInTransaction());
assertEquals(5, helper.getMarks().size());
Node n5 = createNode(transaction, store, "5", baseQNameEntity);
Node n5 = createNode(transaction, store, "5", baseQNameId);
assertEquals(9, getSession().getStatistics().getEntityCount());
@@ -321,7 +320,7 @@ public class HibernateSessionHelperTest extends BaseSpringTest
assertFalse(SessionSizeResourceManager.isDisableInTransaction());
QNameDAO qnameDAO = (QNameDAO) getApplicationContext().getBean("qnameDAO");
QNameEntity baseQNameEntity = qnameDAO.getOrCreateQNameEntity(ContentModel.TYPE_BASE);
Long baseQNameId = qnameDAO.getOrCreateQName(ContentModel.TYPE_BASE).getFirst();
StoreImpl store = new StoreImpl();
store.setProtocol(StoreRef.PROTOCOL_WORKSPACE);
@@ -354,7 +353,7 @@ public class HibernateSessionHelperTest extends BaseSpringTest
assertTrue(SessionSizeResourceManager.isDisableInTransaction());
assertEquals(1, helper.getMarks().size());
Node n1 = createNode(transaction, store, "1", baseQNameEntity);
Node n1 = createNode(transaction, store, "1", baseQNameId);
assertEquals(5, getSession().getStatistics().getEntityCount());
helper.mark("Two");
@@ -362,7 +361,7 @@ public class HibernateSessionHelperTest extends BaseSpringTest
assertTrue(SessionSizeResourceManager.isDisableInTransaction());
assertEquals(2, helper.getMarks().size());
Node n2 = createNode(transaction, store, "2", baseQNameEntity);
Node n2 = createNode(transaction, store, "2", baseQNameId);
assertEquals(6, getSession().getStatistics().getEntityCount());
helper.mark("Three");
@@ -370,7 +369,7 @@ public class HibernateSessionHelperTest extends BaseSpringTest
assertTrue(SessionSizeResourceManager.isDisableInTransaction());
assertEquals(3, helper.getMarks().size());
Node n3 = createNode(transaction, store, "3", baseQNameEntity);
Node n3 = createNode(transaction, store, "3", baseQNameId);
assertEquals(7, getSession().getStatistics().getEntityCount());
helper.mark("Four");
@@ -378,7 +377,7 @@ public class HibernateSessionHelperTest extends BaseSpringTest
assertTrue(SessionSizeResourceManager.isDisableInTransaction());
assertEquals(4, helper.getMarks().size());
Node n4 = createNode(transaction, store, "4", baseQNameEntity);
Node n4 = createNode(transaction, store, "4", baseQNameId);
assertEquals(8, getSession().getStatistics().getEntityCount());
helper.mark("Five");
@@ -386,7 +385,7 @@ public class HibernateSessionHelperTest extends BaseSpringTest
assertTrue(SessionSizeResourceManager.isDisableInTransaction());
assertEquals(5, helper.getMarks().size());
Node n5 = createNode(transaction, store, "5", baseQNameEntity);
Node n5 = createNode(transaction, store, "5", baseQNameId);
assertEquals(9, getSession().getStatistics().getEntityCount());
@@ -541,13 +540,13 @@ public class HibernateSessionHelperTest extends BaseSpringTest
assertNull(helper.getCurrentMark());
}
private Node createNode(TransactionImpl transaction, Store store, String uuid, QNameEntity typeQNameEntity)
private Node createNode(TransactionImpl transaction, Store store, String uuid, Long typeQNameId)
{
// Create the Node
Node node = new NodeImpl();
node.setStore(store);
node.setUuid(uuid);
node.setTypeQName(typeQNameEntity);
node.setTypeQNameId(typeQNameId);
node.setTransaction(transaction);
node.setDeleted(false);
node.getAuditableProperties().setAuditValues("system", new Date(), false);

View File

@@ -80,17 +80,8 @@
cascade="none" />
<!-- Keep track of the node even once it dies -->
<property name="deleted" column="node_deleted" type="boolean" not-null="true" index="idx_alf_node_del"/>
<!-- forward assoc to node type (mandatory) -->
<many-to-one
name="typeQName"
class="org.alfresco.repo.domain.hibernate.QNameEntityImpl"
column="type_qname_id"
foreign-key="fk_alf_node_tqn"
lazy="proxy"
fetch="select"
unique="false"
not-null="true"
cascade="none" />
<!-- Node type QName (mandatory) -->
<property name="typeQNameId" column="type_qname_id" type="long" not-null="true" /> <!-- fk_alf_node_tqn -->
<!-- forward assoc to access control list (optional) -->
<many-to-one
name="accessControlList"
@@ -142,7 +133,7 @@
optimistic-lock="false"
cascade="delete" >
<key column="node_id" foreign-key="fk_alf_nasp_n" not-null="true" />
<element column="qname_id" type="long" not-null="true" />
<element column="qname_id" type="long" not-null="true" /> <!-- fk_alf_nasp_qn -->
</set>
<!-- cm:auditable properties -->
<component name="auditableProperties" class="org.alfresco.repo.domain.AuditableProperties" optimistic-lock="false">
@@ -178,17 +169,7 @@
not-null="true" >
<column name="parent_node_id" not-null="true" />
</many-to-one>
<!-- forward assoc to assoc type (mandatory) -->
<many-to-one
name="typeQName"
class="org.alfresco.repo.domain.hibernate.QNameEntityImpl"
column="type_qname_id"
foreign-key="fk_alf_cass_tqn"
lazy="proxy"
fetch="select"
unique="false"
not-null="true"
cascade="none" />
<property name="typeQNameId" column="type_qname_id" type="long" not-null="true" /> <!-- fk_alf_cass_tqn -->
<property name="childNodeName" column="child_node_name" type="string" length="50" not-null="true" />
<property name="childNodeNameCrc" column="child_node_name_crc" type="long" not-null="true" />
</natural-id>
@@ -205,17 +186,7 @@
not-null="true" >
<column name="child_node_id" not-null="true"/>
</many-to-one>
<!-- forward assoc to namespace for local QName (mandatory) -->
<many-to-one
name="qnameNamespace"
class="org.alfresco.repo.domain.hibernate.NamespaceEntityImpl"
column="qname_ns_id"
foreign-key="fk_alf_cass_qnns"
lazy="proxy"
fetch="select"
unique="false"
not-null="true"
cascade="none" />
<property name="qnameNamespaceId" column="qname_ns_id" type="long" not-null="true" /> <!-- fk_alf_cass_qnns -->
<property name="qnameLocalName" column="qname_localname" type="string" length="100" not-null="true" index="idx_alf_cass_qnln" />
<property name="isPrimary" column="is_primary" />
<property name="index" column="assoc_index" />
@@ -252,17 +223,7 @@
not-null="true" >
<column name="target_node_id" not-null="true" />
</many-to-one>
<!-- forward assoc to assoc type (mandatory) -->
<many-to-one
name="typeQName"
class="org.alfresco.repo.domain.hibernate.QNameEntityImpl"
column="type_qname_id"
foreign-key="fk_alf_nass_tqn"
lazy="proxy"
fetch="select"
unique="false"
not-null="true"
cascade="none" />
<property name="typeQNameId" column="type_qname_id" type="long" not-null="true" /> <!-- fk_alf_nass_tqn -->
</natural-id>
<!-- Optimistic locking -->
<version column="version" name="version" type="long" />
@@ -308,11 +269,15 @@
<query name="node.GetParentAssocs">
select
assoc
assoc,
parent,
child
from
org.alfresco.repo.domain.hibernate.ChildAssocImpl as assoc
join assoc.parent as parent
join assoc.child as child
where
assoc.child.id = :childId
child.id = :childId
order by
assoc.index,
assoc.id
@@ -363,8 +328,8 @@
where
assoc.parent.id = :parentId and
assoc.child.id = :childId and
assoc.typeQName = :typeQName and
assoc.qnameNamespace = :qnameNamespace and
assoc.typeQNameId = :typeQNameId and
assoc.qnameNamespaceId = :qnameNamespaceId and
assoc.qnameLocalName = :qnameLocalName
order by
assoc.index,
@@ -390,7 +355,7 @@
org.alfresco.repo.domain.hibernate.ChildAssocImpl as assoc
where
assoc.parent.id = :parentId and
assoc.typeQName = :typeQName and
assoc.typeQNameId = :typeQNameId and
assoc.childNodeName = :childNodeName and
assoc.childNodeNameCrc = :childNodeNameCrc
order by
@@ -401,8 +366,8 @@
<query name="node.GetChildAssocRefs">
select
assoc.id,
assoc.typeQName,
assoc.qnameNamespace,
assoc.typeQNameId,
assoc.qnameNamespaceId,
assoc.qnameLocalName,
assoc.isPrimary,
assoc.index,
@@ -425,8 +390,8 @@
<query name="node.GetChildAssocRefsByQName">
select
assoc.id,
assoc.typeQName,
assoc.qnameNamespace,
assoc.typeQNameId,
assoc.qnameNamespaceId,
assoc.qnameLocalName,
assoc.isPrimary,
assoc.index,
@@ -441,7 +406,7 @@
join child.store as store
where
parent.id = :parentId and
assoc.qnameNamespace = :qnameNamespace and
assoc.qnameNamespaceId = :qnameNamespaceId and
assoc.qnameLocalName = :qnameLocalName
order by
assoc.index,
@@ -451,8 +416,8 @@
<query name="node.GetChildAssocRefsByTypeQNames">
select
assoc.id,
assoc.typeQName,
assoc.qnameNamespace,
assoc.typeQNameId,
assoc.qnameNamespaceId,
assoc.qnameLocalName,
assoc.isPrimary,
assoc.index,
@@ -467,7 +432,7 @@
join child.store as store
where
parent.id = :parentId and
assoc.typeQName.id in (:childAssocTypeQNameIds)
assoc.typeQNameId in (:childAssocTypeQNameIds)
order by
assoc.index,
assoc.id
@@ -476,8 +441,8 @@
<query name="node.GetChildAssocRefsByTypeQNameAndQName">
select
assoc.id,
assoc.typeQName,
assoc.qnameNamespace,
assoc.typeQNameId,
assoc.qnameNamespaceId,
assoc.qnameLocalName,
assoc.isPrimary,
assoc.index,
@@ -492,8 +457,8 @@
join child.store as store
where
parent.id = :parentId and
assoc.typeQName = :typeQName and
assoc.qnameNamespace = :qnameNamespace and
assoc.typeQNameId = :typeQNameId and
assoc.qnameNamespaceId = :qnameNamespaceId and
assoc.qnameLocalName = :qnameLocalName
order by
assoc.index,
@@ -503,8 +468,8 @@
<query name="node.GetChildAssocRefsByChildTypeQName">
select
assoc.id,
assoc.typeQName,
assoc.qnameNamespace,
assoc.typeQNameId,
assoc.qnameNamespaceId,
assoc.qnameLocalName,
assoc.isPrimary,
assoc.index,
@@ -519,7 +484,7 @@
join child.store as store
where
parent.id = :parentId and
child.typeQName in (:childTypeQNameEntities)
child.typeQNameId in (:childTypeQNameIds)
order by
assoc.index,
assoc.id
@@ -528,8 +493,8 @@
<query name="node.GetPrimaryChildAssocs">
select
assoc.id,
assoc.typeQName,
assoc.qnameNamespace,
assoc.typeQNameId,
assoc.qnameNamespaceId,
assoc.qnameLocalName,
assoc.isPrimary,
assoc.index,
@@ -553,8 +518,8 @@
<query name="node.GetPrimaryChildAssocsNotInSameStore">
select
assoc.id,
assoc.typeQName,
assoc.qnameNamespace,
assoc.typeQNameId,
assoc.qnameNamespaceId,
assoc.qnameLocalName,
assoc.isPrimary,
assoc.index,
@@ -606,7 +571,7 @@
join node.aspects as aspects
where
node.id > :minNodeId and
aspects.id = :aspectQName
aspects.id = :aspectQNameId
order by
node.id
</query>
@@ -619,7 +584,7 @@
where
assoc.source.id = :sourceId and
assoc.target.id = :targetId and
assoc.typeQName = :assocTypeQName
assoc.typeQNameId = :assocTypeQNameId
</query>
<query name="node.GetNodeAssocsToAndFrom">
@@ -669,19 +634,60 @@
p.string_value = :propStringValue
</sql-query>
<query name="node.GetNodesWithCreatorAndStore">
select
node.id,
node.store.protocol,
node.store.identifier,
node.uuid
from
org.alfresco.repo.domain.hibernate.NodeImpl as node
where
node.store.protocol = :storeProtocol and
node.store.identifier = :storeIdentifier and
node.auditableProperties.auditCreator = :userName
</query>
<sql-query name="node.GetContentUrlsForStore">
<return-scalar column="owner" type="string"/>
<return-scalar column="creator" type="string"/>
<return-scalar column="contenturl" type="string"/>
SELECT
p1.string_value AS owner,
n.audit_creator AS creator,
p2.string_value AS contenturl
FROM
alf_node n
JOIN alf_store s ON (s.id = n.store_id AND n.type_qname_id = :contentTypeQNameID)
LEFT JOIN alf_node_properties p1 ON (p1.node_id = n.id AND p1.qname_id = :ownerPropQNameID)
JOIN alf_node_properties p2 ON (p2.node_id = n.id AND p2.qname_id = :contentPropQNameID)
WHERE
s.protocol = :storeProtocol AND
s.identifier = :storeIdentifier AND
(p1.string_value != 'System' OR (p1.string_value IS NULL AND n.audit_creator != 'System'))
</sql-query>
<sql-query name="node.GetUsersWithoutUsage">
<return-scalar column="username" type="string"/>
<return-scalar column="uuid" type="string"/>
SELECT
p1.string_value AS username,
n.uuid AS uuid
FROM
alf_node n
JOIN alf_store s ON (s.id = n.store_id AND n.type_qname_id = :personTypeQNameID)
JOIN alf_node_properties p1 ON (p1.node_id = n.id AND p1.qname_id = :usernamePropQNameID)
LEFT JOIN alf_node_properties p2 ON (p2.node_id = n.id AND p2.qname_id = :sizeCurrentPropQNameID)
WHERE
s.protocol = :storeProtocol AND
s.identifier = :storeIdentifier AND
(p2.persisted_type_n IS NULL OR p2.persisted_type_n = 0) AND
p1.string_value != 'System'
</sql-query>
<sql-query name="node.GetUsersWithUsage">
<return-scalar column="username" type="string"/>
<return-scalar column="uuid" type="string"/>
SELECT
p1.string_value AS username,
n.uuid AS uuid
FROM
alf_node n
JOIN alf_store s ON (s.id = n.store_id AND n.type_qname_id = :personTypeQNameID)
JOIN alf_node_properties p1 ON (p1.node_id = n.id AND p1.qname_id = :usernamePropQNameID)
LEFT JOIN alf_node_properties p2 ON (p2.node_id = n.id AND p2.qname_id = :sizeCurrentPropQNameID)
WHERE
s.protocol = :storeProtocol AND
s.identifier = :storeIdentifier AND
(p2.persisted_type_n != 0 AND p2.persisted_type_n IS NOT NULL) AND
p1.string_value != 'System'
</sql-query>
<query name="node.GetNodesWithPropertyValuesByActualType">
select
@@ -708,20 +714,4 @@
props.serializableValue is not null
</query>
<query name="node.patch.GetAssocsAndChildNames">
<![CDATA[
select
assoc,
child
from
org.alfresco.repo.domain.hibernate.ChildAssocImpl as assoc
join assoc.child as child
where
assoc.id > :lastAssocId and
assoc.typeQName = :assocTypeQName
order by
assoc.id
]]>
</query>
</hibernate-mapping>

View File

@@ -31,8 +31,9 @@ import java.util.concurrent.locks.ReentrantReadWriteLock.WriteLock;
import org.alfresco.repo.domain.Node;
import org.alfresco.repo.domain.NodeAssoc;
import org.alfresco.repo.domain.QNameEntity;
import org.alfresco.repo.domain.QNameDAO;
import org.alfresco.service.cmr.repository.AssociationRef;
import org.alfresco.service.namespace.QName;
import org.alfresco.util.EqualsHelper;
/**
@@ -48,11 +49,12 @@ public class NodeAssocImpl implements NodeAssoc, Serializable
private Long version;
private Node source;
private Node target;
private QNameEntity typeQName;
private Long typeQNameId;
private transient ReadLock refReadLock;
private transient WriteLock refWriteLock;
private transient AssociationRef nodeAssocRef;
private transient QName typeQName;
public NodeAssocImpl()
{
@@ -68,7 +70,7 @@ public class NodeAssocImpl implements NodeAssoc, Serializable
this.setSource(sourceNode);
}
public AssociationRef getNodeAssocRef()
public AssociationRef getNodeAssocRef(QNameDAO qnameDAO)
{
boolean trashReference = false;
// first check if it is available
@@ -98,12 +100,16 @@ public class NodeAssocImpl implements NodeAssoc, Serializable
refWriteLock.lock();
try
{
if (typeQName == null)
{
typeQName = qnameDAO.getQName(typeQNameId).getSecond();
}
// double check
if (nodeAssocRef == null || trashReference)
{
nodeAssocRef = new AssociationRef(
getSource().getNodeRef(),
this.typeQName.getQName(),
this.typeQName,
getTarget().getNodeRef());
}
return nodeAssocRef;
@@ -114,13 +120,54 @@ public class NodeAssocImpl implements NodeAssoc, Serializable
}
}
public QName getTypeQName(QNameDAO qnameDAO)
{
refReadLock.lock();
try
{
if (typeQName != null)
{
return typeQName;
}
}
finally
{
refReadLock.unlock();
}
// get write lock
refWriteLock.lock();
try
{
typeQName = qnameDAO.getQName(typeQNameId).getSecond();
return typeQName;
}
finally
{
refWriteLock.unlock();
}
}
public void setTypeQName(QNameDAO qnameDAO, QName typeQName)
{
Long typeQNameId = qnameDAO.getOrCreateQName(typeQName).getFirst();
refWriteLock.lock();
try
{
setTypeQNameId(typeQNameId);
}
finally
{
refWriteLock.unlock();
}
}
public String toString()
{
StringBuffer sb = new StringBuffer(32);
sb.append("NodeAssoc")
.append("[ source=").append(source)
.append(", target=").append(target)
.append(", name=").append(getTypeQName())
.append(", type=").append(typeQNameId)
.append("]");
return sb.toString();
}
@@ -140,14 +187,22 @@ public class NodeAssocImpl implements NodeAssoc, Serializable
return false;
}
NodeAssoc that = (NodeAssoc) obj;
return (EqualsHelper.nullSafeEquals(this.getTypeQName(), that.getTypeQName())
&& EqualsHelper.nullSafeEquals(this.getTarget(), that.getTarget())
&& EqualsHelper.nullSafeEquals(this.getSource(), that.getSource()));
if (EqualsHelper.nullSafeEquals(this.typeQNameId, that.getId()))
{
return true;
}
else
{
return (EqualsHelper.nullSafeEquals(this.typeQNameId, that.getTypeQNameId())
&& EqualsHelper.nullSafeEquals(this.getTarget(), that.getTarget())
&& EqualsHelper.nullSafeEquals(this.getSource(), that.getSource())
);
}
}
public int hashCode()
{
return (typeQName == null ? 0 : typeQName.hashCode());
return (typeQNameId == null ? 0 : typeQNameId.hashCode());
}
public Long getId()
@@ -222,18 +277,19 @@ public class NodeAssocImpl implements NodeAssoc, Serializable
}
}
public QNameEntity getTypeQName()
public Long getTypeQNameId()
{
return typeQName;
return typeQNameId;
}
public void setTypeQName(QNameEntity typeQName)
public void setTypeQNameId(Long typeQNameId)
{
refWriteLock.lock();
try
{
this.typeQName = typeQName;
this.typeQNameId = typeQNameId;
this.nodeAssocRef = null;
this.typeQName = null;
}
finally
{

View File

@@ -38,10 +38,11 @@ import org.alfresco.repo.domain.DbAccessControlList;
import org.alfresco.repo.domain.Node;
import org.alfresco.repo.domain.NodePropertyValue;
import org.alfresco.repo.domain.PropertyMapKey;
import org.alfresco.repo.domain.QNameEntity;
import org.alfresco.repo.domain.QNameDAO;
import org.alfresco.repo.domain.Store;
import org.alfresco.repo.domain.Transaction;
import org.alfresco.service.cmr.repository.NodeRef;
import org.alfresco.service.namespace.QName;
import org.alfresco.util.EqualsHelper;
/**
@@ -60,7 +61,7 @@ public class NodeImpl extends LifecycleAdapter implements Node, Serializable
private Long version;
private Store store;
private String uuid;
private QNameEntity typeQName;
private Long typeQNameId;
private Transaction transaction;
private boolean deleted;
private DbAccessControlList accessControlList;
@@ -71,6 +72,7 @@ public class NodeImpl extends LifecycleAdapter implements Node, Serializable
private transient ReadLock refReadLock;
private transient WriteLock refWriteLock;
private transient NodeRef nodeRef;
private transient QName typeQName;
public NodeImpl()
{
@@ -118,6 +120,46 @@ public class NodeImpl extends LifecycleAdapter implements Node, Serializable
}
}
public QName getTypeQName(QNameDAO qnameDAO)
{
refReadLock.lock();
try
{
if (typeQName != null)
{
return typeQName;
}
}
finally
{
refReadLock.unlock();
}
refWriteLock.lock();
try
{
typeQName = qnameDAO.getQName(typeQNameId).getSecond();
return typeQName;
}
finally
{
refWriteLock.unlock();
}
}
public void setTypeQName(QNameDAO qnameDAO, QName qname)
{
refWriteLock.lock();
try
{
Long typeQNameId = qnameDAO.getOrCreateQName(qname).getFirst();
setTypeQNameId(typeQNameId);
}
finally
{
refWriteLock.unlock();
}
}
/**
* @see #getNodeRef()
*/
@@ -249,14 +291,23 @@ public class NodeImpl extends LifecycleAdapter implements Node, Serializable
this.deleted = deleted;
}
public QNameEntity getTypeQName()
public Long getTypeQNameId()
{
return typeQName;
return typeQNameId;
}
public void setTypeQName(QNameEntity typeQName)
public void setTypeQNameId(Long typeQNameId)
{
this.typeQName = typeQName;
refWriteLock.lock();
try
{
this.typeQNameId = typeQNameId;
this.typeQName = null;
}
finally
{
refWriteLock.unlock();
}
}
public DbAccessControlList getAccessControlList()

View File

@@ -173,17 +173,8 @@
</id>
<natural-id mutable="true" >
<many-to-one
name="typeQName"
class="org.alfresco.repo.domain.hibernate.QNameEntityImpl"
column="type_qname_id"
foreign-key="fk_alf_perm_tqn"
lazy="proxy"
fetch="select"
unique="false"
not-null="true"
cascade="none" />
<property name="name" type="string" length="100" column="name" />
<property name="typeQNameId" column="type_qname_id" type="long" not-null="true" /> <!-- fk_alf_perm_tqn -->
<property name="name" type="string" length="100" column="name" />
</natural-id>
<version column="version" name="version" type="long" />
@@ -275,7 +266,7 @@
from
org.alfresco.repo.domain.hibernate.DbPermissionImpl as permission
where
permission.typeQName = :permissionTypeQName and
permission.typeQNameId = :permissionTypeQNameId and
permission.name = :permissionName
</query>