RM-2130 (Check classification after method execution, filtering results where appropriate)

- Code refactored

git-svn-id: https://svn.alfresco.com/repos/alfresco-enterprise/modules/recordsmanagement/HEAD@107441 c4b6b30b-aa2e-2d43-bbcb-ca4b014f7261
This commit is contained in:
Tuna Aksoy
2015-06-30 19:15:27 +00:00
parent fa3f1230a4
commit ea4d00f100
19 changed files with 145 additions and 580 deletions

View File

@@ -49,7 +49,7 @@ public class ArrayPostMethodInvocationProcessor extends BasePostMethodInvocation
*/ */
@SuppressWarnings({ "unchecked", "rawtypes" }) @SuppressWarnings({ "unchecked", "rawtypes" })
@Override @Override
public <T> T process(T object) protected <T> T process(T object)
{ {
T result = object; T result = object;

View File

@@ -44,7 +44,7 @@ public class AssociationRefPostMethodInvocationProcessor extends BasePostMethodI
* @see org.alfresco.module.org_alfresco_module_rm.classification.interceptor.processor.BasePostMethodInvocationProcessor#process(java.lang.Object) * @see org.alfresco.module.org_alfresco_module_rm.classification.interceptor.processor.BasePostMethodInvocationProcessor#process(java.lang.Object)
*/ */
@Override @Override
public <T> T process(T object) protected <T> T process(T object)
{ {
T result = object; T result = object;

View File

@@ -97,51 +97,11 @@ public abstract class BasePostMethodInvocationProcessor
return this.postMethodInvocationProcessor; return this.postMethodInvocationProcessor;
} }
/**
* @param nodeService the nodeService to set
*/
public void setNodeService(NodeService nodeService)
{
this.nodeService = nodeService;
}
/**
* @param dictionaryService the dictionaryService to set
*/
public void setDictionaryService(DictionaryService dictionaryService)
{
this.dictionaryService = dictionaryService;
}
/**
* @param contentClassificationService the contentClassificationService to set
*/
public void setContentClassificationService(ContentClassificationService contentClassificationService)
{
this.contentClassificationService = contentClassificationService;
}
/**
* @param securityClearanceService the securityClearanceService to set
*/
public void setSecurityClearanceService(SecurityClearanceService securityClearanceService)
{
this.securityClearanceService = securityClearanceService;
}
/**
* @param postMethodInvocationProcessor the postMethodInvocationProcessor to set
*/
public void setPostMethodInvocationProcessor(PostMethodInvocationProcessor postMethodInvocationProcessor)
{
this.postMethodInvocationProcessor = postMethodInvocationProcessor;
}
/** /**
* Registers the post method invocation processors * Registers the post method invocation processors
*/ */
@PostConstruct @PostConstruct
public void register() private void register()
{ {
getPostMethodInvocationProcessor().register(this); getPostMethodInvocationProcessor().register(this);
} }

View File

@@ -44,7 +44,7 @@ public class ChildAssociationRefPostMethodInvocationProcessor extends BasePostMe
* @see org.alfresco.module.org_alfresco_module_rm.classification.interceptor.processor.BasePostMethodInvocationProcessor#process(java.lang.Object) * @see org.alfresco.module.org_alfresco_module_rm.classification.interceptor.processor.BasePostMethodInvocationProcessor#process(java.lang.Object)
*/ */
@Override @Override
public <T> T process(T object) protected <T> T process(T object)
{ {
T result = object; T result = object;

View File

@@ -35,8 +35,9 @@ public class CollectionPostMethodInvocationProcessor extends BasePostMethodInvoc
/** /**
* @see org.alfresco.module.org_alfresco_module_rm.classification.interceptor.processor.BasePostMethodInvocationProcessor#getClassName() * @see org.alfresco.module.org_alfresco_module_rm.classification.interceptor.processor.BasePostMethodInvocationProcessor#getClassName()
*/ */
@SuppressWarnings("rawtypes")
@Override @Override
protected Class<?> getClassName() protected Class<Collection> getClassName()
{ {
return Collection.class; return Collection.class;
} }
@@ -46,79 +47,38 @@ public class CollectionPostMethodInvocationProcessor extends BasePostMethodInvoc
*/ */
@SuppressWarnings({ "rawtypes", "unchecked" }) @SuppressWarnings({ "rawtypes", "unchecked" })
@Override @Override
public <T> T process(T object) protected <T> T process(T object)
{ {
Collection collection = ((Collection) object); T result = object;
if (collection != null) if (result != null)
{ {
BasePostMethodInvocationProcessor processor = pickProcessor(collection); BasePostMethodInvocationProcessor processor = null;
if (processor != null) Collection collection = getClassName().cast(object);
{ Iterator<T> iterator = collection.iterator();
object = (T) processCollection(collection, processor);
}
}
return object; while (iterator.hasNext())
}
/**
* 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 <T> Collection<T> processCollection(Collection<T> collection, BasePostMethodInvocationProcessor processor)
{
Iterator<T> iterator = collection.iterator();
while (iterator.hasNext())
{
Object next = iterator.next();
Object processed = processor.process(next);
try
{ {
if (processed == null) Object element = iterator.next();
if (processor == null)
{
processor = getPostMethodInvocationProcessor().getProcessor(element);
if (processor == null)
{
break;
}
}
Object processedElement = processor.process(element);
if (processedElement == null)
{ {
iterator.remove(); 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;
}
/** result = (T) 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;
return result;
} }
} }

View File

@@ -1,47 +0,0 @@
/*
* 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 <http://www.gnu.org/licenses/>.
*/
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 <T> Collection<T> createEmptyCollection(Collection<T> collection)
{
return new ArrayList<>();
}
}

View File

@@ -1,61 +0,0 @@
/*
* 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 <http://www.gnu.org/licenses/>.
*/
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 <T> Collection<T> createEmptyCollection(Collection<T> collection);
/** {@inheritDoc} */
@Override
protected <T> Collection<T> processCollection(Collection<T> collection, BasePostMethodInvocationProcessor processor)
{
Collection<T> returnList = createEmptyCollection(collection);
for (T member : collection)
{
T processed = processor.process(member);
if (processed != null)
{
returnList.add(processed);
}
}
return returnList;
}
}

View File

@@ -43,7 +43,7 @@ public class NodeRefPostMethodInvocationProcessor extends BasePostMethodInvocati
* @see org.alfresco.module.org_alfresco_module_rm.classification.interceptor.processor.BasePostMethodInvocationProcessor#process(java.lang.Object) * @see org.alfresco.module.org_alfresco_module_rm.classification.interceptor.processor.BasePostMethodInvocationProcessor#process(java.lang.Object)
*/ */
@Override @Override
public <T> T process(T object) protected <T> T process(T object)
{ {
T result = object; T result = object;

View File

@@ -48,7 +48,7 @@ public class PagingResultsPostMethodInvocationProcessor extends BasePostMethodIn
*/ */
@SuppressWarnings({ "rawtypes", "unchecked" }) @SuppressWarnings({ "rawtypes", "unchecked" })
@Override @Override
public <T> T process(T object) protected <T> T process(T object)
{ {
T result = object; T result = object;

View File

@@ -44,7 +44,7 @@ public class PermissionCheckValuePostMethodInvocationProcessor extends BasePostM
* @see org.alfresco.module.org_alfresco_module_rm.classification.interceptor.processor.BasePostMethodInvocationProcessor#process(java.lang.Object) * @see org.alfresco.module.org_alfresco_module_rm.classification.interceptor.processor.BasePostMethodInvocationProcessor#process(java.lang.Object)
*/ */
@Override @Override
public <T> T process(T object) protected <T> T process(T object)
{ {
T result = object; T result = object;

View File

@@ -50,7 +50,7 @@ public class QueryEngineResultsPostMethodInvocationProcessor extends BasePostMet
*/ */
@SuppressWarnings("unchecked") @SuppressWarnings("unchecked")
@Override @Override
public <T> T process(T object) protected <T> T process(T object)
{ {
T result = object; T result = object;

View File

@@ -55,7 +55,7 @@ public class ResultSetPostMethodInvocationProcessor extends BasePostMethodInvoca
*/ */
@SuppressWarnings({ "unchecked" }) @SuppressWarnings({ "unchecked" })
@Override @Override
public <T> T process(T object) protected <T> T process(T object)
{ {
T result = object; T result = object;

View File

@@ -1,47 +0,0 @@
/*
* 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 <http://www.gnu.org/licenses/>.
*/
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 <T> Collection<T> createEmptyCollection(Collection<T> collection)
{
return new HashSet<>();
}
}

View File

@@ -1,45 +0,0 @@
/*
* 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 <http://www.gnu.org/licenses/>.
*/
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 <T> Collection<T> createEmptyCollection(Collection<T> collection)
{
SortedSet<T> sortedSet = (SortedSet<T>) collection;
return new TreeSet<>(sortedSet.comparator());
}
}

View File

@@ -41,10 +41,10 @@ public class StoreRefPostMethodInvocationProcessor extends BasePostMethodInvocat
} }
/** /**
* @see org.alfresco.module.org_alfresco_module_rm.classification.interceptor.processor.AbstractPostMethodInvocationProcessor#processSingleElement(java.lang.Object) * @see org.alfresco.module.org_alfresco_module_rm.classification.interceptor.processor.BasePostMethodInvocationProcessor#process(java.lang.Object)
*/ */
@Override @Override
public <T> T process(T object) protected <T> T process(T object)
{ {
T result = object; T result = object;

View File

@@ -18,18 +18,20 @@
*/ */
package org.alfresco.module.org_alfresco_module_rm.classification.interceptor.processor; package org.alfresco.module.org_alfresco_module_rm.classification.interceptor.processor;
import static org.alfresco.service.cmr.repository.StoreRef.STORE_REF_WORKSPACE_SPACESSTORE;
import static org.alfresco.util.GUID.generate;
import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertTrue; import static org.junit.Assert.assertTrue;
import static org.mockito.Matchers.isA;
import static org.mockito.Mockito.when; import static org.mockito.Mockito.when;
import static org.mockito.MockitoAnnotations.initMocks;
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; import org.alfresco.service.cmr.repository.NodeRef;
import org.apache.commons.lang3.ArrayUtils; import org.apache.commons.lang3.ArrayUtils;
import org.junit.Before;
import org.junit.Test; import org.junit.Test;
import org.mockito.InjectMocks; import org.mockito.InjectMocks;
import org.mockito.Mock; import org.mockito.Mock;
import org.mockito.Mockito;
/** /**
* Array Post Method Invocation Processor Unit Test * Array Post Method Invocation Processor Unit Test
@@ -37,40 +39,38 @@ import org.mockito.Mockito;
* @author Tuna Aksoy * @author Tuna Aksoy
* @since 3.0 * @since 3.0
*/ */
public class ArrayPostMethodInvocationProcessorUnitTest extends BaseUnitTest public class ArrayPostMethodInvocationProcessorUnitTest
{ {
@InjectMocks ArrayPostMethodInvocationProcessor arrayPostMethodInvocationProcessor; private static final NodeRef NODE_REF_1 = new NodeRef(STORE_REF_WORKSPACE_SPACESSTORE, generate());
@Mock private ContentClassificationService mockedContentClassificationService; private static final NodeRef NODE_REF_2 = new NodeRef(STORE_REF_WORKSPACE_SPACESSTORE, generate());
private static final NodeRef NODE_REF_3 = new NodeRef(STORE_REF_WORKSPACE_SPACESSTORE, generate());
private static final NodeRef NODE_REF_4 = new NodeRef(STORE_REF_WORKSPACE_SPACESSTORE, generate());
@InjectMocks private ArrayPostMethodInvocationProcessor arrayPostMethodInvocationProcessor;
@Mock private PostMethodInvocationProcessor mockedPostMethodInvocationProcessor; @Mock private PostMethodInvocationProcessor mockedPostMethodInvocationProcessor;
@Mock private BasePostMethodInvocationProcessor mockedNodeRefProcessor;
@Before
public void setUp()
{
initMocks(this);
when(mockedPostMethodInvocationProcessor.getProcessor(isA(NodeRef.class))).thenReturn(mockedNodeRefProcessor);
when(mockedNodeRefProcessor.process(NODE_REF_1)).thenReturn(NODE_REF_1);
when(mockedNodeRefProcessor.process(NODE_REF_2)).thenReturn(null);
when(mockedNodeRefProcessor.process(NODE_REF_3)).thenReturn(NODE_REF_3);
when(mockedNodeRefProcessor.process(NODE_REF_4)).thenReturn(null);
}
@Test @Test
public void testArrayPostMethodInvocationProcessor() public void testArrayPostMethodInvocationProcessor()
{ {
NodeRefPostMethodInvocationProcessor processor = new NodeRefPostMethodInvocationProcessor(); NodeRef[] nodes = new NodeRef[] { NODE_REF_1, NODE_REF_2, NODE_REF_3, NODE_REF_4 };
processor.setNodeService(mockedNodeService);
processor.setDictionaryService(mockedDictionaryService);
processor.setContentClassificationService(mockedContentClassificationService);
NodeRef nodeRef1 = generateNodeRef();
NodeRef nodeRef2 = generateNodeRef();
NodeRef nodeRef3 = generateNodeRef();
NodeRef nodeRef4 = generateNodeRef();
when(mockedDictionaryService.isSubClass(mockedNodeService.getType(nodeRef1), TYPE_CONTENT)).thenReturn(true);
when(mockedDictionaryService.isSubClass(mockedNodeService.getType(nodeRef2), TYPE_CONTENT)).thenReturn(true);
when(mockedDictionaryService.isSubClass(mockedNodeService.getType(nodeRef3), TYPE_CONTENT)).thenReturn(true);
when(mockedDictionaryService.isSubClass(mockedNodeService.getType(nodeRef4), TYPE_CONTENT)).thenReturn(true);
when(mockedContentClassificationService.hasClearance(nodeRef1)).thenReturn(true);
when(mockedContentClassificationService.hasClearance(nodeRef2)).thenReturn(false);
when(mockedContentClassificationService.hasClearance(nodeRef3)).thenReturn(true);
when(mockedContentClassificationService.hasClearance(nodeRef4)).thenReturn(false);
when(mockedPostMethodInvocationProcessor.getProcessor(Mockito.any())).thenReturn(processor);
NodeRef[] nodes = new NodeRef[] { nodeRef1, nodeRef2, nodeRef3, nodeRef4 };
NodeRef[] processedNodes = arrayPostMethodInvocationProcessor.process(nodes); NodeRef[] processedNodes = arrayPostMethodInvocationProcessor.process(nodes);
assertEquals(2, processedNodes.length); assertEquals(2, processedNodes.length);
assertTrue(ArrayUtils.contains(processedNodes, nodeRef1)); assertTrue(ArrayUtils.contains(processedNodes, NODE_REF_1));
assertTrue(ArrayUtils.contains(processedNodes, nodeRef3)); assertTrue(ArrayUtils.contains(processedNodes, NODE_REF_3));
} }
} }

View File

@@ -18,7 +18,11 @@
*/ */
package org.alfresco.module.org_alfresco_module_rm.classification.interceptor.processor; package org.alfresco.module.org_alfresco_module_rm.classification.interceptor.processor;
import static com.google.common.collect.Lists.newArrayList;
import static java.util.Arrays.asList;
import static org.alfresco.util.GUID.generate;
import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertNull; import static org.junit.Assert.assertNull;
import static org.junit.Assert.assertTrue; import static org.junit.Assert.assertTrue;
import static org.mockito.Matchers.isA; import static org.mockito.Matchers.isA;
@@ -26,9 +30,12 @@ import static org.mockito.Mockito.when;
import static org.mockito.MockitoAnnotations.initMocks; import static org.mockito.MockitoAnnotations.initMocks;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection; import java.util.Collection;
import java.util.Comparator;
import java.util.Iterator;
import java.util.List; import java.util.List;
import java.util.SortedSet;
import java.util.TreeSet;
import org.junit.Before; import org.junit.Before;
import org.junit.Test; import org.junit.Test;
@@ -43,25 +50,25 @@ import org.mockito.Mock;
*/ */
public class CollectionPostMethodInvocationProcessorUnitTest public class CollectionPostMethodInvocationProcessorUnitTest
{ {
private static final String NON_FILTERED = "NON_FILTERED"; private static final String REALLY_LONG_OUTPUT_STRING = generate() + generate();
private static final String FILTERED = "FILTERED"; private static final String NON_FILTERED = generate();
private static final String CHANGED_INPUT = "CHANGED_INPUT"; private static final String FILTERED = generate();
private static final String CHANGED_OUTPUT = "CHANGED_OUTPUT";
@InjectMocks CollectionPostMethodInvocationProcessor collectionPostMethodInvocationProcessor; @InjectMocks private CollectionPostMethodInvocationProcessor collectionPostMethodInvocationProcessor;
@Mock PostMethodInvocationProcessor mockPostMethodInvocationProcessor; @Mock private PostMethodInvocationProcessor mockPostMethodInvocationProcessor;
@Mock BasePostMethodInvocationProcessor mockStringProcessor; @Mock private BasePostMethodInvocationProcessor mockStringProcessor;
@Before @Before
public void setUp() public void setUp()
{ {
initMocks(this); initMocks(this);
when(mockPostMethodInvocationProcessor.getProcessor(isA(List.class))).thenReturn(collectionPostMethodInvocationProcessor);
when(mockPostMethodInvocationProcessor.getProcessor(isA(String.class))).thenReturn(mockStringProcessor); when(mockPostMethodInvocationProcessor.getProcessor(isA(String.class))).thenReturn(mockStringProcessor);
when(mockStringProcessor.process(REALLY_LONG_OUTPUT_STRING)).thenReturn(REALLY_LONG_OUTPUT_STRING);
when(mockStringProcessor.process(NON_FILTERED)).thenReturn(NON_FILTERED); when(mockStringProcessor.process(NON_FILTERED)).thenReturn(NON_FILTERED);
when(mockStringProcessor.process(FILTERED)).thenReturn(null); when(mockStringProcessor.process(FILTERED)).thenReturn(null);
when(mockStringProcessor.process(CHANGED_INPUT)).thenReturn(CHANGED_OUTPUT);
} }
@Test @Test
@@ -83,10 +90,20 @@ public class CollectionPostMethodInvocationProcessorUnitTest
assertEquals("Expected collection containing null to be passed through.", collection, result); assertEquals("Expected collection containing null to be passed through.", collection, result);
} }
@Test
public void testProcess_emptyList()
{
List<String> collection = new ArrayList<>();
Collection<String> result = collectionPostMethodInvocationProcessor.process(collection);
assertEquals(collection, result);
}
@Test @Test
public void testProcess_nonFilteredMember() public void testProcess_nonFilteredMember()
{ {
Object collection = Arrays.asList(NON_FILTERED); Object collection = asList(NON_FILTERED);
Object result = collectionPostMethodInvocationProcessor.process(collection); Object result = collectionPostMethodInvocationProcessor.process(collection);
@@ -96,42 +113,76 @@ public class CollectionPostMethodInvocationProcessorUnitTest
@Test @Test
public void testProcess_filteredMemberInModifiableList() public void testProcess_filteredMemberInModifiableList()
{ {
List<String> collection = new ArrayList<>(Arrays.asList(FILTERED)); List<String> collection = newArrayList(FILTERED);
Collection<String> result = collectionPostMethodInvocationProcessor.process(collection); Collection<String> result = collectionPostMethodInvocationProcessor.process(collection);
assertTrue("Expected an empty list.", result.isEmpty()); assertTrue("Expected an empty list.", result.isEmpty());
} }
@Test @Test(expected = UnsupportedOperationException.class)
public void testProcess_filteredMemberInUnmodifiableList() public void testProcess_filteredMemberInUnmodifiableList()
{ {
List<String> collection = Arrays.asList(FILTERED, NON_FILTERED); List<String> collection = asList(FILTERED, NON_FILTERED);
Collection<String> result = collectionPostMethodInvocationProcessor.process(collection); collectionPostMethodInvocationProcessor.process(collection);
assertNull("Since the collection could not be modified the whole thing should be filtered.", result);
}
@Test
public void testProcess_modifiedMember()
{
List<String> collection = Arrays.asList(NON_FILTERED, CHANGED_INPUT);
Collection<String> result = collectionPostMethodInvocationProcessor.process(collection);
assertNull("Since the Collection interface does not support replacement, the whole collection should be filtered.",
result);
} }
@Test @Test
public void testProcess_noProcessorDefined() public void testProcess_noProcessorDefined()
{ {
List<Integer> collection = Arrays.asList(1, 4, 91); List<Integer> collection = asList(1, 4, 91);
Collection<Integer> result = collectionPostMethodInvocationProcessor.process(collection); Collection<Integer> result = collectionPostMethodInvocationProcessor.process(collection);
assertEquals("If no processor is defined for the members then the whole list should be returned.", collection, assertEquals("If no processor is defined for the members then the whole list should be returned.", collection, result);
result); }
@SuppressWarnings("unchecked")
@Test
public void testProcess_listOfLists()
{
List<String> innerListA = newArrayList(FILTERED, NON_FILTERED);
List<String> innerListB = newArrayList(FILTERED, NON_FILTERED);
List<List<String>> collection = newArrayList(innerListA, innerListB);
Collection<List<String>> result = collectionPostMethodInvocationProcessor.process(collection);
List<String> expectedInnerListA = asList(NON_FILTERED);
List<String> expectedInnerListB = asList(NON_FILTERED);
List<List<String>> expected = asList(expectedInnerListA, expectedInnerListB);
assertEquals(expected, result);
}
/**
* Given I have a sorted set of input strings
* When I pass it to the collection 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 the output set to be sorted using the same comparator as the input.
*/
@Test
public void testProcess_sortedSet()
{
// Create a custom comparator that sorts based on the length of the strings.
Comparator<String> comparator = new Comparator<String>()
{
public int compare(String o1, String o2)
{
return o1.length() - o2.length();
}
};
SortedSet<String> collection = new TreeSet<>(comparator);
collection.add(REALLY_LONG_OUTPUT_STRING);
collection.add(NON_FILTERED);
collection.add(FILTERED);
Collection<String> result = collectionPostMethodInvocationProcessor.process(collection);
Iterator<String> 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());
} }
} }

View File

@@ -1,112 +0,0 @@
/*
* 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 <http://www.gnu.org/licenses/>.
*/
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<String> collection = new ArrayList<>();
Collection<String> result = listPostMethodInvocationProcessor.processCollection(collection, mockStringProcessor);
assertEquals(collection, result);
}
@Test
public void testProcessCollection_completelyFiltered()
{
List<String> collection = Arrays.asList(FILTERED, FILTERED);
Collection<String> result = listPostMethodInvocationProcessor.processCollection(collection, mockStringProcessor);
assertTrue("Expected all members of the list to be removed.", result.isEmpty());
}
@Test
public void testProcessCollection_supportsReplacement()
{
List<String> collection = Arrays.asList(NON_FILTERED, CHANGED_INPUT);
Collection<String> result = listPostMethodInvocationProcessor.processCollection(collection, mockStringProcessor);
List<String> expected = Arrays.asList(NON_FILTERED, CHANGED_OUTPUT);
assertEquals(expected, result);
}
@Test
public void testProcess_listOfLists()
{
List<String> innerListA = Arrays.asList(FILTERED, NON_FILTERED, CHANGED_INPUT);
List<String> innerListB = Arrays.asList(CHANGED_INPUT, FILTERED, NON_FILTERED);
List<List<String>> collection = Arrays.asList(innerListA, innerListB);
Collection<List<String>> result = listPostMethodInvocationProcessor.process(collection);
List<String> expectedInnerListA = Arrays.asList(NON_FILTERED, CHANGED_OUTPUT);
List<String> expectedInnerListB = Arrays.asList(CHANGED_OUTPUT, NON_FILTERED);
List<List<String>> expected = Arrays.asList(expectedInnerListA, expectedInnerListB);
assertEquals(expected, result);
}
}

View File

@@ -1,94 +0,0 @@
/*
* 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 <http://www.gnu.org/licenses/>.
*/
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<String> comparator = new Comparator<String>()
{
public int compare(String o1, String o2)
{
return o1.length() - o2.length();
}
};
SortedSet<String> collection = new TreeSet<>(comparator);
collection.add(SHORT_INPUT);
collection.add(NON_FILTERED);
collection.add(FILTERED);
Collection<String> result = sortedSetPostMethodInvocationProcessor.processCollection(collection, mockStringProcessor);
Iterator<String> 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());
}
}