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.http.commons.responses;
017
018import static com.google.common.collect.ImmutableList.copyOf;
019import static com.google.common.collect.Iterables.transform;
020import static com.hp.hpl.jena.graph.NodeFactory.createURI;
021import static com.hp.hpl.jena.rdf.model.ResourceFactory.createProperty;
022import static com.hp.hpl.jena.rdf.model.ResourceFactory.createResource;
023import static org.fcrepo.kernel.RdfLexicon.JCR_NAMESPACE;
024import static org.fcrepo.kernel.impl.rdf.JcrRdfTools.getRDFNamespaceForJcrNamespace;
025import static org.slf4j.LoggerFactory.getLogger;
026
027import java.util.Iterator;
028
029import com.google.common.base.Function;
030import com.google.common.collect.ImmutableList;
031import com.hp.hpl.jena.graph.Node;
032import com.hp.hpl.jena.rdf.model.Model;
033import com.hp.hpl.jena.rdf.model.NodeIterator;
034import com.hp.hpl.jena.rdf.model.RDFNode;
035import org.slf4j.Logger;
036
037/**
038 * Utilities to help with serializing a graph to an HTTP resource
039 *
040 * @author awoods
041 */
042public final class RdfSerializationUtils {
043
044    private static final Logger LOGGER = getLogger(RdfSerializationUtils.class);
045
046    /**
047     * No public constructor on utility class
048     */
049    private RdfSerializationUtils() {
050    }
051
052    /**
053     * The RDF predicate that will indicate the primary node type.
054     */
055    public static Node primaryTypePredicate =
056            createURI(getRDFNamespaceForJcrNamespace(JCR_NAMESPACE) +
057                    "primaryType");
058
059    /**
060     * The RDF predicate that will indicate the mixin types.
061     */
062    public static Node mixinTypesPredicate =
063        createURI(getRDFNamespaceForJcrNamespace(JCR_NAMESPACE) +
064                  "mixinTypes");
065
066    private static final Function<RDFNode, String> stringConverter = new Function<RDFNode, String>() {
067        @Override
068        public String apply(final RDFNode node) {
069            return node.asLiteral().getLexicalForm();
070        }
071    };
072
073    /**
074     * Get the very first value for a predicate as a string, or null if the
075     * predicate is not used
076     *
077     * @param rdf the rdf
078     * @param subject the given subject
079     * @param predicate the given predicate
080     * @return first value for the given predicate or null if not found
081     */
082    public static String getFirstValueForPredicate(final Model rdf,
083            final Node subject, final Node predicate) {
084        final NodeIterator statements = rdf.listObjectsOfProperty(createResource(subject.getURI()),
085                createProperty(predicate.getURI()));
086        // we'll take the first one we get
087        if (statements.hasNext()) {
088            return statements.next().asLiteral().getLexicalForm();
089        }
090        LOGGER.trace("No value found for predicate: {}", predicate);
091        return null;
092    }
093
094    /**
095     * Get all the values for a predicate as a string array, or null if the
096     * predicate is not used
097     *
098     * @param rdf the rdf
099     * @param subject the given subject
100     * @param predicate the given predicate
101     * @return all values for the given predicate
102     */
103    public static Iterator<String> getAllValuesForPredicate(final Model rdf,
104            final Node subject, final Node predicate) {
105        final NodeIterator objects =
106            rdf.listObjectsOfProperty(createResource(subject.getURI()),
107                createProperty(predicate.getURI()));
108
109        final ImmutableList<RDFNode> copy = copyOf(objects);
110        return transform(copy, stringConverter).iterator();
111    }
112
113}