mirror of
https://github.com/Alfresco/alfresco-community-repo.git
synced 2025-07-24 17:32:48 +00:00
Schema changes and ID-based node storage
git-svn-id: https://svn.alfresco.com/repos/alfresco-enterprise/alfresco/HEAD/root@2727 c4b6b30b-aa2e-2d43-bbcb-ca4b014f7261
This commit is contained in:
@@ -31,13 +31,11 @@ import org.alfresco.model.ContentModel;
|
||||
import org.alfresco.repo.domain.ChildAssoc;
|
||||
import org.alfresco.repo.domain.Node;
|
||||
import org.alfresco.repo.domain.NodeAssoc;
|
||||
import org.alfresco.repo.domain.NodeKey;
|
||||
import org.alfresco.repo.domain.NodeStatus;
|
||||
import org.alfresco.repo.domain.PropertyValue;
|
||||
import org.alfresco.repo.domain.Store;
|
||||
import org.alfresco.repo.node.AbstractNodeServiceImpl;
|
||||
import org.alfresco.repo.policy.PolicyComponent;
|
||||
import org.alfresco.repo.transaction.AlfrescoTransactionSupport;
|
||||
import org.alfresco.service.cmr.dictionary.AspectDefinition;
|
||||
import org.alfresco.service.cmr.dictionary.ClassDefinition;
|
||||
import org.alfresco.service.cmr.dictionary.DataTypeDefinition;
|
||||
@@ -92,9 +90,7 @@ public class DbNodeServiceImpl extends AbstractNodeServiceImpl
|
||||
*/
|
||||
private Node getNodeNotNull(NodeRef nodeRef) throws InvalidNodeRefException
|
||||
{
|
||||
String protocol = nodeRef.getStoreRef().getProtocol();
|
||||
String identifier = nodeRef.getStoreRef().getIdentifier();
|
||||
Node unchecked = nodeDaoService.getNode(protocol, identifier, nodeRef.getId());
|
||||
Node unchecked = nodeDaoService.getNode(nodeRef);
|
||||
if (unchecked == null)
|
||||
{
|
||||
throw new InvalidNodeRefException("Node does not exist: " + nodeRef, nodeRef);
|
||||
@@ -112,10 +108,7 @@ public class DbNodeServiceImpl extends AbstractNodeServiceImpl
|
||||
|
||||
public boolean exists(NodeRef nodeRef)
|
||||
{
|
||||
StoreRef storeRef = nodeRef.getStoreRef();
|
||||
Node node = nodeDaoService.getNode(storeRef.getProtocol(),
|
||||
storeRef.getIdentifier(),
|
||||
nodeRef.getId());
|
||||
Node node = nodeDaoService.getNode(nodeRef);
|
||||
boolean exists = (node != null);
|
||||
// done
|
||||
return exists;
|
||||
@@ -123,10 +116,7 @@ public class DbNodeServiceImpl extends AbstractNodeServiceImpl
|
||||
|
||||
public Status getNodeStatus(NodeRef nodeRef)
|
||||
{
|
||||
NodeStatus nodeStatus = nodeDaoService.getNodeStatus(
|
||||
nodeRef.getStoreRef().getProtocol(),
|
||||
nodeRef.getStoreRef().getIdentifier(),
|
||||
nodeRef.getId());
|
||||
NodeStatus nodeStatus = nodeDaoService.getNodeStatus(nodeRef);
|
||||
if (nodeStatus == null) // node never existed
|
||||
{
|
||||
return null;
|
||||
@@ -416,8 +406,7 @@ public class DbNodeServiceImpl extends AbstractNodeServiceImpl
|
||||
invokeOnUpdateNode(newParentRef);
|
||||
|
||||
// update the node status
|
||||
NodeStatus nodeStatus = nodeToMove.getStatus();
|
||||
nodeStatus.setChangeTxnId(AlfrescoTransactionSupport.getTransactionId());
|
||||
nodeDaoService.recordChangeId(nodeToMoveRef);
|
||||
|
||||
// done
|
||||
return newAssoc.getChildAssocRef();
|
||||
@@ -526,8 +515,7 @@ public class DbNodeServiceImpl extends AbstractNodeServiceImpl
|
||||
invokeOnAddAspect(nodeRef, aspectTypeQName);
|
||||
|
||||
// update the node status
|
||||
NodeStatus nodeStatus = node.getStatus();
|
||||
nodeStatus.setChangeTxnId(AlfrescoTransactionSupport.getTransactionId());
|
||||
nodeDaoService.recordChangeId(nodeRef);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -581,8 +569,7 @@ public class DbNodeServiceImpl extends AbstractNodeServiceImpl
|
||||
invokeOnRemoveAspect(nodeRef, aspectTypeQName);
|
||||
|
||||
// update the node status
|
||||
NodeStatus nodeStatus = node.getStatus();
|
||||
nodeStatus.setChangeTxnId(AlfrescoTransactionSupport.getTransactionId());
|
||||
nodeDaoService.recordChangeId(nodeRef);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -758,7 +745,7 @@ public class DbNodeServiceImpl extends AbstractNodeServiceImpl
|
||||
{
|
||||
Node parentNode = getNodeNotNull(parentRef);
|
||||
Node childNode = getNodeNotNull(childRef);
|
||||
NodeKey childNodeKey = childNode.getKey();
|
||||
Long childNodeId = childNode.getId();
|
||||
|
||||
// get all the child assocs
|
||||
ChildAssociationRef primaryAssocRef = null;
|
||||
@@ -766,7 +753,7 @@ public class DbNodeServiceImpl extends AbstractNodeServiceImpl
|
||||
assocs = new HashSet<ChildAssoc>(assocs); // copy set as we will be modifying it
|
||||
for (ChildAssoc assoc : assocs)
|
||||
{
|
||||
if (!assoc.getChild().getKey().equals(childNodeKey))
|
||||
if (!assoc.getChild().getId().equals(childNodeId))
|
||||
{
|
||||
continue; // not a matching association
|
||||
}
|
||||
@@ -901,8 +888,7 @@ public class DbNodeServiceImpl extends AbstractNodeServiceImpl
|
||||
invokeOnUpdateProperties(nodeRef, propertiesBefore, propertiesAfter);
|
||||
|
||||
// update the node status
|
||||
NodeStatus nodeStatus = node.getStatus();
|
||||
nodeStatus.setChangeTxnId(AlfrescoTransactionSupport.getTransactionId());
|
||||
nodeDaoService.recordChangeId(nodeRef);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -937,8 +923,7 @@ public class DbNodeServiceImpl extends AbstractNodeServiceImpl
|
||||
invokeOnUpdateProperties(nodeRef, propertiesBefore, propertiesAfter);
|
||||
|
||||
// update the node status
|
||||
NodeStatus nodeStatus = node.getStatus();
|
||||
nodeStatus.setChangeTxnId(AlfrescoTransactionSupport.getTransactionId());
|
||||
nodeDaoService.recordChangeId(nodeRef);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@@ -190,19 +190,13 @@ public class DbNodeServiceImplTest extends BaseNodeServiceTest
|
||||
public Object doWork()
|
||||
{
|
||||
// check n6
|
||||
NodeStatus n6Status = nodeDaoService.getNodeStatus(
|
||||
n6Ref.getStoreRef().getProtocol(),
|
||||
n6Ref.getStoreRef().getIdentifier(),
|
||||
n6Ref.getId());
|
||||
NodeStatus n6Status = nodeDaoService.getNodeStatus(n6Ref);
|
||||
if (!n6Status.isDeleted())
|
||||
{
|
||||
throw new RuntimeException("Deleted node does not have deleted status");
|
||||
}
|
||||
// n8 is a primary child - it should be deleted too
|
||||
NodeStatus n8Status = nodeDaoService.getNodeStatus(
|
||||
n8Ref.getStoreRef().getProtocol(),
|
||||
n8Ref.getStoreRef().getIdentifier(),
|
||||
n8Ref.getId());
|
||||
NodeStatus n8Status = nodeDaoService.getNodeStatus(n8Ref);
|
||||
if (!n8Status.isDeleted())
|
||||
{
|
||||
throw new RuntimeException("Cascade-deleted node does not have deleted status");
|
||||
|
@@ -25,6 +25,7 @@ import org.alfresco.repo.domain.NodeAssoc;
|
||||
import org.alfresco.repo.domain.NodeStatus;
|
||||
import org.alfresco.repo.domain.Store;
|
||||
import org.alfresco.service.cmr.dictionary.InvalidTypeException;
|
||||
import org.alfresco.service.cmr.repository.NodeRef;
|
||||
import org.alfresco.service.namespace.QName;
|
||||
|
||||
/**
|
||||
@@ -63,24 +64,40 @@ public interface NodeDaoService
|
||||
* @return Returns a store with the given values or null if one doesn't exist
|
||||
*/
|
||||
public Store getStore(String protocol, String identifier);
|
||||
|
||||
/**
|
||||
* Gets the node's status. If the node <i>never</i> existed, then
|
||||
* <code>null</code> is returned.
|
||||
*
|
||||
* @param nodeRef the node reference
|
||||
* @return Returns the node status if the node exists or once existed, otherwise
|
||||
* returns <code>null</code>.
|
||||
*/
|
||||
public NodeStatus getNodeStatus(NodeRef nodeRef);
|
||||
|
||||
/**
|
||||
* Sets the current transaction ID on the node status. Note that the node
|
||||
* may not exist, but the status will.
|
||||
*
|
||||
* @param nodeRef the node reference
|
||||
*/
|
||||
public void recordChangeId(NodeRef nodeRef);
|
||||
|
||||
/**
|
||||
* @param store the store to which the node must belong
|
||||
* @param id the node store-unique identifier
|
||||
* @param uuid the node store-unique identifier
|
||||
* @param nodeTypeQName the type of the node
|
||||
* @return Returns a new node of the given type and attached to the store
|
||||
* @throws InvalidTypeException if the node type is invalid or if the node type
|
||||
* is not a valid real node
|
||||
*/
|
||||
public Node newNode(Store store, String id, QName nodeTypeQName) throws InvalidTypeException;
|
||||
public Node newNode(Store store, String uuid, QName nodeTypeQName) throws InvalidTypeException;
|
||||
|
||||
/**
|
||||
* @param protocol the store protocol
|
||||
* @param identifier the store identifier for the given protocol
|
||||
* @param id the store-specific node identifier
|
||||
* @param nodeRef the node reference
|
||||
* @return Returns the <b>node</b> entity
|
||||
*/
|
||||
public Node getNode(String protocol, String identifier, String id);
|
||||
public Node getNode(NodeRef nodeRef);
|
||||
|
||||
/**
|
||||
* Deletes the node instance, taking care of any cascades that are required over
|
||||
@@ -165,18 +182,6 @@ public interface NodeDaoService
|
||||
*/
|
||||
public void deleteNodeAssoc(NodeAssoc assoc);
|
||||
|
||||
/**
|
||||
* Gets the node's status. If the node <i>never</i> existed, then
|
||||
* <code>null</code> is returned.
|
||||
*
|
||||
* @param protocol the store protocol
|
||||
* @param identifier the store identifier for the given protocol
|
||||
* @param id the store-specific node status identifier
|
||||
* @return Returns the node status if the node exists or once existed, otherwise
|
||||
* returns <code>null</code>.
|
||||
*/
|
||||
public NodeStatus getNodeStatus(String protocol, String identifier, String id);
|
||||
|
||||
/**
|
||||
* Fetch all content data strings. These are all string values that begin
|
||||
* with <b>contentUrl=</b>.
|
||||
|
@@ -37,6 +37,7 @@ import org.alfresco.repo.node.db.NodeDaoService;
|
||||
import org.alfresco.repo.transaction.AlfrescoTransactionSupport;
|
||||
import org.alfresco.service.cmr.dictionary.InvalidTypeException;
|
||||
import org.alfresco.service.cmr.repository.ChildAssociationRef;
|
||||
import org.alfresco.service.cmr.repository.NodeRef;
|
||||
import org.alfresco.service.namespace.QName;
|
||||
import org.alfresco.util.GUID;
|
||||
import org.hibernate.ObjectDeletedException;
|
||||
@@ -173,59 +174,91 @@ public class HibernateNodeDaoServiceImpl extends HibernateDaoSupport implements
|
||||
return store;
|
||||
}
|
||||
|
||||
public Node newNode(Store store, String id, QName nodeTypeQName) throws InvalidTypeException
|
||||
{
|
||||
NodeKey key = new NodeKey(store.getKey(), id);
|
||||
|
||||
// create (or reuse) the mandatory node status
|
||||
NodeStatus nodeStatus = (NodeStatus) getHibernateTemplate().get(NodeStatusImpl.class, key);
|
||||
if (nodeStatus == null)
|
||||
{
|
||||
nodeStatus = new NodeStatusImpl();
|
||||
}
|
||||
// set required status properties
|
||||
nodeStatus.setKey(key);
|
||||
nodeStatus.setDeleted(false);
|
||||
nodeStatus.setChangeTxnId(AlfrescoTransactionSupport.getTransactionId());
|
||||
// persist the nodestatus
|
||||
getHibernateTemplate().save(nodeStatus);
|
||||
|
||||
// build a concrete node based on a bootstrap type
|
||||
Node node = new NodeImpl();
|
||||
// set other required properties
|
||||
node.setKey(key);
|
||||
node.setTypeQName(nodeTypeQName);
|
||||
node.setStore(store);
|
||||
node.setStatus(nodeStatus);
|
||||
// persist the node
|
||||
getHibernateTemplate().save(node);
|
||||
// done
|
||||
return node;
|
||||
}
|
||||
|
||||
public Node getNode(String protocol, String identifier, String id)
|
||||
/**
|
||||
* Fetch the node status, if it exists
|
||||
*/
|
||||
public NodeStatus getNodeStatus(NodeRef nodeRef)
|
||||
{
|
||||
try
|
||||
{
|
||||
NodeKey nodeKey = new NodeKey(protocol, identifier, id);
|
||||
Object obj = getHibernateTemplate().get(NodeImpl.class, nodeKey);
|
||||
NodeKey nodeKey = new NodeKey(nodeRef);
|
||||
Object obj = getHibernateTemplate().get(NodeStatusImpl.class, nodeKey);
|
||||
// done
|
||||
return (Node) obj;
|
||||
}
|
||||
catch (ObjectDeletedException e)
|
||||
{
|
||||
return null;
|
||||
return (NodeStatus) obj;
|
||||
}
|
||||
catch (DataAccessException e)
|
||||
{
|
||||
if (e.contains(ObjectDeletedException.class))
|
||||
{
|
||||
// the object no loner exists
|
||||
// the object no longer exists
|
||||
return null;
|
||||
}
|
||||
throw e;
|
||||
}
|
||||
}
|
||||
|
||||
public void recordChangeId(NodeRef nodeRef)
|
||||
{
|
||||
NodeKey key = new NodeKey(nodeRef);
|
||||
|
||||
NodeStatus status = (NodeStatus) getHibernateTemplate().get(NodeStatusImpl.class, key);
|
||||
if (status == null)
|
||||
{
|
||||
// the node never existed or the status was deleted
|
||||
return;
|
||||
}
|
||||
else
|
||||
{
|
||||
status.setChangeTxnId(AlfrescoTransactionSupport.getTransactionId());
|
||||
}
|
||||
}
|
||||
|
||||
public Node newNode(Store store, String uuid, QName nodeTypeQName) throws InvalidTypeException
|
||||
{
|
||||
NodeKey key = new NodeKey(store.getKey(), uuid);
|
||||
|
||||
// build a concrete node based on a bootstrap type
|
||||
Node node = new NodeImpl();
|
||||
// set other required properties
|
||||
node.setStore(store);
|
||||
node.setUuid(uuid);
|
||||
node.setTypeQName(nodeTypeQName);
|
||||
// persist the node
|
||||
getHibernateTemplate().save(node);
|
||||
|
||||
// create (or reuse) the mandatory node status
|
||||
NodeStatus status = (NodeStatus) getHibernateTemplate().get(NodeStatusImpl.class, key);
|
||||
if (status == null)
|
||||
{
|
||||
status = new NodeStatusImpl();
|
||||
status.setKey(key);
|
||||
}
|
||||
// set required status properties
|
||||
status.setNode(node);
|
||||
status.setChangeTxnId(AlfrescoTransactionSupport.getTransactionId());
|
||||
// persist the nodestatus
|
||||
getHibernateTemplate().save(status);
|
||||
|
||||
// done
|
||||
return node;
|
||||
}
|
||||
|
||||
public Node getNode(NodeRef nodeRef)
|
||||
{
|
||||
// get it via the node status
|
||||
NodeStatus status = getNodeStatus(nodeRef);
|
||||
if (status == null)
|
||||
{
|
||||
// no status implies no node
|
||||
return null;
|
||||
}
|
||||
else
|
||||
{
|
||||
// a status may have a node
|
||||
Node node = status.getNode();
|
||||
return node;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Manually ensures that all cascading of associations is taken care of
|
||||
@@ -261,37 +294,23 @@ public class HibernateNodeDaoServiceImpl extends HibernateDaoSupport implements
|
||||
deleteNodeAssoc(assoc);
|
||||
}
|
||||
// update the node status
|
||||
NodeStatus nodeStatus = node.getStatus();
|
||||
nodeStatus.setDeleted(true);
|
||||
nodeStatus.setChangeTxnId(AlfrescoTransactionSupport.getTransactionId());
|
||||
NodeRef nodeRef = node.getNodeRef();
|
||||
NodeStatus nodeStatus = getNodeStatus(nodeRef);
|
||||
if (nodeStatus == null)
|
||||
{
|
||||
logger.warn("Node to be deleted does not have a status: \n" +
|
||||
" node: " + node.getId());
|
||||
}
|
||||
else
|
||||
{
|
||||
nodeStatus.setNode(null);
|
||||
nodeStatus.setChangeTxnId(AlfrescoTransactionSupport.getTransactionId());
|
||||
}
|
||||
// finally delete the node
|
||||
getHibernateTemplate().delete(node);
|
||||
// done
|
||||
}
|
||||
|
||||
/**
|
||||
* Fetch the node status, if it exists
|
||||
*/
|
||||
public NodeStatus getNodeStatus(String protocol, String identifier, String id)
|
||||
{
|
||||
try
|
||||
{
|
||||
NodeKey nodeKey = new NodeKey(protocol, identifier, id);
|
||||
Object obj = getHibernateTemplate().get(NodeStatusImpl.class, nodeKey);
|
||||
// done
|
||||
return (NodeStatus) obj;
|
||||
}
|
||||
catch (DataAccessException e)
|
||||
{
|
||||
if (e.contains(ObjectDeletedException.class))
|
||||
{
|
||||
// the object no loner exists
|
||||
return null;
|
||||
}
|
||||
throw e;
|
||||
}
|
||||
}
|
||||
|
||||
public ChildAssoc newChildAssoc(
|
||||
Node parentNode,
|
||||
Node childNode,
|
||||
@@ -427,21 +446,15 @@ public class HibernateNodeDaoServiceImpl extends HibernateDaoSupport implements
|
||||
final Node targetNode,
|
||||
final QName assocTypeQName)
|
||||
{
|
||||
final NodeKey sourceKey = sourceNode.getKey();
|
||||
final NodeKey targetKey = targetNode.getKey();
|
||||
HibernateCallback callback = new HibernateCallback()
|
||||
{
|
||||
public Object doInHibernate(Session session)
|
||||
{
|
||||
Query query = session.getNamedQuery(HibernateNodeDaoServiceImpl.QUERY_GET_NODE_ASSOC);
|
||||
query.setString("sourceKeyProtocol", sourceKey.getProtocol())
|
||||
.setString("sourceKeyIdentifier", sourceKey.getIdentifier())
|
||||
.setString("sourceKeyGuid", sourceKey.getGuid())
|
||||
query.setEntity("sourceNode", sourceNode)
|
||||
.setEntity("targetNode", targetNode)
|
||||
.setString("assocTypeQName", assocTypeQName.toString())
|
||||
.setString("targetKeyProtocol", targetKey.getProtocol())
|
||||
.setString("targetKeyIdentifier", targetKey.getIdentifier())
|
||||
.setString("targetKeyGuid", targetKey.getGuid());
|
||||
query.setMaxResults(1);
|
||||
.setMaxResults(1);
|
||||
return query.uniqueResult();
|
||||
}
|
||||
};
|
||||
@@ -458,15 +471,12 @@ public class HibernateNodeDaoServiceImpl extends HibernateDaoSupport implements
|
||||
@SuppressWarnings("unchecked")
|
||||
public Collection<Node> getNodeAssocTargets(final Node sourceNode, final QName assocTypeQName)
|
||||
{
|
||||
final NodeKey sourceKey = sourceNode.getKey();
|
||||
HibernateCallback callback = new HibernateCallback()
|
||||
{
|
||||
public Object doInHibernate(Session session)
|
||||
{
|
||||
Query query = session.getNamedQuery(HibernateNodeDaoServiceImpl.QUERY_GET_NODE_ASSOC_TARGETS);
|
||||
query.setString("sourceKeyProtocol", sourceKey.getProtocol())
|
||||
.setString("sourceKeyIdentifier", sourceKey.getIdentifier())
|
||||
.setString("sourceKeyGuid", sourceKey.getGuid())
|
||||
query.setEntity("sourceNode", sourceNode)
|
||||
.setString("assocTypeQName", assocTypeQName.toString());
|
||||
return query.list();
|
||||
}
|
||||
@@ -479,15 +489,12 @@ public class HibernateNodeDaoServiceImpl extends HibernateDaoSupport implements
|
||||
@SuppressWarnings("unchecked")
|
||||
public Collection<Node> getNodeAssocSources(final Node targetNode, final QName assocTypeQName)
|
||||
{
|
||||
final NodeKey targetKey = targetNode.getKey();
|
||||
HibernateCallback callback = new HibernateCallback()
|
||||
{
|
||||
public Object doInHibernate(Session session)
|
||||
{
|
||||
Query query = session.getNamedQuery(HibernateNodeDaoServiceImpl.QUERY_GET_NODE_ASSOC_SOURCES);
|
||||
query.setString("targetKeyProtocol", targetKey.getProtocol())
|
||||
.setString("targetKeyIdentifier", targetKey.getIdentifier())
|
||||
.setString("targetKeyGuid", targetKey.getGuid())
|
||||
query.setEntity("targetNode", targetNode)
|
||||
.setString("assocTypeQName", assocTypeQName.toString());
|
||||
return query.list();
|
||||
}
|
||||
|
Reference in New Issue
Block a user