mirror of
https://github.com/Alfresco/alfresco-community-repo.git
synced 2025-06-16 17:55:15 +00:00
Fix ups for null permissions
git-svn-id: https://svn.alfresco.com/repos/alfresco-enterprise/alfresco/HEAD/root@9988 c4b6b30b-aa2e-2d43-bbcb-ca4b014f7261
This commit is contained in:
parent
ec903f2dc1
commit
08a552304e
@ -99,13 +99,19 @@ import org.springframework.util.Assert;
|
||||
public class DbNodeServiceImpl extends AbstractNodeServiceImpl
|
||||
{
|
||||
private static Log logger = LogFactory.getLog(DbNodeServiceImpl.class);
|
||||
|
||||
private static Log loggerPaths = LogFactory.getLog(DbNodeServiceImpl.class.getName() + ".paths");
|
||||
|
||||
private QNameDAO qnameDAO;
|
||||
|
||||
private NodeDaoService nodeDaoService;
|
||||
|
||||
private StoreArchiveMap storeArchiveMap;
|
||||
|
||||
private NodeService avmNodeService;
|
||||
|
||||
private TenantService tenantService;
|
||||
|
||||
private AclDaoComponent aclDaoComponent;
|
||||
|
||||
public DbNodeServiceImpl()
|
||||
@ -149,9 +155,11 @@ public class DbNodeServiceImpl extends AbstractNodeServiceImpl
|
||||
/**
|
||||
* Performs a null-safe get of the node
|
||||
*
|
||||
* @param nodeRef the node to retrieve
|
||||
* @param nodeRef
|
||||
* the node to retrieve
|
||||
* @return Returns the node entity (never null)
|
||||
* @throws InvalidNodeRefException if the referenced node could not be found
|
||||
* @throws InvalidNodeRefException
|
||||
* if the referenced node could not be found
|
||||
*/
|
||||
private Node getNodeNotNull(NodeRef nodeRef) throws InvalidNodeRefException
|
||||
{
|
||||
@ -167,9 +175,12 @@ public class DbNodeServiceImpl extends AbstractNodeServiceImpl
|
||||
|
||||
/**
|
||||
* Gets the node status for a live node.
|
||||
* @param nodeRef the node reference
|
||||
*
|
||||
* @param nodeRef
|
||||
* the node reference
|
||||
* @return Returns the node status, which will not be <tt>null</tt> and will have a live node attached.
|
||||
* @throws InvalidNodeRefException if the node is deleted or never existed
|
||||
* @throws InvalidNodeRefException
|
||||
* if the node is deleted or never existed
|
||||
*/
|
||||
public NodeStatus getNodeStatusNotNull(NodeRef nodeRef) throws InvalidNodeRefException
|
||||
{
|
||||
@ -212,9 +223,7 @@ public class DbNodeServiceImpl extends AbstractNodeServiceImpl
|
||||
}
|
||||
else
|
||||
{
|
||||
return new NodeRef.Status(
|
||||
nodeStatus.getTransaction().getChangeTxnId(),
|
||||
nodeStatus.isDeleted());
|
||||
return new NodeRef.Status(nodeStatus.getTransaction().getChangeTxnId(), nodeStatus.isDeleted());
|
||||
}
|
||||
}
|
||||
|
||||
@ -234,7 +243,8 @@ public class DbNodeServiceImpl extends AbstractNodeServiceImpl
|
||||
{
|
||||
String currentUser = AuthenticationUtil.getCurrentUserName();
|
||||
|
||||
// MT: return tenant stores only (although for super System return all stores - as used by ConfigurationChecker, IndexRecovery, IndexBackup etc)
|
||||
// MT: return tenant stores only (although for super System return all stores - as used by
|
||||
// ConfigurationChecker, IndexRecovery, IndexBackup etc)
|
||||
if ((currentUser == null) || (!currentUser.equals(AuthenticationUtil.getSystemUserName())))
|
||||
{
|
||||
tenantService.checkDomain(storeRef.getIdentifier());
|
||||
@ -258,6 +268,7 @@ public class DbNodeServiceImpl extends AbstractNodeServiceImpl
|
||||
|
||||
/**
|
||||
* Defers to the typed service
|
||||
*
|
||||
* @see StoreDaoService#createWorkspace(String)
|
||||
*/
|
||||
public StoreRef createStore(String protocol, String identifier)
|
||||
@ -281,9 +292,7 @@ public class DbNodeServiceImpl extends AbstractNodeServiceImpl
|
||||
NodeRef rootNodeRef = tenantService.getBaseName(rootNode.getNodeRef());
|
||||
|
||||
// assign the root aspect - this is expected of all roots, even store roots
|
||||
addAspect(rootNodeRef,
|
||||
ContentModel.ASPECT_ROOT,
|
||||
Collections.<QName, Serializable>emptyMap());
|
||||
addAspect(rootNodeRef, ContentModel.ASPECT_ROOT, Collections.<QName, Serializable> emptyMap());
|
||||
|
||||
// Bind root permission
|
||||
|
||||
@ -352,24 +361,17 @@ public class DbNodeServiceImpl extends AbstractNodeServiceImpl
|
||||
/**
|
||||
* @see #createNode(NodeRef, QName, QName, QName, Map)
|
||||
*/
|
||||
public ChildAssociationRef createNode(
|
||||
NodeRef parentRef,
|
||||
QName assocTypeQName,
|
||||
QName assocQName,
|
||||
QName nodeTypeQName)
|
||||
public ChildAssociationRef createNode(NodeRef parentRef, QName assocTypeQName, QName assocQName, QName nodeTypeQName)
|
||||
{
|
||||
return this.createNode(parentRef, assocTypeQName, assocQName, nodeTypeQName, null);
|
||||
}
|
||||
|
||||
/**
|
||||
* @see org.alfresco.service.cmr.repository.NodeService#createNode(org.alfresco.service.cmr.repository.NodeRef, org.alfresco.service.namespace.QName, org.alfresco.service.namespace.QName, org.alfresco.service.namespace.QName, java.util.Map)
|
||||
* @see org.alfresco.service.cmr.repository.NodeService#createNode(org.alfresco.service.cmr.repository.NodeRef,
|
||||
* org.alfresco.service.namespace.QName, org.alfresco.service.namespace.QName,
|
||||
* org.alfresco.service.namespace.QName, java.util.Map)
|
||||
*/
|
||||
public ChildAssociationRef createNode(
|
||||
NodeRef parentRef,
|
||||
QName assocTypeQName,
|
||||
QName assocQName,
|
||||
QName nodeTypeQName,
|
||||
Map<QName, Serializable> properties)
|
||||
public ChildAssociationRef createNode(NodeRef parentRef, QName assocTypeQName, QName assocQName, QName nodeTypeQName, Map<QName, Serializable> properties)
|
||||
{
|
||||
Assert.notNull(parentRef);
|
||||
Assert.notNull(assocTypeQName);
|
||||
@ -417,12 +419,7 @@ public class DbNodeServiceImpl extends AbstractNodeServiceImpl
|
||||
invokeBeforeCreateChildAssociation(parentRef, childNodeRef, assocTypeQName, assocQName, true);
|
||||
|
||||
// Create the association
|
||||
ChildAssoc childAssoc = nodeDaoService.newChildAssoc(
|
||||
parentNode,
|
||||
childNode,
|
||||
true,
|
||||
assocTypeQName,
|
||||
assocQName);
|
||||
ChildAssoc childAssoc = nodeDaoService.newChildAssoc(parentNode, childNode, true, assocTypeQName, assocQName);
|
||||
|
||||
// Set the default property values
|
||||
addDefaultPropertyValues(nodeTypeDef, properties);
|
||||
@ -499,12 +496,7 @@ public class DbNodeServiceImpl extends AbstractNodeServiceImpl
|
||||
/**
|
||||
* Drops the old primary association and creates a new one
|
||||
*/
|
||||
public ChildAssociationRef moveNode(
|
||||
NodeRef nodeToMoveRef,
|
||||
NodeRef newParentRef,
|
||||
QName assocTypeQName,
|
||||
QName assocQName)
|
||||
throws InvalidNodeRefException
|
||||
public ChildAssociationRef moveNode(NodeRef nodeToMoveRef, NodeRef newParentRef, QName assocTypeQName, QName assocQName) throws InvalidNodeRefException
|
||||
{
|
||||
Assert.notNull(nodeToMoveRef);
|
||||
Assert.notNull(newParentRef);
|
||||
@ -541,12 +533,7 @@ public class DbNodeServiceImpl extends AbstractNodeServiceImpl
|
||||
nodeDaoService.deleteChildAssoc(oldAssoc, false);
|
||||
|
||||
// create a new assoc
|
||||
ChildAssoc newAssoc = nodeDaoService.newChildAssoc(
|
||||
newParentNode,
|
||||
nodeToMove,
|
||||
true,
|
||||
assocTypeQName,
|
||||
assocQName);
|
||||
ChildAssoc newAssoc = nodeDaoService.newChildAssoc(newParentNode, nodeToMove, true, assocTypeQName, assocQName);
|
||||
setChildUniqueName(nodeToMove); // ensure uniqueness
|
||||
ChildAssociationRef newAssocRef = tenantService.getBaseName(newAssoc.getChildAssocRef());
|
||||
|
||||
@ -566,11 +553,15 @@ public class DbNodeServiceImpl extends AbstractNodeServiceImpl
|
||||
// Fix inherited permissions
|
||||
|
||||
if (aclDaoComponent != null)
|
||||
{
|
||||
if (newAssoc.getChild().getAccessControlList() != null)
|
||||
{
|
||||
Long targetAcl = newAssoc.getChild().getAccessControlList().getId();
|
||||
AccessControlListProperties aclProperties = aclDaoComponent.getAccessControlListProperties(targetAcl);
|
||||
Boolean inherits = aclProperties.getInherits();
|
||||
if ((inherits != null) && (inherits.booleanValue()))
|
||||
{
|
||||
if (newAssoc.getParent().getAccessControlList() != null)
|
||||
{
|
||||
Long parentAcl = newAssoc.getParent().getAccessControlList().getId();
|
||||
Long inheritedAcl = aclDaoComponent.getInheritedAccessControlList(parentAcl);
|
||||
@ -583,6 +574,33 @@ public class DbNodeServiceImpl extends AbstractNodeServiceImpl
|
||||
DMAccessControlListDAO.setFixedAcls(newAssoc.getChildAssocRef().getChildRef(), inheritedAcl, true, this, aclDaoComponent, nodeDaoService);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (aclProperties.getAclType() == ACLType.DEFINING)
|
||||
{
|
||||
|
||||
// there is nothing to inherit from so clear out any inherited aces
|
||||
aclDaoComponent.deleteInheritedAccessControlEntries(targetAcl);
|
||||
}
|
||||
else if (aclProperties.getAclType() == ACLType.SHARED)
|
||||
{
|
||||
// there is nothing to inherit
|
||||
nodeToMove.setAccessControlList(null);
|
||||
}
|
||||
|
||||
// throw new IllegalStateException("Share bug");
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (newAssoc.getParent().getAccessControlList() != null)
|
||||
{
|
||||
Long parentAcl = newAssoc.getParent().getAccessControlList().getId();
|
||||
Long inheritedAcl = aclDaoComponent.getInheritedAccessControlList(parentAcl);
|
||||
DMAccessControlListDAO.setFixedAcls(newAssoc.getChildAssocRef().getChildRef(), inheritedAcl, true, this, aclDaoComponent, nodeDaoService);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@ -596,7 +614,8 @@ public class DbNodeServiceImpl extends AbstractNodeServiceImpl
|
||||
nodeToMoveAspectQNames.add(nodeToMoveAspectQName);
|
||||
}
|
||||
// TODO for now indicate that the node has been archived to prevent the version history from being removed
|
||||
// in the future a onMove policy could be added and remove the need for onDelete and onCreate to be fired here
|
||||
// in the future a onMove policy could be added and remove the need for onDelete and onCreate to be fired
|
||||
// here
|
||||
invokeOnDeleteNode(oldAssocRef, nodeToMoveTypeQName, nodeToMoveAspectQNames, true);
|
||||
invokeOnCreateNode(newAssoc.getChildAssocRef());
|
||||
}
|
||||
@ -620,17 +639,10 @@ public class DbNodeServiceImpl extends AbstractNodeServiceImpl
|
||||
Node parentNode = getNodeNotNull(childAssocRef.getParentRef());
|
||||
Node childNode = getNodeNotNull(childAssocRef.getChildRef());
|
||||
|
||||
ChildAssoc assoc = nodeDaoService.getChildAssoc(
|
||||
parentNode,
|
||||
childNode,
|
||||
childAssocRef.getTypeQName(),
|
||||
childAssocRef.getQName());
|
||||
ChildAssoc assoc = nodeDaoService.getChildAssoc(parentNode, childNode, childAssocRef.getTypeQName(), childAssocRef.getQName());
|
||||
if (assoc == null)
|
||||
{
|
||||
throw new InvalidChildAssociationRefException("Unable to set child association index: \n" +
|
||||
" assoc: " + childAssocRef + "\n" +
|
||||
" index: " + index,
|
||||
childAssocRef);
|
||||
throw new InvalidChildAssociationRefException("Unable to set child association index: \n" + " assoc: " + childAssocRef + "\n" + " index: " + index, childAssocRef);
|
||||
}
|
||||
// set the index
|
||||
assoc.setIndex(index);
|
||||
@ -645,7 +657,8 @@ public class DbNodeServiceImpl extends AbstractNodeServiceImpl
|
||||
}
|
||||
|
||||
/**
|
||||
* @see org.alfresco.service.cmr.repository.NodeService#setType(org.alfresco.service.cmr.repository.NodeRef, org.alfresco.service.namespace.QName)
|
||||
* @see org.alfresco.service.cmr.repository.NodeService#setType(org.alfresco.service.cmr.repository.NodeRef,
|
||||
* org.alfresco.service.namespace.QName)
|
||||
*/
|
||||
public void setType(NodeRef nodeRef, QName typeQName) throws InvalidNodeRefException
|
||||
{
|
||||
@ -677,11 +690,7 @@ public class DbNodeServiceImpl extends AbstractNodeServiceImpl
|
||||
/**
|
||||
* @see Node#getAspects()
|
||||
*/
|
||||
public void addAspect(
|
||||
NodeRef nodeRef,
|
||||
QName aspectTypeQName,
|
||||
Map<QName, Serializable> aspectProperties)
|
||||
throws InvalidNodeRefException, InvalidAspectException
|
||||
public void addAspect(NodeRef nodeRef, QName aspectTypeQName, Map<QName, Serializable> aspectProperties) throws InvalidNodeRefException, InvalidAspectException
|
||||
{
|
||||
// check that the aspect is legal
|
||||
AspectDefinition aspectDef = dictionaryService.getAspect(aspectTypeQName);
|
||||
@ -730,8 +739,7 @@ public class DbNodeServiceImpl extends AbstractNodeServiceImpl
|
||||
/**
|
||||
* @see Node#getAspects()
|
||||
*/
|
||||
public void removeAspect(NodeRef nodeRef, QName aspectTypeQName)
|
||||
throws InvalidNodeRefException, InvalidAspectException
|
||||
public void removeAspect(NodeRef nodeRef, QName aspectTypeQName) throws InvalidNodeRefException, InvalidAspectException
|
||||
{
|
||||
// get the aspect
|
||||
AspectDefinition aspectDef = dictionaryService.getAspect(aspectTypeQName);
|
||||
@ -862,8 +870,7 @@ public class DbNodeServiceImpl extends AbstractNodeServiceImpl
|
||||
|
||||
// check if we need to archive the node
|
||||
StoreRef archiveStoreRef = null;
|
||||
if (nodeAspectQNameEntityIds.contains(aspectTempQNameEntity.getId()) ||
|
||||
nodeAspectQNameEntityIds.contains(aspectWorkingCopyQNameEntity.getId()))
|
||||
if (nodeAspectQNameEntityIds.contains(aspectTempQNameEntity.getId()) || nodeAspectQNameEntityIds.contains(aspectWorkingCopyQNameEntity.getId()))
|
||||
{
|
||||
// The node is either temporary or a working copy.
|
||||
// It can not be archived.
|
||||
@ -916,12 +923,7 @@ public class DbNodeServiceImpl extends AbstractNodeServiceImpl
|
||||
invokeBeforeCreateChildAssociation(parentRef, childRef, assocTypeQName, assocQName, false);
|
||||
|
||||
// make the association
|
||||
ChildAssoc assoc = nodeDaoService.newChildAssoc(
|
||||
parentNode,
|
||||
childNode,
|
||||
false,
|
||||
assocTypeQName,
|
||||
assocQName);
|
||||
ChildAssoc assoc = nodeDaoService.newChildAssoc(parentNode, childNode, false, assocTypeQName, assocQName);
|
||||
// ensure name uniqueness
|
||||
setChildUniqueName(childNode);
|
||||
ChildAssociationRef assocRef = assoc.getChildAssocRef();
|
||||
@ -1019,9 +1021,7 @@ public class DbNodeServiceImpl extends AbstractNodeServiceImpl
|
||||
}
|
||||
if (assoc.getIsPrimary())
|
||||
{
|
||||
throw new IllegalArgumentException(
|
||||
"removeSeconaryChildAssociation can not be applied to a primary association: \n" +
|
||||
" Child Assoc: " + assoc);
|
||||
throw new IllegalArgumentException("removeSeconaryChildAssociation can not be applied to a primary association: \n" + " Child Assoc: " + assoc);
|
||||
}
|
||||
// Delete the secondary association
|
||||
nodeDaoService.deleteChildAssoc(assoc, false);
|
||||
@ -1033,11 +1033,13 @@ public class DbNodeServiceImpl extends AbstractNodeServiceImpl
|
||||
}
|
||||
|
||||
/**
|
||||
* Remove properties that should not be persisted as general properties. Where necessary, the
|
||||
* properties are set on the node.
|
||||
* Remove properties that should not be persisted as general properties. Where necessary, the properties are set on
|
||||
* the node.
|
||||
*
|
||||
* @param node the node to set properties on
|
||||
* @param properties properties to change
|
||||
* @param node
|
||||
* the node to set properties on
|
||||
* @param properties
|
||||
* properties to change
|
||||
*/
|
||||
private void extractIntrinsicProperties(Node node, Map<QName, Serializable> properties)
|
||||
{
|
||||
@ -1048,18 +1050,19 @@ public class DbNodeServiceImpl extends AbstractNodeServiceImpl
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds all properties used by the
|
||||
* {@link ContentModel#ASPECT_REFERENCEABLE referencable aspect}.
|
||||
* Adds all properties used by the {@link ContentModel#ASPECT_REFERENCEABLE referencable aspect}.
|
||||
* <p>
|
||||
* This method can be used to ensure that the values used by the aspect
|
||||
* are present as node properties.
|
||||
* This method can be used to ensure that the values used by the aspect are present as node properties.
|
||||
* <p>
|
||||
* This method also ensures that the {@link ContentModel#PROP_NAME name property}
|
||||
* is always present as a property on a node.
|
||||
* This method also ensures that the {@link ContentModel#PROP_NAME name property} is always present as a property on
|
||||
* a node.
|
||||
*
|
||||
* @param node the node with the values
|
||||
* @param nodeRef the node reference containing the values required
|
||||
* @param properties the node properties
|
||||
* @param node
|
||||
* the node with the values
|
||||
* @param nodeRef
|
||||
* the node reference containing the values required
|
||||
* @param properties
|
||||
* the node properties
|
||||
*/
|
||||
private void addIntrinsicProperties(Node node, Map<QName, Serializable> properties)
|
||||
{
|
||||
@ -1159,14 +1162,14 @@ public class DbNodeServiceImpl extends AbstractNodeServiceImpl
|
||||
}
|
||||
|
||||
/**
|
||||
* Ensures that all required properties are present on the node and copies the
|
||||
* property values to the <code>Node</code>.
|
||||
* Ensures that all required properties are present on the node and copies the property values to the
|
||||
* <code>Node</code>.
|
||||
* <p>
|
||||
* To remove a property, <b>remove it from the map</b> before calling this method.
|
||||
* Null-valued properties are allowed.
|
||||
* To remove a property, <b>remove it from the map</b> before calling this method. Null-valued properties are
|
||||
* allowed.
|
||||
* <p>
|
||||
* If any of the values are null, a marker object is put in to mimic nulls. They will be turned back into
|
||||
* a real nulls when the properties are requested again.
|
||||
* If any of the values are null, a marker object is put in to mimic nulls. They will be turned back into a real
|
||||
* nulls when the properties are requested again.
|
||||
*
|
||||
* @see Node#getProperties()
|
||||
*/
|
||||
@ -1192,8 +1195,10 @@ public class DbNodeServiceImpl extends AbstractNodeServiceImpl
|
||||
* Does the work of setting the property values. Returns a map containing the state of the properties after the set
|
||||
* operation is complete.
|
||||
*
|
||||
* @param node the node
|
||||
* @param properties the map of property values
|
||||
* @param node
|
||||
* the node
|
||||
* @param properties
|
||||
* the map of property values
|
||||
* @return the map of property values after the set operation is complete
|
||||
* @throws InvalidNodeRefException
|
||||
*/
|
||||
@ -1229,8 +1234,7 @@ public class DbNodeServiceImpl extends AbstractNodeServiceImpl
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the properties map, sets the value (null is allowed) and checks that the new set
|
||||
* of properties is valid.
|
||||
* Gets the properties map, sets the value (null is allowed) and checks that the new set of properties is valid.
|
||||
*
|
||||
* @see DbNodeServiceImpl.NullPropertyValue
|
||||
*/
|
||||
@ -1262,9 +1266,12 @@ public class DbNodeServiceImpl extends AbstractNodeServiceImpl
|
||||
* Does the work of setting a property value. Returns the values of the properties after the set operation is
|
||||
* complete.
|
||||
*
|
||||
* @param node the node
|
||||
* @param qname the qname of the property
|
||||
* @param value the value of the property
|
||||
* @param node
|
||||
* the node
|
||||
* @param qname
|
||||
* the qname of the property
|
||||
* @param value
|
||||
* the value of the property
|
||||
* @return the values of the properties after the set operation is complete
|
||||
* @throws InvalidNodeRefException
|
||||
*/
|
||||
@ -1459,8 +1466,7 @@ public class DbNodeServiceImpl extends AbstractNodeServiceImpl
|
||||
return assocRef;
|
||||
}
|
||||
|
||||
public AssociationRef createAssociation(NodeRef sourceRef, NodeRef targetRef, QName assocTypeQName)
|
||||
throws InvalidNodeRefException, AssociationExistsException
|
||||
public AssociationRef createAssociation(NodeRef sourceRef, NodeRef targetRef, QName assocTypeQName) throws InvalidNodeRefException, AssociationExistsException
|
||||
{
|
||||
Node sourceNode = getNodeNotNull(sourceRef);
|
||||
Node targetNode = getNodeNotNull(targetRef);
|
||||
@ -1480,8 +1486,7 @@ public class DbNodeServiceImpl extends AbstractNodeServiceImpl
|
||||
return assocRef;
|
||||
}
|
||||
|
||||
public void removeAssociation(NodeRef sourceRef, NodeRef targetRef, QName assocTypeQName)
|
||||
throws InvalidNodeRefException
|
||||
public void removeAssociation(NodeRef sourceRef, NodeRef targetRef, QName assocTypeQName) throws InvalidNodeRefException
|
||||
{
|
||||
Node sourceNode = getNodeNotNull(sourceRef);
|
||||
Node targetNode = getNodeNotNull(targetRef);
|
||||
@ -1544,25 +1549,24 @@ public class DbNodeServiceImpl extends AbstractNodeServiceImpl
|
||||
/**
|
||||
* Recursive method used to build up paths from a given node to the root.
|
||||
* <p>
|
||||
* Whilst walking up the hierarchy to the root, some nodes may have a <b>root</b> aspect.
|
||||
* Everytime one of these is encountered, a new path is farmed off, but the method
|
||||
* continues to walk up the hierarchy.
|
||||
* Whilst walking up the hierarchy to the root, some nodes may have a <b>root</b> aspect. Everytime one of these is
|
||||
* encountered, a new path is farmed off, but the method continues to walk up the hierarchy.
|
||||
*
|
||||
* @param currentNode the node to start from, i.e. the child node to work upwards from
|
||||
* @param currentPath the path from the current node to the descendent that we started from
|
||||
* @param completedPaths paths that have reached the root are added to this collection
|
||||
* @param assocStack the parent-child relationships traversed whilst building the path.
|
||||
* Used to detected cyclic relationships.
|
||||
* @param primaryOnly true if only the primary parent association must be traversed.
|
||||
* If this is true, then the only root is the top level node having no parents.
|
||||
* @param currentNode
|
||||
* the node to start from, i.e. the child node to work upwards from
|
||||
* @param currentPath
|
||||
* the path from the current node to the descendent that we started from
|
||||
* @param completedPaths
|
||||
* paths that have reached the root are added to this collection
|
||||
* @param assocStack
|
||||
* the parent-child relationships traversed whilst building the path. Used to detected cyclic
|
||||
* relationships.
|
||||
* @param primaryOnly
|
||||
* true if only the primary parent association must be traversed. If this is true, then the only root is
|
||||
* the top level node having no parents.
|
||||
* @throws CyclicChildRelationshipException
|
||||
*/
|
||||
private void prependPaths(
|
||||
final Node currentNode,
|
||||
final Path currentPath,
|
||||
Collection<Path> completedPaths,
|
||||
Stack<ChildAssoc> assocStack,
|
||||
boolean primaryOnly)
|
||||
private void prependPaths(final Node currentNode, final Path currentPath, Collection<Path> completedPaths, Stack<ChildAssoc> assocStack, boolean primaryOnly)
|
||||
throws CyclicChildRelationshipException
|
||||
{
|
||||
NodeRef currentNodeRef = currentNode.getNodeRef();
|
||||
@ -1581,11 +1585,7 @@ public class DbNodeServiceImpl extends AbstractNodeServiceImpl
|
||||
// this effectively spoofs the fact that the current node is not below the root
|
||||
// - we put this assoc in as the first assoc in the path must be a one-sided
|
||||
// reference pointing to the root node
|
||||
ChildAssociationRef assocRef = new ChildAssociationRef(
|
||||
null,
|
||||
null,
|
||||
null,
|
||||
getRootNode(currentNode.getNodeRef().getStoreRef()));
|
||||
ChildAssociationRef assocRef = new ChildAssociationRef(null, null, null, getRootNode(currentNode.getNodeRef().getStoreRef()));
|
||||
// create a path to save and add the 'root' assoc
|
||||
Path pathToSave = new Path();
|
||||
Path.ChildAssocElement first = null;
|
||||
@ -1604,11 +1604,8 @@ public class DbNodeServiceImpl extends AbstractNodeServiceImpl
|
||||
{
|
||||
// mimic an association that would appear if the current node was below the root node
|
||||
// or if first beneath the root node it will make the real thing
|
||||
ChildAssociationRef updateAssocRef = new ChildAssociationRef(
|
||||
isStoreRoot ? ContentModel.ASSOC_CHILDREN : first.getRef().getTypeQName(),
|
||||
getRootNode(currentNode.getNodeRef().getStoreRef()),
|
||||
first.getRef().getQName(),
|
||||
first.getRef().getChildRef());
|
||||
ChildAssociationRef updateAssocRef = new ChildAssociationRef(isStoreRoot ? ContentModel.ASSOC_CHILDREN : first.getRef().getTypeQName(), getRootNode(currentNode
|
||||
.getNodeRef().getStoreRef()), first.getRef().getQName(), first.getRef().getChildRef());
|
||||
Path.Element newFirst = new Path.ChildAssocElement(updateAssocRef);
|
||||
pathToSave.prepend(newFirst);
|
||||
}
|
||||
@ -1622,8 +1619,7 @@ public class DbNodeServiceImpl extends AbstractNodeServiceImpl
|
||||
|
||||
if (parentAssocs.size() == 0 && !isRoot)
|
||||
{
|
||||
throw new RuntimeException("Node without parents does not have root aspect: " +
|
||||
currentNodeRef);
|
||||
throw new RuntimeException("Node without parents does not have root aspect: " + currentNodeRef);
|
||||
}
|
||||
// walk up each parent association
|
||||
for (ChildAssoc assoc : parentAssocs)
|
||||
@ -1632,12 +1628,8 @@ public class DbNodeServiceImpl extends AbstractNodeServiceImpl
|
||||
if (assocStack.contains(assoc))
|
||||
{
|
||||
// the association was present already
|
||||
throw new CyclicChildRelationshipException(
|
||||
"Cyclic parent-child relationship detected: \n" +
|
||||
" current node: " + currentNode + "\n" +
|
||||
" current path: " + currentPath + "\n" +
|
||||
" next assoc: " + assoc,
|
||||
assoc);
|
||||
throw new CyclicChildRelationshipException("Cyclic parent-child relationship detected: \n"
|
||||
+ " current node: " + currentNode + "\n" + " current path: " + currentPath + "\n" + " next assoc: " + assoc, assoc);
|
||||
}
|
||||
// do we consider only primary assocs?
|
||||
if (primaryOnly && !assoc.getIsPrimary())
|
||||
@ -1650,13 +1642,7 @@ public class DbNodeServiceImpl extends AbstractNodeServiceImpl
|
||||
NodeRef childRef = tenantService.getBaseName(assoc.getChild().getNodeRef());
|
||||
boolean isPrimary = assoc.getIsPrimary();
|
||||
// build a real association reference
|
||||
ChildAssociationRef assocRef = new ChildAssociationRef(
|
||||
assoc.getTypeQName().getQName(),
|
||||
parentRef,
|
||||
qname,
|
||||
childRef,
|
||||
isPrimary,
|
||||
-1);
|
||||
ChildAssociationRef assocRef = new ChildAssociationRef(assoc.getTypeQName().getQName(), parentRef, qname, childRef, isPrimary, -1);
|
||||
// Ordering is not important here: We are building distinct paths upwards
|
||||
Path.Element element = new Path.ChildAssocElement(assocRef);
|
||||
// create a new path that builds on the current path
|
||||
@ -1690,8 +1676,8 @@ public class DbNodeServiceImpl extends AbstractNodeServiceImpl
|
||||
}
|
||||
|
||||
/**
|
||||
* When searching for <code>primaryOnly == true</code>, checks that there is exactly
|
||||
* one path.
|
||||
* When searching for <code>primaryOnly == true</code>, checks that there is exactly one path.
|
||||
*
|
||||
* @see #prependPaths(Node, Path, Collection, Stack, boolean)
|
||||
*/
|
||||
public List<Path> getPaths(NodeRef nodeRef, boolean primaryOnly) throws InvalidNodeRefException
|
||||
@ -1752,44 +1738,31 @@ public class DbNodeServiceImpl extends AbstractNodeServiceImpl
|
||||
Set<Long> aspects = node.getAspects();
|
||||
aspects.add(aspectQNameEntityArchived.getId());
|
||||
Map<Long, PropertyValue> properties = node.getProperties();
|
||||
PropertyValue archivedByProperty = makePropertyValue(
|
||||
dictionaryService.getProperty(ContentModel.PROP_ARCHIVED_BY),
|
||||
AuthenticationUtil.getCurrentUserName());
|
||||
PropertyValue archivedByProperty = makePropertyValue(dictionaryService.getProperty(ContentModel.PROP_ARCHIVED_BY), AuthenticationUtil.getCurrentUserName());
|
||||
properties.put(propQNameArchivedBy.getId(), archivedByProperty);
|
||||
PropertyValue archivedDateProperty = makePropertyValue(
|
||||
dictionaryService.getProperty(ContentModel.PROP_ARCHIVED_DATE),
|
||||
new Date());
|
||||
PropertyValue archivedDateProperty = makePropertyValue(dictionaryService.getProperty(ContentModel.PROP_ARCHIVED_DATE), new Date());
|
||||
properties.put(propQNameArchivedDate.getId(), archivedDateProperty);
|
||||
PropertyValue archivedPrimaryParentNodeRefProperty = makePropertyValue(
|
||||
dictionaryService.getProperty(ContentModel.PROP_ARCHIVED_ORIGINAL_PARENT_ASSOC),
|
||||
primaryParentAssoc.getChildAssocRef());
|
||||
PropertyValue archivedPrimaryParentNodeRefProperty = makePropertyValue(dictionaryService.getProperty(ContentModel.PROP_ARCHIVED_ORIGINAL_PARENT_ASSOC), primaryParentAssoc
|
||||
.getChildAssocRef());
|
||||
properties.put(propQNameArchivedOriginalParentAssoc.getId(), archivedPrimaryParentNodeRefProperty);
|
||||
PropertyValue originalOwnerProperty = properties.get(propQNameEntityOwner.getId());
|
||||
PropertyValue originalCreatorProperty = properties.get(propQNameEntityCreator.getId());
|
||||
if (originalOwnerProperty != null || originalCreatorProperty != null)
|
||||
{
|
||||
QNameEntity propQNameArchivedOriginalOwner = qnameDAO.getOrCreateQNameEntity(ContentModel.PROP_ARCHIVED_ORIGINAL_OWNER);
|
||||
properties.put(
|
||||
propQNameArchivedOriginalOwner.getId(),
|
||||
originalOwnerProperty != null ? originalOwnerProperty : originalCreatorProperty);
|
||||
properties.put(propQNameArchivedOriginalOwner.getId(), originalOwnerProperty != null ? originalOwnerProperty : originalCreatorProperty);
|
||||
}
|
||||
|
||||
// change the node ownership
|
||||
QNameEntity ownableAspectQNameEntity = qnameDAO.getOrCreateQNameEntity(ContentModel.ASPECT_OWNABLE);
|
||||
aspects.add(ownableAspectQNameEntity.getId());
|
||||
PropertyValue newOwnerProperty = makePropertyValue(
|
||||
dictionaryService.getProperty(ContentModel.PROP_ARCHIVED_ORIGINAL_OWNER),
|
||||
AuthenticationUtil.getCurrentUserName());
|
||||
PropertyValue newOwnerProperty = makePropertyValue(dictionaryService.getProperty(ContentModel.PROP_ARCHIVED_ORIGINAL_OWNER), AuthenticationUtil.getCurrentUserName());
|
||||
QNameEntity propQNameOwner = qnameDAO.getOrCreateQNameEntity(ContentModel.PROP_OWNER);
|
||||
properties.put(propQNameOwner.getId(), newOwnerProperty);
|
||||
|
||||
// move the node
|
||||
NodeRef archiveStoreRootNodeRef = getRootNode(archiveStoreRef);
|
||||
moveNode(
|
||||
nodeRef,
|
||||
archiveStoreRootNodeRef,
|
||||
ContentModel.ASSOC_CHILDREN,
|
||||
QName.createQName(NamespaceService.SYSTEM_MODEL_1_0_URI, "archivedItem"));
|
||||
moveNode(nodeRef, archiveStoreRootNodeRef, ContentModel.ASSOC_CHILDREN, QName.createQName(NamespaceService.SYSTEM_MODEL_1_0_URI, "archivedItem"));
|
||||
|
||||
// the node reference has changed due to the store move
|
||||
nodeRef = node.getNodeRef();
|
||||
@ -1812,12 +1785,13 @@ public class DbNodeServiceImpl extends AbstractNodeServiceImpl
|
||||
}
|
||||
|
||||
/**
|
||||
* Performs all the necessary housekeeping involved in changing a node's store.
|
||||
* This method cascades down through all the primary children of the node as
|
||||
* well.
|
||||
* Performs all the necessary housekeeping involved in changing a node's store. This method cascades down through
|
||||
* all the primary children of the node as well.
|
||||
*
|
||||
* @param node the node whose store is changing
|
||||
* @param store the new store for the node
|
||||
* @param node
|
||||
* the node whose store is changing
|
||||
* @param store
|
||||
* the new store for the node
|
||||
*/
|
||||
private void moveNodeToStore(Node node, Store store)
|
||||
{
|
||||
@ -1867,12 +1841,13 @@ public class DbNodeServiceImpl extends AbstractNodeServiceImpl
|
||||
}
|
||||
|
||||
/**
|
||||
* Fill the map of all primary children below the given node.
|
||||
* The given node will be added to the map and the method is recursive
|
||||
* to all primary children.
|
||||
* Fill the map of all primary children below the given node. The given node will be added to the map and the method
|
||||
* is recursive to all primary children.
|
||||
*
|
||||
* @param nodeStatus the status of the node at the top of the hierarchy
|
||||
* @param nodeStatusesById a map of node statuses that will be reused as the return value
|
||||
* @param nodeStatus
|
||||
* the status of the node at the top of the hierarchy
|
||||
* @param nodeStatusesById
|
||||
* a map of node statuses that will be reused as the return value
|
||||
* @return Returns a map of nodes in the hierarchy keyed by their IDs
|
||||
*/
|
||||
private Map<Long, NodeStatus> getNodeHierarchy(NodeStatus nodeStatus, Map<Long, NodeStatus> nodeStatusesById)
|
||||
@ -1910,13 +1885,15 @@ public class DbNodeServiceImpl extends AbstractNodeServiceImpl
|
||||
}
|
||||
|
||||
/**
|
||||
* Archive all associations to and from the given node, with the
|
||||
* exception of associations to or from nodes in the given map.
|
||||
* Archive all associations to and from the given node, with the exception of associations to or from nodes in the
|
||||
* given map.
|
||||
* <p>
|
||||
* Primary parent associations are also ignored.
|
||||
*
|
||||
* @param node the node whose associations must be archived
|
||||
* @param nodesById a map of nodes partaking in the archival process
|
||||
* @param node
|
||||
* the node whose associations must be archived
|
||||
* @param nodesById
|
||||
* a map of nodes partaking in the archival process
|
||||
*/
|
||||
private void archiveAssocs(Node node, Map<Long, NodeStatus> nodeStatusesById)
|
||||
{
|
||||
@ -2060,13 +2037,13 @@ public class DbNodeServiceImpl extends AbstractNodeServiceImpl
|
||||
{
|
||||
throw new AlfrescoRuntimeException("The node to archive is not an archive node");
|
||||
}
|
||||
ChildAssociationRef originalPrimaryParentAssocRef = (ChildAssociationRef) makeSerializableValue(
|
||||
dictionaryService.getProperty(ContentModel.PROP_ARCHIVED_ORIGINAL_PARENT_ASSOC),
|
||||
properties.get(propQNameEntityOrigParentAssoc.getId()));
|
||||
ChildAssociationRef originalPrimaryParentAssocRef = (ChildAssociationRef) makeSerializableValue(dictionaryService
|
||||
.getProperty(ContentModel.PROP_ARCHIVED_ORIGINAL_PARENT_ASSOC), properties.get(propQNameEntityOrigParentAssoc.getId()));
|
||||
PropertyValue originalOwnerProperty = properties.get(propQNameEntityOrigOwner.getId());
|
||||
|
||||
// remove the archived aspect
|
||||
removeAspect(archivedNodeRef, ContentModel.ASPECT_ARCHIVED); // allow policy to fire, e.g. for DictionaryModelType
|
||||
removeAspect(archivedNodeRef, ContentModel.ASPECT_ARCHIVED); // allow policy to fire, e.g. for
|
||||
// DictionaryModelType
|
||||
|
||||
properties.remove(propQNameEntityOrigParentAssoc.getId());
|
||||
properties.remove(propQNameEntityArchivedBy.getId());
|
||||
@ -2097,11 +2074,7 @@ public class DbNodeServiceImpl extends AbstractNodeServiceImpl
|
||||
}
|
||||
|
||||
// move the node to the target parent, which may or may not be the original parent
|
||||
ChildAssociationRef newChildAssocRef = moveNode(
|
||||
archivedNodeRef,
|
||||
destinationParentNodeRef,
|
||||
assocTypeQName,
|
||||
assocQName);
|
||||
ChildAssociationRef newChildAssocRef = moveNode(archivedNodeRef, destinationParentNodeRef, assocTypeQName, assocQName);
|
||||
archivedNodeRef = newChildAssocRef.getChildRef();
|
||||
archivedNodeStatus = nodeDaoService.getNodeStatus(archivedNodeRef, false);
|
||||
|
||||
@ -2120,10 +2093,8 @@ public class DbNodeServiceImpl extends AbstractNodeServiceImpl
|
||||
// done
|
||||
if (logger.isDebugEnabled())
|
||||
{
|
||||
logger.debug("Restored node: \n" +
|
||||
" original noderef: " + archivedNodeRef + "\n" +
|
||||
" restored noderef: " + restoredNodeRef + "\n" +
|
||||
" new parent: " + destinationParentNodeRef);
|
||||
logger.debug("Restored node: \n"
|
||||
+ " original noderef: " + archivedNodeRef + "\n" + " restored noderef: " + restoredNodeRef + "\n" + " new parent: " + destinationParentNodeRef);
|
||||
}
|
||||
return restoredNodeRef;
|
||||
}
|
||||
@ -2135,9 +2106,7 @@ public class DbNodeServiceImpl extends AbstractNodeServiceImpl
|
||||
Map<Long, PropertyValue> properties = node.getProperties();
|
||||
|
||||
// restore parent associations
|
||||
Collection<ChildAssociationRef> parentAssocRefs = (Collection<ChildAssociationRef>) getProperty(
|
||||
nodeRef,
|
||||
ContentModel.PROP_ARCHIVED_PARENT_ASSOCS);
|
||||
Collection<ChildAssociationRef> parentAssocRefs = (Collection<ChildAssociationRef>) getProperty(nodeRef, ContentModel.PROP_ARCHIVED_PARENT_ASSOCS);
|
||||
if (parentAssocRefs != null)
|
||||
{
|
||||
for (ChildAssociationRef assocRef : parentAssocRefs)
|
||||
@ -2150,12 +2119,7 @@ public class DbNodeServiceImpl extends AbstractNodeServiceImpl
|
||||
Node parentNode = getNodeNotNull(parentNodeRef);
|
||||
// get the name to use for the unique child check
|
||||
QName assocTypeQName = assocRef.getTypeQName();
|
||||
nodeDaoService.newChildAssoc(
|
||||
parentNode,
|
||||
node,
|
||||
assocRef.isPrimary(),
|
||||
assocTypeQName,
|
||||
assocRef.getQName());
|
||||
nodeDaoService.newChildAssoc(parentNode, node, assocRef.isPrimary(), assocTypeQName, assocRef.getQName());
|
||||
}
|
||||
properties.remove(propQNameEntityOrigParentAssoc.getId());
|
||||
}
|
||||
@ -2164,9 +2128,7 @@ public class DbNodeServiceImpl extends AbstractNodeServiceImpl
|
||||
setChildUniqueName(node);
|
||||
|
||||
// restore child associations
|
||||
Collection<ChildAssociationRef> childAssocRefs = (Collection<ChildAssociationRef>) getProperty(
|
||||
nodeRef,
|
||||
ContentModel.PROP_ARCHIVED_CHILD_ASSOCS);
|
||||
Collection<ChildAssociationRef> childAssocRefs = (Collection<ChildAssociationRef>) getProperty(nodeRef, ContentModel.PROP_ARCHIVED_CHILD_ASSOCS);
|
||||
if (childAssocRefs != null)
|
||||
{
|
||||
for (ChildAssociationRef assocRef : childAssocRefs)
|
||||
@ -2179,21 +2141,14 @@ public class DbNodeServiceImpl extends AbstractNodeServiceImpl
|
||||
Node childNode = getNodeNotNull(childNodeRef);
|
||||
QName assocTypeQName = assocRef.getTypeQName();
|
||||
// get the name to use for the unique child check
|
||||
nodeDaoService.newChildAssoc(
|
||||
node,
|
||||
childNode,
|
||||
assocRef.isPrimary(),
|
||||
assocTypeQName,
|
||||
assocRef.getQName());
|
||||
nodeDaoService.newChildAssoc(node, childNode, assocRef.isPrimary(), assocTypeQName, assocRef.getQName());
|
||||
// ensure that the name uniqueness is enforced for the child node
|
||||
setChildUniqueName(childNode);
|
||||
}
|
||||
properties.remove(ContentModel.PROP_ARCHIVED_CHILD_ASSOCS);
|
||||
}
|
||||
// restore source associations
|
||||
Collection<AssociationRef> sourceAssocRefs = (Collection<AssociationRef>) getProperty(
|
||||
nodeRef,
|
||||
ContentModel.PROP_ARCHIVED_SOURCE_ASSOCS);
|
||||
Collection<AssociationRef> sourceAssocRefs = (Collection<AssociationRef>) getProperty(nodeRef, ContentModel.PROP_ARCHIVED_SOURCE_ASSOCS);
|
||||
if (sourceAssocRefs != null)
|
||||
{
|
||||
for (AssociationRef assocRef : sourceAssocRefs)
|
||||
@ -2209,9 +2164,7 @@ public class DbNodeServiceImpl extends AbstractNodeServiceImpl
|
||||
properties.remove(ContentModel.PROP_ARCHIVED_SOURCE_ASSOCS);
|
||||
}
|
||||
// restore target associations
|
||||
Collection<AssociationRef> targetAssocRefs = (Collection<AssociationRef>) getProperty(
|
||||
nodeRef,
|
||||
ContentModel.PROP_ARCHIVED_TARGET_ASSOCS);
|
||||
Collection<AssociationRef> targetAssocRefs = (Collection<AssociationRef>) getProperty(nodeRef, ContentModel.PROP_ARCHIVED_TARGET_ASSOCS);
|
||||
if (targetAssocRefs != null)
|
||||
{
|
||||
for (AssociationRef assocRef : targetAssocRefs)
|
||||
@ -2233,8 +2186,10 @@ public class DbNodeServiceImpl extends AbstractNodeServiceImpl
|
||||
/**
|
||||
* Checks the dictionary's definition of the association to assign a unique name to the child node.
|
||||
*
|
||||
* @param assocTypeQName the type of the child association
|
||||
* @param childNode the child node being added. The name will be extracted from it, if necessary.
|
||||
* @param assocTypeQName
|
||||
* the type of the child association
|
||||
* @param childNode
|
||||
* the child node being added. The name will be extracted from it, if necessary.
|
||||
* @return Returns the value to be put on the child association for uniqueness, or null if
|
||||
*/
|
||||
private void setChildUniqueName(Node childNode)
|
||||
@ -2277,9 +2232,7 @@ public class DbNodeServiceImpl extends AbstractNodeServiceImpl
|
||||
// done
|
||||
if (logger.isDebugEnabled())
|
||||
{
|
||||
logger.debug(
|
||||
"Unique name set for all " + parentAssocs.size() + " parent associations: \n" +
|
||||
" name: " + useName);
|
||||
logger.debug("Unique name set for all " + parentAssocs.size() + " parent associations: \n" + " name: " + useName);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user