001/*
002 * Copyright 2015 DuraSpace, Inc.
003 *
004 * Licensed under the Apache License, Version 2.0 (the "License");
005 * you may not use this file except in compliance with the License.
006 * You may obtain a copy of the License at
007 *
008 *     http://www.apache.org/licenses/LICENSE-2.0
009 *
010 * Unless required by applicable law or agreed to in writing, software
011 * distributed under the License is distributed on an "AS IS" BASIS,
012 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
013 * See the License for the specific language governing permissions and
014 * limitations under the License.
015 */
016package org.fcrepo.kernel.modeshape.observer;
017
018import static com.google.common.collect.Sets.newHashSet;
019import static java.util.Arrays.stream;
020import static java.util.stream.Stream.concat;
021import static java.util.stream.Stream.of;
022import static org.fcrepo.kernel.api.FedoraTypes.FEDORA_BINARY;
023import static org.fcrepo.kernel.api.FedoraTypes.FEDORA_NON_RDF_SOURCE_DESCRIPTION;
024import static org.fcrepo.kernel.api.FedoraTypes.FEDORA_CONTAINER;
025import static org.fcrepo.kernel.api.FedoraTypes.FEDORA_RESOURCE;
026import static org.fcrepo.kernel.modeshape.FedoraJcrConstants.ROOT;
027import static org.slf4j.LoggerFactory.getLogger;
028
029import javax.jcr.PathNotFoundException;
030import javax.jcr.RepositoryException;
031import javax.jcr.nodetype.NodeType;
032import javax.jcr.observation.Event;
033
034import org.fcrepo.kernel.api.exception.RepositoryRuntimeException;
035
036import org.slf4j.Logger;
037
038import java.util.HashSet;
039import java.util.stream.Stream;
040
041/**
042 * {@link EventFilter} that passes only events emitted from nodes with a Fedora
043 * JCR type, or properties attached to them, except in the case of a node
044 * removal. In that case, since we cannot test the node for its types, we assume
045 * that any non-JCR namespaced node is fair game.
046 *
047 * @author ajs6f
048 * @author barmintor
049 * @since Dec 2013
050 * @author eddies
051 * @since Feb 7, 2013
052 * @author escowles
053 * @since Oct 3, 2013
054 */
055public class DefaultFilter implements EventFilter {
056
057    private static final Logger LOGGER = getLogger(DefaultFilter.class);
058
059    private static final HashSet<String> fedoraMixins =
060            newHashSet(FEDORA_BINARY, FEDORA_CONTAINER, FEDORA_NON_RDF_SOURCE_DESCRIPTION, FEDORA_RESOURCE, ROOT);
061
062    @Override
063    public boolean test(final Event event) {
064        try {
065            return getMixinTypes(event).anyMatch(fedoraMixins::contains);
066        } catch (final PathNotFoundException e) {
067            LOGGER.trace("Dropping event from outside our assigned workspace:\n", e);
068            return false;
069        } catch (final RepositoryException e) {
070            throw new RepositoryRuntimeException(e);
071        }
072    }
073
074    protected static Stream<String> getMixinTypes(final Event event)
075            throws PathNotFoundException, RepositoryException {
076        try {
077            final org.modeshape.jcr.api.observation.Event modeEvent =
078                    (org.modeshape.jcr.api.observation.Event) event;
079            return concat(of(modeEvent.getPrimaryNodeType()), stream(modeEvent.getMixinNodeTypes()))
080                .map(NodeType::toString);
081        } catch (final ClassCastException e) {
082            throw new ClassCastException(event + " is not a Modeshape Event");
083        }
084    }
085
086}