diff --git a/rm-server/source/java/org/alfresco/module/org_alfresco_module_rm/classification/interceptor/processor/CollectionPostMethodInvocationProcessor.java b/rm-server/source/java/org/alfresco/module/org_alfresco_module_rm/classification/interceptor/processor/CollectionPostMethodInvocationProcessor.java index 8548035977..af099d9994 100644 --- a/rm-server/source/java/org/alfresco/module/org_alfresco_module_rm/classification/interceptor/processor/CollectionPostMethodInvocationProcessor.java +++ b/rm-server/source/java/org/alfresco/module/org_alfresco_module_rm/classification/interceptor/processor/CollectionPostMethodInvocationProcessor.java @@ -24,7 +24,7 @@ import java.util.Iterator; import org.springframework.stereotype.Component; /** - * Collection Post Method Invocation Processor + * Collection Post Method Invocation Processor. * * @author Tuna Aksoy * @since 3.0 @@ -44,40 +44,81 @@ public class CollectionPostMethodInvocationProcessor extends BasePostMethodInvoc /** * @see org.alfresco.module.org_alfresco_module_rm.classification.interceptor.processor.BasePostMethodInvocationProcessor#process(java.lang.Object) */ - @SuppressWarnings("rawtypes") + @SuppressWarnings({ "rawtypes", "unchecked" }) @Override public T process(T object) { - T result = object; + Collection collection = ((Collection) object); - if (result != null) + if (collection != null) { - Collection collection = ((Collection) result); - if (!collection.isEmpty()) + BasePostMethodInvocationProcessor processor = pickProcessor(collection); + if (processor != null) { - Iterator iterator = collection.iterator(); - while (iterator.hasNext()) - { - Object next = iterator.next(); - // TODO: Can we guarantee that all the elements of a collection can be processed by the same processor? - BasePostMethodInvocationProcessor processor = getPostMethodInvocationProcessor().getProcessor(next); - if (processor != null) - { - Object processed = processor.process(next); - if (processed == null) - { - iterator.remove(); - } - else if (!processed.equals(next)) - { - // TODO Support this, as it will be hit by e.g. collections of collections. - throw new IllegalStateException("Modifying members of a collection is not yet supported."); - } - } - } + object = (T) processCollection(collection, processor); } } - return result; + return object; + } + + /** + * Process a collection using the supplied processor. + * + * @param collection The collection to be processed. + * @param processor A collection suitable for access by someone with the current security clearance. + */ + protected Collection processCollection(Collection collection, BasePostMethodInvocationProcessor processor) + { + Iterator iterator = collection.iterator(); + while (iterator.hasNext()) + { + Object next = iterator.next(); + Object processed = processor.process(next); + try + { + if (processed == null) + { + iterator.remove(); + } + else if (!processed.equals(next)) + { + // Modifying members of this type of collection is not supported, so filter the whole collection. + return null; + } + } + catch (UnsupportedOperationException e) + { + // If the collection cannot be modified and it contains classified data then the whole thing must be filtered. + return null; + } + } + return collection; + } + + /** + * Pick a suitable processor for the members of the collection. We assume that all the elements of a collection can + * be processed by the same processor. + * + * @param collection The collection to be processed. + * @return The chosen processor, or {@code null} if no suitable processor could be found. + */ + @SuppressWarnings("rawtypes") + private BasePostMethodInvocationProcessor pickProcessor(Collection collection) + { + Iterator iterator = collection.iterator(); + while (iterator.hasNext()) + { + Object next = iterator.next(); + if (next != null) + { + BasePostMethodInvocationProcessor processor = getPostMethodInvocationProcessor().getProcessor(next); + if (processor != null) + { + return processor; + } + } + } + return null; } } diff --git a/rm-server/source/java/org/alfresco/module/org_alfresco_module_rm/classification/interceptor/processor/ListPostMethodInvocationProcessor.java b/rm-server/source/java/org/alfresco/module/org_alfresco_module_rm/classification/interceptor/processor/ListPostMethodInvocationProcessor.java new file mode 100644 index 0000000000..65124b6a8e --- /dev/null +++ b/rm-server/source/java/org/alfresco/module/org_alfresco_module_rm/classification/interceptor/processor/ListPostMethodInvocationProcessor.java @@ -0,0 +1,47 @@ +/* + * Copyright (C) 2005-2015 Alfresco Software Limited. + * + * This file is part of Alfresco + * + * Alfresco is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * Alfresco is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with Alfresco. If not, see . + */ +package org.alfresco.module.org_alfresco_module_rm.classification.interceptor.processor; + +import java.util.ArrayList; +import java.util.Collection; +import java.util.List; + +/** + * List Post Method Invocation Processor. This replaces the existing list with a filtered {@link ArrayList}. By doing + * this we gain the ability to replace members of a list, which is not possible using the + * {@link CollectionPostMethodInvocationProcessor}. The downside is that whatever type of list was provided gets + * replaced with an {@code ArrayList}. + * + * @author Tom Page + * @since 3.0 + */ +public class ListPostMethodInvocationProcessor extends ModifiableCollectionPostMethodInvocationProcessor +{ + @Override + protected Class getClassName() + { + return List.class; + } + + @Override + protected Collection createEmptyCollection(Collection collection) + { + return new ArrayList<>(); + } +} diff --git a/rm-server/source/java/org/alfresco/module/org_alfresco_module_rm/classification/interceptor/processor/ModifiableCollectionPostMethodInvocationProcessor.java b/rm-server/source/java/org/alfresco/module/org_alfresco_module_rm/classification/interceptor/processor/ModifiableCollectionPostMethodInvocationProcessor.java new file mode 100644 index 0000000000..95bd18d07a --- /dev/null +++ b/rm-server/source/java/org/alfresco/module/org_alfresco_module_rm/classification/interceptor/processor/ModifiableCollectionPostMethodInvocationProcessor.java @@ -0,0 +1,61 @@ +/* + * Copyright (C) 2005-2015 Alfresco Software Limited. + * + * This file is part of Alfresco + * + * Alfresco is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * Alfresco is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with Alfresco. If not, see . + */ +package org.alfresco.module.org_alfresco_module_rm.classification.interceptor.processor; + +import java.util.ArrayList; +import java.util.Collection; + +/** + * List Post Method Invocation Processor. This replaces the existing list with a filtered {@link ArrayList}. By doing + * this we gain the ability to replace members of a list, which is not possible using the + * {@link CollectionPostMethodInvocationProcessor}. The downside is that whatever type of list was provided gets + * replaced with an {@code ArrayList}. + * + * @author Tom Page + * @since 3.0 + */ +public abstract class ModifiableCollectionPostMethodInvocationProcessor extends CollectionPostMethodInvocationProcessor +{ + @Override + abstract protected Class getClassName(); + + /** + * Create an empty modifiable collection. + * + * @param collection The source collection to try to mimic. + * @return The new empty collection. + */ + abstract protected Collection createEmptyCollection(Collection collection); + + /** {@inheritDoc} */ + @Override + protected Collection processCollection(Collection collection, BasePostMethodInvocationProcessor processor) + { + Collection returnList = createEmptyCollection(collection); + for (T member : collection) + { + T processed = processor.process(member); + if (processed != null) + { + returnList.add(processed); + } + } + return returnList; + } +} diff --git a/rm-server/source/java/org/alfresco/module/org_alfresco_module_rm/classification/interceptor/processor/SetPostMethodInvocationProcessor.java b/rm-server/source/java/org/alfresco/module/org_alfresco_module_rm/classification/interceptor/processor/SetPostMethodInvocationProcessor.java new file mode 100644 index 0000000000..ab16dd9130 --- /dev/null +++ b/rm-server/source/java/org/alfresco/module/org_alfresco_module_rm/classification/interceptor/processor/SetPostMethodInvocationProcessor.java @@ -0,0 +1,47 @@ +/* + * Copyright (C) 2005-2015 Alfresco Software Limited. + * + * This file is part of Alfresco + * + * Alfresco is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * Alfresco is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with Alfresco. If not, see . + */ +package org.alfresco.module.org_alfresco_module_rm.classification.interceptor.processor; + +import java.util.Collection; +import java.util.HashSet; +import java.util.Set; + +/** + * Set Post Method Invocation Processor. This replaces the existing set with a filtered {@link HashSet}. By doing + * this we gain the ability to replace members of a set, which is not possible using the + * {@link CollectionPostMethodInvocationProcessor}. The downside is that whatever type of set was provided gets + * replaced with an {@code HashSet}. + * + * @author Tom Page + * @since 3.0 + */ +public class SetPostMethodInvocationProcessor extends ModifiableCollectionPostMethodInvocationProcessor +{ + @Override + protected Class getClassName() + { + return Set.class; + } + + @Override + protected Collection createEmptyCollection(Collection collection) + { + return new HashSet<>(); + } +} diff --git a/rm-server/source/java/org/alfresco/module/org_alfresco_module_rm/classification/interceptor/processor/SortedSetPostMethodInvocationProcessor.java b/rm-server/source/java/org/alfresco/module/org_alfresco_module_rm/classification/interceptor/processor/SortedSetPostMethodInvocationProcessor.java new file mode 100644 index 0000000000..77030ff263 --- /dev/null +++ b/rm-server/source/java/org/alfresco/module/org_alfresco_module_rm/classification/interceptor/processor/SortedSetPostMethodInvocationProcessor.java @@ -0,0 +1,45 @@ +/* + * Copyright (C) 2005-2015 Alfresco Software Limited. + * + * This file is part of Alfresco + * + * Alfresco is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * Alfresco is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with Alfresco. If not, see . + */ +package org.alfresco.module.org_alfresco_module_rm.classification.interceptor.processor; + +import java.util.Collection; +import java.util.SortedSet; +import java.util.TreeSet; + +/** + * Sorted Set Post Method Invocation Processor. This replaces the existing set with a filtered {@link TreeSet}. + * + * @author Tom Page + * @since 3.0 + */ +public class SortedSetPostMethodInvocationProcessor extends ModifiableCollectionPostMethodInvocationProcessor +{ + @Override + protected Class getClassName() + { + return SortedSet.class; + } + + @Override + protected Collection createEmptyCollection(Collection collection) + { + SortedSet sortedSet = (SortedSet) collection; + return new TreeSet<>(sortedSet.comparator()); + } +} diff --git a/rm-server/unit-test/java/org/alfresco/module/org_alfresco_module_rm/classification/interceptor/processor/CollectionPostMethodInvocationProcessorUnitTest.java b/rm-server/unit-test/java/org/alfresco/module/org_alfresco_module_rm/classification/interceptor/processor/CollectionPostMethodInvocationProcessorUnitTest.java new file mode 100644 index 0000000000..09a682d9d5 --- /dev/null +++ b/rm-server/unit-test/java/org/alfresco/module/org_alfresco_module_rm/classification/interceptor/processor/CollectionPostMethodInvocationProcessorUnitTest.java @@ -0,0 +1,137 @@ +/* + * Copyright (C) 2005-2015 Alfresco Software Limited. + * + * This file is part of Alfresco + * + * Alfresco is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * Alfresco is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with Alfresco. If not, see . + */ +package org.alfresco.module.org_alfresco_module_rm.classification.interceptor.processor; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertNull; +import static org.junit.Assert.assertTrue; +import static org.mockito.Matchers.isA; +import static org.mockito.Mockito.when; +import static org.mockito.MockitoAnnotations.initMocks; + +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Collection; +import java.util.List; + +import org.junit.Before; +import org.junit.Test; +import org.mockito.InjectMocks; +import org.mockito.Mock; + +/** + * Unit tests for the {@link CollectionPostMethodInvocationProcessor}. + * + * @author Tom Page + * @since 3.0 + */ +public class CollectionPostMethodInvocationProcessorUnitTest +{ + private static final String NON_FILTERED = "NON_FILTERED"; + private static final String FILTERED = "FILTERED"; + private static final String CHANGED_INPUT = "CHANGED_INPUT"; + private static final String CHANGED_OUTPUT = "CHANGED_OUTPUT"; + + @InjectMocks CollectionPostMethodInvocationProcessor collectionPostMethodInvocationProcessor; + @Mock PostMethodInvocationProcessor mockPostMethodInvocationProcessor; + @Mock BasePostMethodInvocationProcessor mockStringProcessor; + + @Before + public void setUp() + { + initMocks(this); + + when(mockPostMethodInvocationProcessor.getProcessor(isA(String.class))).thenReturn(mockStringProcessor); + + when(mockStringProcessor.process(NON_FILTERED)).thenReturn(NON_FILTERED); + when(mockStringProcessor.process(FILTERED)).thenReturn(null); + when(mockStringProcessor.process(CHANGED_INPUT)).thenReturn(CHANGED_OUTPUT); + } + + @Test + public void testProcess_copesWithNull() + { + Object result = collectionPostMethodInvocationProcessor.process(null); + + assertNull("Expected null collection to be passed through.", result); + } + + @Test + public void testProcess_nullMember() + { + List collection = new ArrayList<>(); + collection.add(null); + + Object result = collectionPostMethodInvocationProcessor.process(collection); + + assertEquals("Expected collection containing null to be passed through.", collection, result); + } + + @Test + public void testProcess_nonFilteredMember() + { + Object collection = Arrays.asList(NON_FILTERED); + + Object result = collectionPostMethodInvocationProcessor.process(collection); + + assertEquals("Expected element to still be present in result.", collection, result); + } + + @Test + public void testProcess_filteredMemberInModifiableList() + { + List collection = new ArrayList<>(Arrays.asList(FILTERED)); + + Collection result = collectionPostMethodInvocationProcessor.process(collection); + + assertTrue("Expected an empty list.", result.isEmpty()); + } + + @Test + public void testProcess_filteredMemberInUnmodifiableList() + { + List collection = Arrays.asList(FILTERED, NON_FILTERED); + + Collection result = collectionPostMethodInvocationProcessor.process(collection); + + assertNull("Since the collection could not be modified the whole thing should be filtered.", result); + } + + @Test + public void testProcess_modifiedMember() + { + List collection = Arrays.asList(NON_FILTERED, CHANGED_INPUT); + + Collection result = collectionPostMethodInvocationProcessor.process(collection); + + assertNull("Since the Collection interface does not support replacement, the whole collection should be filtered.", + result); + } + + @Test + public void testProcess_noProcessorDefined() + { + List collection = Arrays.asList(1, 4, 91); + + Collection result = collectionPostMethodInvocationProcessor.process(collection); + + assertEquals("If no processor is defined for the members then the whole list should be returned.", collection, + result); + } +} diff --git a/rm-server/unit-test/java/org/alfresco/module/org_alfresco_module_rm/classification/interceptor/processor/ListPostMethodInvocationProcessorUnitTest.java b/rm-server/unit-test/java/org/alfresco/module/org_alfresco_module_rm/classification/interceptor/processor/ListPostMethodInvocationProcessorUnitTest.java new file mode 100644 index 0000000000..e7cc4db762 --- /dev/null +++ b/rm-server/unit-test/java/org/alfresco/module/org_alfresco_module_rm/classification/interceptor/processor/ListPostMethodInvocationProcessorUnitTest.java @@ -0,0 +1,112 @@ +/* + * Copyright (C) 2005-2015 Alfresco Software Limited. + * + * This file is part of Alfresco + * + * Alfresco is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * Alfresco is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with Alfresco. If not, see . + */ +package org.alfresco.module.org_alfresco_module_rm.classification.interceptor.processor; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertTrue; +import static org.mockito.Matchers.isA; +import static org.mockito.Mockito.when; +import static org.mockito.MockitoAnnotations.initMocks; + +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Collection; +import java.util.List; + +import org.junit.Before; +import org.junit.Test; +import org.mockito.InjectMocks; +import org.mockito.Mock; + +/** + * Unit tests for {@link ListPostMethodInvocationProcessor}. + * + * @author Tom Page + * @since 3.0 + */ +public class ListPostMethodInvocationProcessorUnitTest +{ + private static final String NON_FILTERED = "NON_FILTERED"; + private static final String FILTERED = "FILTERED"; + private static final String CHANGED_INPUT = "CHANGED_INPUT"; + private static final String CHANGED_OUTPUT = "CHANGED_OUTPUT"; + + @InjectMocks ListPostMethodInvocationProcessor listPostMethodInvocationProcessor; + @Mock PostMethodInvocationProcessor mockPostMethodInvocationProcessor; + @Mock BasePostMethodInvocationProcessor mockStringProcessor; + + @Before + public void setUp() + { + initMocks(this); + + when(mockPostMethodInvocationProcessor.getProcessor(isA(List.class))).thenReturn(listPostMethodInvocationProcessor); + when(mockPostMethodInvocationProcessor.getProcessor(isA(String.class))).thenReturn(mockStringProcessor); + + when(mockStringProcessor.process(NON_FILTERED)).thenReturn(NON_FILTERED); + when(mockStringProcessor.process(FILTERED)).thenReturn(null); + when(mockStringProcessor.process(CHANGED_INPUT)).thenReturn(CHANGED_OUTPUT); + } + + @Test + public void testProcessCollection_emptyList() + { + List collection = new ArrayList<>(); + + Collection result = listPostMethodInvocationProcessor.processCollection(collection, mockStringProcessor); + + assertEquals(collection, result); + } + + @Test + public void testProcessCollection_completelyFiltered() + { + List collection = Arrays.asList(FILTERED, FILTERED); + + Collection result = listPostMethodInvocationProcessor.processCollection(collection, mockStringProcessor); + + assertTrue("Expected all members of the list to be removed.", result.isEmpty()); + } + + @Test + public void testProcessCollection_supportsReplacement() + { + List collection = Arrays.asList(NON_FILTERED, CHANGED_INPUT); + + Collection result = listPostMethodInvocationProcessor.processCollection(collection, mockStringProcessor); + + List expected = Arrays.asList(NON_FILTERED, CHANGED_OUTPUT); + assertEquals(expected, result); + } + + @Test + public void testProcess_listOfLists() + { + List innerListA = Arrays.asList(FILTERED, NON_FILTERED, CHANGED_INPUT); + List innerListB = Arrays.asList(CHANGED_INPUT, FILTERED, NON_FILTERED); + List> collection = Arrays.asList(innerListA, innerListB); + + Collection> result = listPostMethodInvocationProcessor.process(collection); + + List expectedInnerListA = Arrays.asList(NON_FILTERED, CHANGED_OUTPUT); + List expectedInnerListB = Arrays.asList(CHANGED_OUTPUT, NON_FILTERED); + List> expected = Arrays.asList(expectedInnerListA, expectedInnerListB); + assertEquals(expected, result); + } +} diff --git a/rm-server/unit-test/java/org/alfresco/module/org_alfresco_module_rm/classification/interceptor/processor/NodeRefPostMethodInvocationProcessorUnitTest.java b/rm-server/unit-test/java/org/alfresco/module/org_alfresco_module_rm/classification/interceptor/processor/NodeRefPostMethodInvocationProcessorUnitTest.java index 1d4ae13864..c8ddc99bd7 100644 --- a/rm-server/unit-test/java/org/alfresco/module/org_alfresco_module_rm/classification/interceptor/processor/NodeRefPostMethodInvocationProcessorUnitTest.java +++ b/rm-server/unit-test/java/org/alfresco/module/org_alfresco_module_rm/classification/interceptor/processor/NodeRefPostMethodInvocationProcessorUnitTest.java @@ -18,15 +18,10 @@ */ package org.alfresco.module.org_alfresco_module_rm.classification.interceptor.processor; -import static com.google.common.collect.ImmutableList.copyOf; -import static com.google.common.collect.Lists.newArrayList; -import static java.util.Collections.unmodifiableCollection; import static org.junit.Assert.assertEquals; import static org.mockito.Mockito.when; import static org.springframework.extensions.webscripts.GUID.generate; -import java.util.ArrayList; - import org.alfresco.module.org_alfresco_module_rm.classification.ContentClassificationService; import org.alfresco.module.org_alfresco_module_rm.test.util.BaseUnitTest; import org.alfresco.service.cmr.repository.NodeRef; @@ -90,83 +85,9 @@ public class NodeRefPostMethodInvocationProcessorUnitTest extends BaseUnitTest } @Test - public void testCollection_bothNodesConent_userClearedForBoth() + public void testProcessingNull() { - NodeRef nodeRef1 = generateNodeRef(); - NodeRef nodeRef2 = generateNodeRef(); - ArrayList nodeRefs = newArrayList(nodeRef1, nodeRef2); - - when(mockedDictionaryService.isSubClass(mockedNodeService.getType(nodeRef1), TYPE_CONTENT)).thenReturn(true); - when(mockedContentClassificationService.hasClearance(nodeRef1)).thenReturn(true); - - when(mockedDictionaryService.isSubClass(mockedNodeService.getType(nodeRef2), TYPE_CONTENT)).thenReturn(true); - when(mockedContentClassificationService.hasClearance(nodeRef2)).thenReturn(true); - - assertEquals(nodeRefs, nodeRefPostMethodInvocationProcessor.process(nodeRefs)); - } - - @Test - public void testCollection_bothNodesContent_userClearedForOne() - { - NodeRef nodeRef1 = generateNodeRef(); - NodeRef nodeRef2 = generateNodeRef(); - ArrayList nodeRefs = newArrayList(nodeRef1, nodeRef2); - - when(mockedDictionaryService.isSubClass(mockedNodeService.getType(nodeRef1), TYPE_CONTENT)).thenReturn(true); - when(mockedContentClassificationService.hasClearance(nodeRef1)).thenReturn(true); - - when(mockedDictionaryService.isSubClass(mockedNodeService.getType(nodeRef2), TYPE_CONTENT)).thenReturn(true); - when(mockedContentClassificationService.hasClearance(nodeRef2)).thenReturn(false); - - assertEquals(newArrayList(nodeRef1), nodeRefPostMethodInvocationProcessor.process(nodeRefs)); - } - - @SuppressWarnings("rawtypes") - @Test - public void testCollection_bothNodesContent_userClearedForNone() - { - NodeRef nodeRef1 = generateNodeRef(); - NodeRef nodeRef2 = generateNodeRef(); - ArrayList nodeRefs = newArrayList(nodeRef1, nodeRef2); - - when(mockedDictionaryService.isSubClass(mockedNodeService.getType(nodeRef1), TYPE_CONTENT)).thenReturn(true); - when(mockedContentClassificationService.hasClearance(nodeRef1)).thenReturn(false); - - when(mockedDictionaryService.isSubClass(mockedNodeService.getType(nodeRef2), TYPE_CONTENT)).thenReturn(true); - when(mockedContentClassificationService.hasClearance(nodeRef2)).thenReturn(false); - - assertEquals(new ArrayList(), nodeRefPostMethodInvocationProcessor.process(unmodifiableCollection(nodeRefs))); - } - - @Test - public void testCollection_onlyOneNodeContent_userClearedForBoth() - { - NodeRef nodeRef1 = generateNodeRef(); - NodeRef nodeRef2 = generateNodeRef(); - ArrayList nodeRefs = newArrayList(nodeRef1, nodeRef2); - - when(mockedDictionaryService.isSubClass(mockedNodeService.getType(nodeRef1), TYPE_CONTENT)).thenReturn(false); - when(mockedContentClassificationService.hasClearance(nodeRef1)).thenReturn(true); - - when(mockedDictionaryService.isSubClass(mockedNodeService.getType(nodeRef2), TYPE_CONTENT)).thenReturn(true); - when(mockedContentClassificationService.hasClearance(nodeRef2)).thenReturn(true); - - assertEquals(nodeRefs, nodeRefPostMethodInvocationProcessor.process(copyOf(nodeRefs))); - } - - @Test - public void testCollection_bothNodesNotContent_userClearedForBoth() - { - NodeRef nodeRef1 = generateNodeRef(); - NodeRef nodeRef2 = generateNodeRef(); - ArrayList nodeRefs = newArrayList(nodeRef1, nodeRef2); - - when(mockedDictionaryService.isSubClass(mockedNodeService.getType(nodeRef1), TYPE_CONTENT)).thenReturn(false); - when(mockedContentClassificationService.hasClearance(nodeRef1)).thenReturn(true); - - when(mockedDictionaryService.isSubClass(mockedNodeService.getType(nodeRef2), TYPE_CONTENT)).thenReturn(false); - when(mockedContentClassificationService.hasClearance(nodeRef2)).thenReturn(true); - - assertEquals(nodeRefs, nodeRefPostMethodInvocationProcessor.process(copyOf(nodeRefs))); + assertEquals("Expected null to be passed through without error.", null, + nodeRefPostMethodInvocationProcessor.process((NodeRef) null)); } } diff --git a/rm-server/unit-test/java/org/alfresco/module/org_alfresco_module_rm/classification/interceptor/processor/SortedSetPostMethodInvocationProcessorUnitTest.java b/rm-server/unit-test/java/org/alfresco/module/org_alfresco_module_rm/classification/interceptor/processor/SortedSetPostMethodInvocationProcessorUnitTest.java new file mode 100644 index 0000000000..918140d06e --- /dev/null +++ b/rm-server/unit-test/java/org/alfresco/module/org_alfresco_module_rm/classification/interceptor/processor/SortedSetPostMethodInvocationProcessorUnitTest.java @@ -0,0 +1,94 @@ +/* + * Copyright (C) 2005-2015 Alfresco Software Limited. + * + * This file is part of Alfresco + * + * Alfresco is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * Alfresco is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with Alfresco. If not, see . + */ +package org.alfresco.module.org_alfresco_module_rm.classification.interceptor.processor; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertFalse; +import static org.mockito.Mockito.when; +import static org.mockito.MockitoAnnotations.initMocks; + +import java.util.Collection; +import java.util.Comparator; +import java.util.Iterator; +import java.util.SortedSet; +import java.util.TreeSet; + +import org.junit.Before; +import org.junit.Test; +import org.mockito.InjectMocks; +import org.mockito.Mock; + +/** + * Unit tests for {@link SortedSetPostMethodInvocationProcessor}. + * + * @author Tom Page + * @since 3.0 + */ +public class SortedSetPostMethodInvocationProcessorUnitTest +{ + private static final String NON_FILTERED = "NON_FILTERED"; + private static final String FILTERED = "FILTERED"; + private static final String SHORT_INPUT = "SHORT_INPUT"; + private static final String REALLY_LONG_OUTPUT_STRING = "REALLY_LONG_OUTPUT_STRING"; + + @InjectMocks SortedSetPostMethodInvocationProcessor sortedSetPostMethodInvocationProcessor; + @Mock BasePostMethodInvocationProcessor mockStringProcessor; + + @Before + public void setUp() + { + initMocks(this); + + when(mockStringProcessor.process(NON_FILTERED)).thenReturn(NON_FILTERED); + when(mockStringProcessor.process(FILTERED)).thenReturn(null); + when(mockStringProcessor.process(SHORT_INPUT)).thenReturn(REALLY_LONG_OUTPUT_STRING); + } + + /** + * Given I have a sorted set of input strings + * When I pass it to the SortedSet processor + * Then I expect items above my clearance to be filtered + * And I expect items below my clearance to be passed through + * And I expect items that get changed by the filtering process to be changed + * And I expect the output set to be sorted using the same comparator as the input. + */ + @Test + public void testProcessCollection() + { + // Create a custom comparator that sorts based on the length of the strings. + Comparator comparator = new Comparator() + { + public int compare(String o1, String o2) + { + return o1.length() - o2.length(); + } + }; + SortedSet collection = new TreeSet<>(comparator); + collection.add(SHORT_INPUT); + collection.add(NON_FILTERED); + collection.add(FILTERED); + + Collection result = sortedSetPostMethodInvocationProcessor.processCollection(collection, mockStringProcessor); + + Iterator iterator = result.iterator(); + assertEquals("Expected the first element to be the shortest", NON_FILTERED, iterator.next()); + assertEquals("Expected the second element to be the longest", REALLY_LONG_OUTPUT_STRING, iterator.next()); + assertFalse("Expected two elements in output", iterator.hasNext()); + } +}