use of org.alfresco.repo.transfer.manifest.ManifestAccessControl in project alfresco-repository by Alfresco.
the class RepoPrimaryManifestProcessorImpl method update.
/**
* @param node TransferManifestNormalNode
* @param resolvedNodes ResolvedParentChildPair
* @param primaryParentAssoc ChildAssociationRef
*/
private void update(TransferManifestNormalNode node, ResolvedParentChildPair resolvedNodes, ChildAssociationRef primaryParentAssoc) {
NodeRef nodeToUpdate = resolvedNodes.resolvedChild;
/**
* Check that if the destination is "from" the transferring repo if it is "from" another repo then ignore
*/
if (nodeService.hasAspect(nodeToUpdate, TransferModel.ASPECT_TRANSFERRED)) {
String fromRepository = (String) nodeService.getProperty(nodeToUpdate, TransferModel.PROP_FROM_REPOSITORY_ID);
String transferringRepo = header.getRepositoryId();
if (fromRepository != null && transferringRepo != null) {
if (!fromRepository.equalsIgnoreCase(transferringRepo)) {
logComment("Not updating local node (not from the transferring repository): " + node.getNodeRef());
return;
}
}
} else {
logComment("Not updating local node - node is local to this repository): " + node.getNodeRef());
// Not a transferred node.
return;
}
QName parentAssocType = primaryParentAssoc.getTypeQName();
QName parentAssocName = primaryParentAssoc.getQName();
NodeRef parentNodeRef = resolvedNodes.resolvedParent;
if (parentNodeRef == null) {
// We can't find the node's parent.
// We'll store the node in a temporary location and record it for
// later processing
ChildAssociationRef tempLocation = getTemporaryLocation(node.getNodeRef());
parentNodeRef = tempLocation.getParentRef();
parentAssocType = tempLocation.getTypeQName();
parentAssocName = tempLocation.getQName();
storeOrphanNode(primaryParentAssoc);
}
// First of all, do we need to move the node? If any aspect of the
// primary parent association has changed
// then the answer is "yes"
ChildAssociationRef currentParent = nodeService.getPrimaryParent(nodeToUpdate);
if (!currentParent.getParentRef().equals(parentNodeRef) || !currentParent.getTypeQName().equals(parentAssocType) || !currentParent.getQName().equals(parentAssocName)) {
/**
* Yes, the parent assoc has changed so we need to move the node
*/
if (nodeService.hasAspect(currentParent.getParentRef(), TransferModel.ASPECT_ALIEN)) {
// old parent node ref may be alien so treat as a delete
alienProcessor.beforeDeleteAlien(currentParent.getChildRef(), null);
}
// Yes, we need to move the node
ChildAssociationRef newNode = nodeService.moveNode(nodeToUpdate, parentNodeRef, parentAssocType, parentAssocName);
logMoved(node.getNodeRef(), nodeToUpdate, node.getParentPath().toString(), newNode.getParentRef(), nodeService.getPath(newNode.getChildRef()).toString());
logSummaryMoved(node.getNodeRef(), nodeToUpdate, node.getParentPath().toString(), newNode.getParentRef(), nodeService.getPath(newNode.getChildRef()).toString());
/**
* are we adding an alien node here? The transfer service has policies disabled
* so have to call the consequence of the policy directly.
*/
if (nodeService.hasAspect(newNode.getChildRef(), TransferModel.ASPECT_ALIEN)) {
alienProcessor.afterMoveAlien(newNode);
} else {
/**
* are we adding an alien node here? The transfer service has policies disabled
* so have to call the consequence of the policy directly.
*/
if (nodeService.hasAspect(parentNodeRef, TransferModel.ASPECT_TRANSFERRED) || nodeService.hasAspect(parentNodeRef, TransferModel.ASPECT_ALIEN)) {
alienProcessor.onCreateChild(newNode, header.getRepositoryId(), true);
}
}
}
log.info("Resolved parent node to " + parentNodeRef);
if (updateNeeded(node, nodeToUpdate)) {
logUpdated(node.getNodeRef(), nodeToUpdate, nodeService.getPath(nodeToUpdate).toString());
// We need to process content properties separately.
// First, create a shallow copy of the supplied property map...
Map<QName, Serializable> props = new HashMap<QName, Serializable>(node.getProperties());
Map<QName, Serializable> existingProps = nodeService.getProperties(nodeToUpdate);
processCategories(props, node.getManifestCategories());
// inject transferred properties/aspect here
injectTransferred(props);
// Remove the invadedBy property since that is used by the transfer service
// and is local to this repository.
props.remove(TransferModel.PROP_INVADED_BY);
// Do we need to worry about locking this updated ?
if (header.isReadOnly()) {
props.put(ContentModel.PROP_LOCK_OWNER, AuthenticationUtil.getAdminUserName());
props.put(ContentModel.PROP_LOCK_TYPE, LockType.NODE_LOCK.toString());
props.put(ContentModel.PROP_EXPIRY_DATE, null);
log.debug("updated node needs to be locked");
}
// Split out the content properties and sanitise the others
Map<QName, Serializable> contentProps = processProperties(nodeToUpdate, props, existingProps);
// If there was already a value for invadedBy then leave it alone rather than replacing it.
if (existingProps.containsKey(TransferModel.PROP_INVADED_BY)) {
props.put(TransferModel.PROP_INVADED_BY, existingProps.get(TransferModel.PROP_INVADED_BY));
}
// Update the non-content properties
nodeService.setProperties(nodeToUpdate, props);
// Deal with the content properties
boolean contentUpdated = writeContent(nodeToUpdate, contentProps);
if (contentUpdated) {
logSummaryUpdated(node.getNodeRef(), nodeToUpdate, nodeService.getPath(nodeToUpdate).toString());
}
// Change the type of the content
if (!nodeService.getType(nodeToUpdate).equals(node.getType())) {
// The type has changed, check the dictionary to contain the model for that type
TypeDefinition newTypeDef = dictionaryService.getType(node.getType());
if (newTypeDef == null) {
log.warn("Failed to update the type: " + node.getType() + " for node: " + nodeToUpdate + ", as there is no type definition for it");
} else {
// Check the default properties
Map<QName, PropertyDefinition> typeProperties = newTypeDef.getProperties();
// Search if all the properties are in place
boolean fail = false;
for (QName key : typeProperties.keySet()) {
PropertyDefinition propDef = typeProperties.get(key);
if (!props.containsKey(key) && propDef.isMandatory()) {
log.warn("Failed to update the type: " + node.getType() + " for node: " + nodeToUpdate + ", as the mandatory property '" + propDef.getName() + "' was not transferred.");
fail = true;
break;
}
}
if (!fail) {
// Set the new type
nodeService.setType(nodeToUpdate, node.getType());
}
}
}
// Blend the aspects together
Set<QName> suppliedAspects = new HashSet<QName>(node.getAspects());
Set<QName> existingAspects = nodeService.getAspects(nodeToUpdate);
Set<QName> aspectsToRemove = new HashSet<QName>(existingAspects);
// Add mandatory aspects to the supplied aspects (eg. should not explicitly remove auditable aspect from a folder - see also DMDeploymentTarget for similar)
List<AspectDefinition> aspectDefs = dictionaryService.getType(nodeService.getType(nodeToUpdate)).getDefaultAspects(true);
for (AspectDefinition aspectDef : aspectDefs) {
suppliedAspects.add(aspectDef.getName());
}
if (header.isReadOnly()) {
suppliedAspects.add(ContentModel.ASPECT_LOCKABLE);
}
aspectsToRemove.removeAll(suppliedAspects);
/**
* Don't remove the aspects that the transfer service uses itself.
*/
aspectsToRemove.remove(TransferModel.ASPECT_TRANSFERRED);
aspectsToRemove.remove(TransferModel.ASPECT_ALIEN);
suppliedAspects.removeAll(existingAspects);
// and suppliedAspects contains the set of aspects to add
for (QName aspect : suppliedAspects) {
nodeService.addAspect(nodeToUpdate, aspect, null);
}
for (QName aspect : aspectsToRemove) {
nodeService.removeAspect(nodeToUpdate, aspect);
}
// Check the ACL of this updated node
ManifestAccessControl acl = node.getAccessControl();
if (acl != null) {
boolean existInherit = permissionService.getInheritParentPermissions(nodeToUpdate);
if (existInherit != acl.isInherited()) {
log.debug("changed inherit permissions flag");
permissionService.setInheritParentPermissions(nodeToUpdate, acl.isInherited());
}
Set<AccessPermission> existingPermissions = permissionService.getAllSetPermissions(nodeToUpdate);
List<ManifestPermission> newPermissions = acl.getPermissions();
if (existingPermissions.size() > 0 || newPermissions != null) {
// Yes we have explicit permissions on this node.
log.debug("have to check permissions");
Set<ManifestPermission> work = new HashSet<ManifestPermission>();
for (AccessPermission permission : existingPermissions) {
if (permission.isSetDirectly()) {
ManifestPermission p = new ManifestPermission();
p.setAuthority(permission.getAuthority());
p.setPermission(permission.getPermission());
p.setStatus(permission.getAccessStatus().toString());
work.add(p);
}
}
// Do we need to check whether to add any permissions ?
if (newPermissions != null) {
// Do we need to add any permissions ?
for (ManifestPermission permission : acl.getPermissions()) {
if (!work.contains(permission)) {
log.debug("setting permission on node:" + permission);
AccessStatus status = AccessStatus.valueOf(permission.getStatus());
permissionService.setPermission(nodeToUpdate, permission.getAuthority(), permission.getPermission(), status == AccessStatus.ALLOWED);
}
}
// Remove permissions from "work" that should be there
work.removeAll(newPermissions);
}
// Do we need to remove any permissions
for (ManifestPermission permission : work) {
log.debug("removing permission on node:" + permission);
permissionService.deletePermission(nodeToUpdate, permission.getAuthority(), permission.getPermission());
}
}
}
}
}
use of org.alfresco.repo.transfer.manifest.ManifestAccessControl in project alfresco-repository by Alfresco.
the class RepoPrimaryManifestProcessorImpl method create.
/**
* Create new node.
*
* @param node TransferManifestNormalNode
* @param resolvedNodes ResolvedParentChildPair
* @param primaryParentAssoc ChildAssociationRef
*/
private void create(TransferManifestNormalNode node, ResolvedParentChildPair resolvedNodes, ChildAssociationRef primaryParentAssoc) {
log.info("Creating new node with noderef " + node.getNodeRef());
QName parentAssocType = primaryParentAssoc.getTypeQName();
QName parentAssocName = primaryParentAssoc.getQName();
NodeRef parentNodeRef = resolvedNodes.resolvedParent;
if (parentNodeRef == null) {
if (log.isDebugEnabled()) {
log.debug("Unable to resolve parent for inbound noderef " + node.getNodeRef() + ".\n Supplied parent noderef is " + primaryParentAssoc.getParentRef() + ".\n Supplied parent path is " + node.getParentPath().toString());
}
// We can't find the node's parent.
// We'll store the node in a temporary location and record it for
// later processing
ChildAssociationRef tempLocation = getTemporaryLocation(node.getNodeRef());
parentNodeRef = tempLocation.getParentRef();
parentAssocType = tempLocation.getTypeQName();
parentAssocName = tempLocation.getQName();
log.info("Recording orphaned transfer node: " + node.getNodeRef());
logComment("Unable to resolve parent for new incoming node. Storing it in temp folder: " + node.getNodeRef());
storeOrphanNode(primaryParentAssoc);
}
// We now know that this is a new node, and we have found the
// appropriate parent node in the
// local repository.
log.info("Resolved parent node to " + parentNodeRef);
// We need to process content properties separately.
// First, create a shallow copy of the supplied property map...
Map<QName, Serializable> props = new HashMap<QName, Serializable>(node.getProperties());
processCategories(props, node.getManifestCategories());
injectTransferred(props);
// Split out the content properties and sanitise the others
Map<QName, Serializable> contentProps = processProperties(null, props, null);
// Remove the invadedBy property since that is used by the transfer service
// and is local to this repository.
props.remove(TransferModel.PROP_INVADED_BY);
// Do we need to worry about locking this new node ?
if (header.isReadOnly()) {
log.debug("new node needs to be locked");
props.put(ContentModel.PROP_LOCK_OWNER, AuthenticationUtil.getAdminUserName());
props.put(ContentModel.PROP_LOCK_TYPE, LockType.NODE_LOCK.toString());
props.put(ContentModel.PROP_EXPIRY_DATE, null);
}
// Create the corresponding node...
ChildAssociationRef newNode = nodeService.createNode(parentNodeRef, parentAssocType, parentAssocName, node.getType(), props);
if (log.isDebugEnabled()) {
log.debug("Created new node (" + newNode.getChildRef() + ") parented by node " + newNode.getParentRef());
}
logCreated(node.getNodeRef(), newNode.getChildRef(), newNode.getParentRef(), nodeService.getPath(newNode.getChildRef()).toString(), false);
logSummaryCreated(node.getNodeRef(), newNode.getChildRef(), newNode.getParentRef(), nodeService.getPath(newNode.getChildRef()).toString(), false);
// Deal with the content properties
writeContent(newNode.getChildRef(), contentProps);
// Apply any aspects that are needed but haven't automatically been
// applied
Set<QName> aspects = new HashSet<QName>(node.getAspects());
aspects.removeAll(nodeService.getAspects(newNode.getChildRef()));
for (QName aspect : aspects) {
nodeService.addAspect(newNode.getChildRef(), aspect, null);
}
ManifestAccessControl acl = node.getAccessControl();
// Apply new ACL to this node
if (acl != null) {
permissionService.setInheritParentPermissions(newNode.getChildRef(), acl.isInherited());
if (acl.getPermissions() != null) {
for (ManifestPermission permission : acl.getPermissions()) {
log.debug("setting permission on node");
AccessStatus status = AccessStatus.valueOf(permission.getStatus());
// The node has its own access control list
permissionService.setPermission(newNode.getChildRef(), permission.getAuthority(), permission.getPermission(), status == AccessStatus.ALLOWED);
}
}
}
/**
* are we adding an alien node here? The transfer service has policies disabled
* so have to call the consequence of the policy directly.
*/
if (nodeService.hasAspect(parentNodeRef, TransferModel.ASPECT_TRANSFERRED) || nodeService.hasAspect(parentNodeRef, TransferModel.ASPECT_ALIEN)) {
alienProcessor.onCreateChild(newNode, header.getRepositoryId(), true);
}
// Is the node that we've just added the parent of any orphans that
// we've found earlier?
checkOrphans(newNode.getChildRef());
}
Aggregations