Fix for RM-2549. The copyAspect implementation needs to be very careful to use addProperties not setPropertiesand it also needs to not copy inherited properties.

git-svn-id: https://svn.alfresco.com/repos/alfresco-enterprise/modules/recordsmanagement/HEAD@110844 c4b6b30b-aa2e-2d43-bbcb-ca4b014f7261
This commit is contained in:
Neil McErlean
2015-08-25 16:12:45 +00:00
parent eee581c814
commit 7b87cf446e
2 changed files with 16 additions and 6 deletions

View File

@@ -23,6 +23,7 @@ import static org.alfresco.util.collections.CollectionUtils.filterKeys;
import org.alfresco.service.cmr.dictionary.AspectDefinition;
import org.alfresco.service.cmr.dictionary.DictionaryException;
import org.alfresco.service.cmr.dictionary.DictionaryService;
import org.alfresco.service.cmr.dictionary.PropertyDefinition;
import org.alfresco.service.cmr.repository.NodeRef;
import org.alfresco.service.cmr.repository.NodeService;
import org.alfresco.service.namespace.QName;
@@ -30,7 +31,6 @@ import org.alfresco.util.collections.Function;
import java.io.Serializable;
import java.util.Map;
import java.util.Set;
/**
* Provides additional methods of general use that could (in principle) be moved to the core services.
@@ -55,29 +55,31 @@ public class CoreServicesExtras
/**
* This method copies the property values for the specified aspect from one node to another.
* All associations are ignored.
* All associations are ignored. Inherited properties are not copied.
*
* @param from the node whose property values are to be read.
* @param to the node to which the property values are to be written.
* @return a Map of the property values which were copied.
*/
public Map<QName, Serializable> copyAspect(NodeRef from, NodeRef to, QName aspectQName)
public Map<QName, Serializable> copyAspect(final NodeRef from, final NodeRef to, final QName aspectQName)
{
final AspectDefinition aspectDefn = dictionaryService.getAspect(aspectQName);
if (aspectDefn == null) { throw new DictionaryException("Unknown aspect: " + aspectQName); }
final Set<QName> aspectProperties = aspectDefn.getProperties().keySet();
final Map<QName, PropertyDefinition> aspectProperties = aspectDefn.getProperties();
final Map<QName, Serializable> nodeProperties = nodeService.getProperties(from);
final Map<QName, Serializable> relevantPropVals = filterKeys(nodeProperties, new Function<QName, Boolean>()
{
@Override public Boolean apply(QName value)
{
return aspectProperties.contains(value);
// Only copy property values that are defined on the provided aspect.
final PropertyDefinition propDef = aspectProperties.get(value);
return propDef != null && propDef.getContainerClass().getName().equals(aspectQName);
}
});
nodeService.setProperties(to, relevantPropVals);
nodeService.addProperties(to, relevantPropVals);
return relevantPropVals;
}
}

View File

@@ -27,6 +27,8 @@ import static org.mockito.Mockito.mock;
import static org.alfresco.module.org_alfresco_module_rm.test.util.ExceptionUtils.expectedException;
import static org.junit.Assert.assertEquals;
import static java.util.Arrays.asList;
import org.alfresco.service.cmr.dictionary.AspectDefinition;
import org.alfresco.service.cmr.dictionary.DictionaryException;
import org.alfresco.service.cmr.dictionary.DictionaryService;
@@ -97,9 +99,15 @@ public class CoreServicesExtrasUnitTest
final NodeService mockNS = mock(NodeService.class);
final AspectDefinition mockAspect = mock(AspectDefinition.class);
when(mockAspect.getName()).thenReturn(testAspect);
final Map<QName, PropertyDefinition> props = new HashMap<>();
final PropertyDefinition mockProp1 = mock(PropertyDefinition.class);
final PropertyDefinition mockProp2 = mock(PropertyDefinition.class);
for (PropertyDefinition p : asList(mockProp1, mockProp2))
{
when(p.getContainerClass()).thenReturn(mockAspect);
}
props.put(testProp1, mockProp1);
props.put(testProp2, mockProp2);
when(mockAspect.getProperties()).thenReturn(props);