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 com.google.common.base.Function;
019import com.google.common.base.Predicate;
020import com.google.common.collect.Iterators;
021import org.fcrepo.kernel.FedoraJcrTypes;
022import org.slf4j.Logger;
023
024import javax.jcr.Node;
025import javax.jcr.Property;
026import javax.jcr.RepositoryException;
027import javax.jcr.Value;
028import javax.jcr.nodetype.NodeType;
029import java.util.Iterator;
030
031import static com.google.common.base.Preconditions.checkNotNull;
032import static com.google.common.base.Throwables.propagate;
033import static javax.jcr.PropertyType.BINARY;
034import static org.modeshape.jcr.api.JcrConstants.JCR_DATA;
035import static org.slf4j.LoggerFactory.getLogger;
036
037/**
038 * @author cabeer
039 * @since 9/25/14
040 */
041public final class JcrPropertyFunctions {
042
043    private static final Logger LOGGER = getLogger(JcrPropertyFunctions.class);
044
045    private JcrPropertyFunctions() {
046    }
047
048    /**
049     * Translates a {@link javax.jcr.nodetype.NodeType} to its {@link String} name.
050     */
051    public static Function<NodeType, String> nodetype2name =
052        new Function<NodeType, String>() {
053
054            @Override
055            public String apply(final NodeType t) {
056                checkNotNull(t, "null has no name!");
057                return t.getName();
058            }
059        };
060    /**
061     * Translates a JCR {@link javax.jcr.Value} to its {@link String} expression.
062     */
063    public static Function<Value, String> value2string =
064        new Function<Value, String>() {
065
066            @Override
067            public String apply(final Value v) {
068                try {
069                    checkNotNull(v, "null has no appropriate "
070                                        + "String representation!");
071                    return v.getString();
072                } catch (final RepositoryException e) {
073                    throw propagate(e);
074                }
075            }
076        };
077    /**
078     * Constructs an {@link java.util.Iterator} of {@link javax.jcr.Value}s from any
079     * {@link javax.jcr.Property}, multi-valued or not.
080     */
081    public static Function<Property, Iterator<Value>> property2values =
082        new Function<Property, Iterator<Value>>() {
083
084            @Override
085            public Iterator<Value> apply(final Property p) {
086                try {
087                    if (p.isMultiple()) {
088                        LOGGER.debug("Found multi-valued property: {}", p);
089                        return Iterators.forArray(p.getValues());
090                    }
091                    LOGGER.debug("Found single-valued property: {}", p);
092                    return Iterators.forArray(p.getValue());
093                } catch (final Exception e) {
094                    throw propagate(e);
095                }
096            }
097        };
098    /**
099     * Check if a JCR property is a multivalued property or not
100     */
101    public static Predicate<Property> isMultipleValuedProperty =
102        new Predicate<Property>() {
103
104            @Override
105            public boolean apply(final Property p) {
106                checkNotNull(p, "null is neither multiple nor not multiple!");
107                try {
108                    return p.isMultiple();
109                } catch (final RepositoryException e) {
110                    throw propagate(e);
111                }
112            }
113        };
114    /**
115     * Check if a JCR property is a binary jcr:data property
116     */
117    public static Predicate<Property> isBinaryContentProperty =
118        new Predicate<Property>() {
119
120            @Override
121            public boolean apply(final Property p) {
122                checkNotNull(p, "null is neither binary nor not binary!");
123                try {
124                    return p.getType() == BINARY && p.getName().equals(JCR_DATA);
125                } catch (final RepositoryException e) {
126                    throw propagate(e);
127                }
128            }
129        };
130    /**
131     * Predicate for determining whether this {@link javax.jcr.Node} is a frozen node
132     * (a part of the system version history).
133     */
134    public static Predicate<Node> isFrozen = new Predicate<Node>() {
135
136        @Override
137        public boolean apply(final Node node) {
138            checkNotNull(node, "null cannot be a Frozen node!");
139            try {
140                return node.isNodeType(FedoraJcrTypes.FROZEN_NODE);
141            } catch (final RepositoryException e) {
142                throw propagate(e);
143            }
144        }
145    };
146
147}