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