diff --git a/source/java/org/alfresco/rest/api/impl/NodesImpl.java b/source/java/org/alfresco/rest/api/impl/NodesImpl.java index 9b92d51d3e..00086d1a5a 100644 --- a/source/java/org/alfresco/rest/api/impl/NodesImpl.java +++ b/source/java/org/alfresco/rest/api/impl/NodesImpl.java @@ -884,7 +884,6 @@ public class NodesImpl implements Nodes public Node updateNode(String nodeId, Node nodeInfo, Parameters parameters) { - final NodeRef nodeRef = validateNode(nodeId); final Set fileOrFolder = new HashSet<>(Arrays.asList(ContentModel.TYPE_FOLDER, ContentModel.TYPE_CONTENT)); @@ -911,6 +910,61 @@ public class NodesImpl implements Nodes props.put(ContentModel.PROP_NAME, name); } + List aspectNames = nodeInfo.getAspectNames(); + if (aspectNames != null) + { + // note: can be empty (eg. to remove existing aspects (+ aspect properties) ... apart from cm:auditable, sys:referencable, sys:localized) + Set aspectQNames = new HashSet<>(aspectNames.size()); + for (String aspectName : aspectNames) + { + QName aspectQName = QName.createQName(aspectName, namespaceService); + aspectQNames.add(aspectQName); + } + + Set existingAspects = nodeService.getAspects(nodeRef); + + Set aspectsToAdd = new HashSet<>(3); + Set aspectsToRemove = new HashSet<>(3); + + for (QName aspectQName : aspectQNames) + { + if (EXCLUDED_ASPECTS.contains(aspectQName) || aspectQName.equals(ContentModel.ASPECT_AUDITABLE)) + { + continue; // ignore + } + + if (! existingAspects.contains(aspectQName)) + { + aspectsToAdd.add(aspectQName); + } + } + + for (QName existingAspect : existingAspects) + { + if (EXCLUDED_ASPECTS.contains(existingAspect) || existingAspect.equals(ContentModel.ASPECT_AUDITABLE)) + { + continue; // ignore + } + + if (! aspectQNames.contains(existingAspect)) + { + aspectsToRemove.add(existingAspect); + } + } + + // Note: for now, if aspectNames are sent then all that are required should be sent (to avoid properties from other existing aspects being removed) + // TODO: optional PATCH mechanism to add one new new aspect (with some related aspect properties) without affecting existing aspects/properties + for (QName aQName : aspectsToRemove) + { + nodeService.removeAspect(nodeRef, aQName); + } + + for (QName aQName : aspectsToAdd) + { + nodeService.addAspect(nodeRef, aQName, null); + } + } + if (props.size() > 0) { nodeService.addProperties(nodeRef, props); diff --git a/source/java/org/alfresco/rest/api/model/Node.java b/source/java/org/alfresco/rest/api/model/Node.java index bd3a74be81..265755805a 100644 --- a/source/java/org/alfresco/rest/api/model/Node.java +++ b/source/java/org/alfresco/rest/api/model/Node.java @@ -114,7 +114,7 @@ public class Node implements Comparable public static UserInfo lookupUserInfo(String userName, Map mapUserInfo, PersonService personService) { UserInfo userInfo = mapUserInfo.get(userName); - if (userInfo == null) + if ((userInfo == null) && (userName != null)) { String sysUserName = AuthenticationUtil.getSystemUserName(); if (userName.equals(sysUserName) || (AuthenticationUtil.isMtEnabled() && userName.startsWith(sysUserName + "@")))