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.impl.observer;
017
018import static com.google.common.base.Throwables.propagate;
019import static com.google.common.collect.Iterables.transform;
020import static org.fcrepo.kernel.FedoraJcrTypes.FEDORA_BINARY;
021import static org.fcrepo.kernel.FedoraJcrTypes.FEDORA_NON_RDF_SOURCE_DESCRIPTION;
022import static org.fcrepo.kernel.FedoraJcrTypes.FEDORA_CONTAINER;
023import static org.fcrepo.kernel.FedoraJcrTypes.FEDORA_RESOURCE;
024import static org.slf4j.LoggerFactory.getLogger;
025
026import javax.jcr.PathNotFoundException;
027import javax.jcr.RepositoryException;
028import javax.jcr.Session;
029import javax.jcr.nodetype.NodeType;
030import javax.jcr.observation.Event;
031
032import com.google.common.base.Function;
033import com.google.common.base.Predicate;
034
035import com.google.common.collect.ImmutableList;
036import com.google.common.collect.ImmutableSet;
037import org.fcrepo.kernel.observer.EventFilter;
038import org.slf4j.Logger;
039
040import java.util.Collection;
041import java.util.List;
042
043/**
044 * {@link EventFilter} that passes only events emitted from nodes with a Fedora
045 * JCR type, or properties attached to them, except in the case of a node
046 * removal. In that case, since we cannot test the node for its types, we assume
047 * that any non-JCR namespaced node is fair game.
048 *
049 * @author ajs6f
050 * @author barmintor
051 * @since Dec 2013
052 * @author eddies
053 * @since Feb 7, 2013
054 * @author escowles
055 * @since Oct 3, 2013
056 */
057public class DefaultFilter implements EventFilter {
058
059    private static final Logger LOGGER = getLogger(DefaultFilter.class);
060
061    private static final Function<NodeType, String> nodetype2string = new Function<NodeType, String>() {
062        @Override
063        public String apply(final NodeType input) {
064            return input.getName();
065        }
066    };
067
068    /**
069     * Default constructor.
070     */
071    public DefaultFilter() {
072    }
073
074    @Override
075    public Predicate<Event> getFilter(final Session session) {
076        return new DefaultFilter();
077    }
078
079    @Override
080    public boolean apply(final Event event) {
081        try {
082            final org.modeshape.jcr.api.observation.Event modeEvent = getJcr21Event(event);
083
084            final List<NodeType> nodeTypes = ImmutableList.copyOf(modeEvent.getMixinNodeTypes());
085            final Collection<String> mixinTypes = ImmutableSet.copyOf(transform(nodeTypes, nodetype2string));
086            return mixinTypes.contains(FEDORA_RESOURCE)
087                    || mixinTypes.contains(FEDORA_BINARY)
088                    || mixinTypes.contains(FEDORA_NON_RDF_SOURCE_DESCRIPTION)
089                    || mixinTypes.contains(FEDORA_CONTAINER);
090        } catch (final PathNotFoundException e) {
091            LOGGER.trace("Dropping event from outside our assigned workspace:\n", e);
092            return false;
093        } catch (final RepositoryException e) {
094            throw propagate(e);
095        }
096    }
097
098    private static org.modeshape.jcr.api.observation.Event getJcr21Event(final Event event) {
099        try {
100            return (org.modeshape.jcr.api.observation.Event) event;
101        } catch (final ClassCastException e) {
102            throw new ClassCastException(event + " is not a Modeshape Event");
103        }
104    }
105
106}