Skip to content

Commit

Permalink
Merge pull request #526 from fcrepo4/event-get-mixin-node-types
Browse files Browse the repository at this point in the history
Use Event.getMixinNodeTypes() in default filter, instead of pulling back the whole object
  • Loading branch information
Andrew Woods committed Oct 15, 2014
2 parents ba3dcf9 + 76fd5a4 commit a038383
Show file tree
Hide file tree
Showing 2 changed files with 70 additions and 87 deletions.
Expand Up @@ -16,22 +16,30 @@
package org.fcrepo.kernel.impl.observer;

import static com.google.common.base.Throwables.propagate;
import static org.fcrepo.kernel.utils.EventType.valueOf;
import static org.fcrepo.kernel.impl.utils.FedoraTypesUtils.isFedoraObject;
import static org.fcrepo.kernel.impl.utils.FedoraTypesUtils.isFedoraDatastream;
import static com.google.common.collect.Iterables.transform;
import static org.fcrepo.jcr.FedoraJcrTypes.FEDORA_BINARY;
import static org.fcrepo.jcr.FedoraJcrTypes.FEDORA_DATASTREAM;
import static org.fcrepo.jcr.FedoraJcrTypes.FEDORA_OBJECT;
import static org.fcrepo.jcr.FedoraJcrTypes.FEDORA_RESOURCE;
import static org.slf4j.LoggerFactory.getLogger;

import javax.jcr.Node;
import javax.jcr.PathNotFoundException;
import javax.jcr.RepositoryException;
import javax.jcr.Session;
import javax.jcr.nodetype.NodeType;
import javax.jcr.observation.Event;

import com.google.common.base.Function;
import com.google.common.base.Predicate;

import com.google.common.collect.ImmutableList;
import com.google.common.collect.ImmutableSet;
import org.fcrepo.kernel.observer.EventFilter;
import org.slf4j.Logger;

import java.util.Collection;
import java.util.List;

/**
* {@link EventFilter} that passes only events emitted from nodes with a Fedora
* JCR type, or properties attached to them, except in the case of a node
Expand All @@ -51,6 +59,12 @@ public class DefaultFilter implements EventFilter {
private static final Logger LOGGER = getLogger(DefaultFilter.class);

private Session session;
private static final Function<NodeType, String> nodetype2string = new Function<NodeType, String>() {
@Override
public String apply(final NodeType input) {
return input.getName();
}
};;

/**
* Default constructor.
Expand All @@ -73,31 +87,28 @@ public Predicate<Event> getFilter(final Session session) {
@Override
public boolean apply(final Event event) {
try {
switch (valueOf(event.getType())) {
case NODE_REMOVED:
final String path = event.getPath();
// only propagate non-jcr node removals, a simple test, but
// we cannot use the predicates we use below in the absence
// of a node to test
if (!path.startsWith("jcr:", path.lastIndexOf('/') + 1)) {
return true;
}
break;
default:
final String nodeId = event.getIdentifier();
final Node n = session.getNodeByIdentifier(nodeId);
if (isFedoraObject.apply(n) || isFedoraDatastream.apply(n)) {
return true;
}
break;
}
final org.modeshape.jcr.api.observation.Event modeEvent = getJcr21Event(event);

final List<NodeType> nodeTypes = ImmutableList.copyOf(modeEvent.getMixinNodeTypes());
final Collection<String> mixinTypes = ImmutableSet.copyOf(transform(nodeTypes, nodetype2string));
return mixinTypes.contains(FEDORA_RESOURCE)
|| mixinTypes.contains(FEDORA_BINARY)
|| mixinTypes.contains(FEDORA_DATASTREAM)
|| mixinTypes.contains(FEDORA_OBJECT);
} catch (final PathNotFoundException e) {
LOGGER.trace("Dropping event from outside our assigned workspace:\n", e);
return false;
} catch (final RepositoryException e) {
throw propagate(e);
}
return false;
}

private static org.modeshape.jcr.api.observation.Event getJcr21Event(final Event event) {
try {
return (org.modeshape.jcr.api.observation.Event) event;
} catch (final ClassCastException e) {
throw new ClassCastException(event + " is not a Modeshape Event");
}
}

}
Expand Up @@ -15,35 +15,26 @@
*/
package org.fcrepo.kernel.impl.observer;

import static com.google.common.base.Predicates.alwaysFalse;
import static com.google.common.base.Predicates.alwaysTrue;
import static org.fcrepo.kernel.impl.utils.FedoraTypesUtils.isFedoraDatastream;
import static org.fcrepo.kernel.impl.utils.FedoraTypesUtils.isFedoraObject;
import static org.fcrepo.jcr.FedoraJcrTypes.FEDORA_BINARY;
import static org.fcrepo.jcr.FedoraJcrTypes.FEDORA_DATASTREAM;
import static org.fcrepo.jcr.FedoraJcrTypes.FEDORA_OBJECT;
import static org.fcrepo.jcr.FedoraJcrTypes.FEDORA_RESOURCE;
import static java.util.UUID.randomUUID;
import static javax.jcr.observation.Event.NODE_ADDED;
import static javax.jcr.observation.Event.PROPERTY_ADDED;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertTrue;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.when;
import static org.mockito.MockitoAnnotations.initMocks;

import javax.jcr.Node;
import javax.jcr.PathNotFoundException;
import javax.jcr.Property;
import javax.jcr.RepositoryException;
import javax.jcr.Session;
import javax.jcr.observation.Event;
import javax.jcr.nodetype.NodeType;

import org.junit.Before;
import org.junit.Test;
import org.mockito.Mock;
import org.mockito.Mockito;
import org.modeshape.jcr.api.Repository;

import com.google.common.base.Predicate;

/**
* @author ajs6f
* @since 2013
Expand All @@ -59,7 +50,7 @@ public class DefaultFilterTest {
private Repository mockRepo;

@Mock
private Event mockEvent;
private org.modeshape.jcr.api.observation.Event mockEvent;

@Mock
private Node mockNode;
Expand All @@ -71,72 +62,53 @@ public class DefaultFilterTest {

private final static String testPath = "/foo/bar";

@Mock
private NodeType fedoraResource;
@Mock
private NodeType fedoraObject;
@Mock
private NodeType fedoraDatastream;
@Mock
private NodeType fedoraBinary;

@Before
public void setUp() throws Exception {
initMocks(this);
mockSession = mock(Session.class, Mockito.withSettings().extraInterfaces(org.modeshape.jcr.api.Session.class));
when(mockEvent.getPath()).thenReturn(testPath);
when(mockEvent.getIdentifier()).thenReturn(testId);
when(mockEvent.getType()).thenReturn(NODE_ADDED);
when(mockNode.isNode()).thenReturn(true);
testObj = new DefaultFilter();
when(mockRepo.login()).thenReturn((org.modeshape.jcr.api.Session) mockSession);
when(fedoraResource.getName()).thenReturn(FEDORA_RESOURCE);
when(fedoraObject.getName()).thenReturn(FEDORA_OBJECT);
when(fedoraDatastream.getName()).thenReturn(FEDORA_DATASTREAM);
when(fedoraBinary.getName()).thenReturn(FEDORA_BINARY);
}

@Test
public void shouldApplyToObjectOrDatastream() throws Exception {
when(mockSession.getItem(testPath)).thenReturn(mockNode);
final Predicate<Node> holdO = isFedoraObject;
try {
isFedoraObject = alwaysTrue();
assertTrue(testObj.getFilter(mockSession).apply(mockEvent));
} finally {
isFedoraObject = holdO;
}
public void shouldApplyToResource() throws Exception {
when(mockEvent.getMixinNodeTypes()).thenReturn(new NodeType[] { fedoraResource });
assertTrue(testObj.getFilter(mockSession).apply(mockEvent));
}

@Test
public void shouldNotApplyToNonExistentNodes() throws Exception {
when(mockSession.getNodeByIdentifier(testId)).thenThrow(
new PathNotFoundException("Expected."));
assertFalse(testObj.getFilter(mockSession).apply(mockEvent));
public void shouldApplyToObject() throws Exception {
when(mockEvent.getMixinNodeTypes()).thenReturn(new NodeType[] { fedoraObject });
assertTrue(testObj.getFilter(mockSession).apply(mockEvent));
}

@Test
public void shouldNotApplyToNonFedoraNodes() throws Exception {
when(mockSession.getNode(testPath)).thenReturn(mockNode);
final Predicate<Node> holdO = isFedoraObject;
final Predicate<Node> hold1 = isFedoraDatastream;
try {
isFedoraObject = alwaysFalse();
isFedoraDatastream = alwaysFalse();
assertFalse(testObj.getFilter(mockSession).apply(mockEvent));
} finally {
isFedoraObject = holdO;
isFedoraDatastream = hold1;
}
public void shouldApplyToDatastream() throws Exception {
when(mockEvent.getMixinNodeTypes()).thenReturn(new NodeType[] { fedoraDatastream });
assertTrue(testObj.getFilter(mockSession).apply(mockEvent));
}

@Test(expected = RuntimeException.class)
public void testBadItem() throws RepositoryException {
when(mockEvent.getType()).thenReturn(PROPERTY_ADDED);
when(mockSession.getNode("/foo")).thenThrow(
new RepositoryException("Expected."));
when(mockProperty.isNode()).thenReturn(false);
testObj.getFilter(mockSession).apply(mockEvent);
@Test
public void shouldApplyToBinary() throws Exception {
when(mockEvent.getMixinNodeTypes()).thenReturn(new NodeType[] { fedoraBinary });
assertTrue(testObj.getFilter(mockSession).apply(mockEvent));
}


@Test
public void testProperty() throws RepositoryException {
when(mockProperty.isNode()).thenReturn(false);
when(mockProperty.getParent()).thenReturn(mockNode);
when(mockSession.getItem(testPath)).thenReturn(mockProperty);
final Predicate<Node> holdO = isFedoraObject;
try {
isFedoraObject = alwaysTrue();
assertNotNull(testObj.getFilter(mockSession).apply(mockEvent));
} finally {
isFedoraObject = holdO;
}
public void shouldNotApplyToNonFedoraNodes() throws Exception {
when(mockEvent.getMixinNodeTypes()).thenReturn(new NodeType[] { });
assertFalse(testObj.getFilter(mockSession).apply(mockEvent));
}
}

0 comments on commit a038383

Please sign in to comment.