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.services.functions;
017
018import static com.google.common.base.Throwables.propagate;
019import static org.fcrepo.kernel.FedoraJcrTypes.FROZEN_MIXIN_TYPES;
020import static org.fcrepo.kernel.services.functions.JcrPropertyFunctions.isFrozen;
021import static org.fcrepo.kernel.services.functions.JcrPropertyFunctions.property2values;
022import static org.fcrepo.kernel.services.functions.JcrPropertyFunctions.value2string;
023
024import java.util.Arrays;
025import java.util.Collection;
026import java.util.Iterator;
027
028import javax.jcr.Node;
029import javax.jcr.RepositoryException;
030
031import com.google.common.base.Predicate;
032import com.google.common.collect.Iterators;
033
034/**
035 * Base class for matching sets of node types
036 * @author armintor@gmail.com
037 *
038 */
039public abstract class BooleanTypesPredicate implements Predicate<Node> {
040
041    protected final Collection<String> nodeTypes;
042
043    /**
044     * Base constructor for function peforming boolean ops on matched node types.
045     * @param types the types
046     */
047    public BooleanTypesPredicate(final String... types) {
048        nodeTypes = Arrays.asList(types);
049    }
050
051    @Override
052    public boolean apply(final Node input) {
053        if (input == null) {
054            throw new IllegalArgumentException(
055                    "null node passed to" + getClass().getName()
056            );
057        }
058        int matched = 0;
059        try {
060
061            if (isFrozen.apply(input) && input.hasProperty(FROZEN_MIXIN_TYPES)) {
062                final Iterator<String> transform = Iterators.transform(
063                        property2values.apply(input.getProperty(FROZEN_MIXIN_TYPES)),
064                        value2string
065                );
066
067                while (transform.hasNext()) {
068                    if (nodeTypes.contains(transform.next())) {
069                        matched++;
070                    }
071                }
072            } else {
073                for (final String nodeType : nodeTypes) {
074                    if (input.isNodeType(nodeType)) {
075                        matched++;
076                    }
077                }
078            }
079        } catch (RepositoryException e) {
080            throw propagate(e);
081        }
082        return test(matched);
083    }
084
085    protected abstract boolean test(final int matched);
086
087}