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.modeshape.rdf.impl.mappings;
017
018import com.hp.hpl.jena.graph.Node;
019import com.hp.hpl.jena.graph.Triple;
020import com.hp.hpl.jena.rdf.model.Resource;
021import org.modeshape.jcr.api.Namespaced;
022import org.slf4j.Logger;
023
024import javax.jcr.RepositoryException;
025import javax.jcr.nodetype.ItemDefinition;
026import javax.jcr.nodetype.NodeType;
027
028import java.util.stream.Stream;
029import java.util.function.Function;
030
031import static java.util.stream.Stream.of;
032import static com.google.common.base.Throwables.propagate;
033import static com.hp.hpl.jena.graph.NodeFactory.createLiteral;
034import static com.hp.hpl.jena.graph.Triple.create;
035import static com.hp.hpl.jena.rdf.model.ResourceFactory.createProperty;
036import static com.hp.hpl.jena.vocabulary.RDF.Property;
037import static com.hp.hpl.jena.vocabulary.RDF.type;
038import static com.hp.hpl.jena.vocabulary.RDFS.domain;
039import static com.hp.hpl.jena.vocabulary.RDFS.label;
040import static org.fcrepo.kernel.modeshape.rdf.JcrRdfTools.getRDFNamespaceForJcrNamespace;
041import static org.slf4j.LoggerFactory.getLogger;
042
043
044/**
045 * Utility for moving generic Item Definitions into RDFS triples
046 * @author cbeer
047 * @author ajs6f
048 *
049 * @since Oct 2013
050 *
051 * @param <T> the property of T
052 */
053public class ItemDefinitionToTriples<T extends ItemDefinition> implements Function<T, Stream<Triple>> {
054
055    private static final Logger LOGGER = getLogger(ItemDefinitionToTriples.class);
056
057    private Node context;
058
059    /**
060     * Translate ItemDefinitions into triples. The definitions will hang off
061     * the provided RDF Node
062     * @param context the context
063     */
064    public ItemDefinitionToTriples(final Node context) {
065        this.context = context;
066    }
067
068    @Override
069    public Stream<Triple> apply(final T input) {
070
071        try {
072            final Node propertyDefinitionNode = getResource(input).asNode();
073
074            LOGGER.trace("Adding triples for nodeType: {} with child nodes: {}",
075                         context.getURI(),
076                         propertyDefinitionNode.getURI());
077
078            return of(
079                    create(propertyDefinitionNode, type.asNode(), Property.asNode()),
080                    create(propertyDefinitionNode, domain.asNode(), context),
081                    create(propertyDefinitionNode, label.asNode(), createLiteral(input.getName())));
082        } catch (final RepositoryException e) {
083            throw propagate(e);
084        }
085    }
086
087    /**
088     * Get a RDF {@link Resource} for a {@link Namespaced} JCR object.
089     * {@link Namespaced} is a Modeshape API type which is implemented by types
090     * that fulfill the JCR interfaces that represent definitions.
091     *
092     * @param namespacedObject the namespace object
093     * @return a resource for the given Namespaced JCR object
094     * @throws javax.jcr.RepositoryException if repository exception occurred
095     */
096    public static Resource getResource(final Namespaced namespacedObject)
097        throws RepositoryException {
098        // TODO find a better way to create an explicitly-namespaced resource
099        // if Jena offers one, since this isn't actually a Property
100        LOGGER.trace("Creating RDF resource for {}:{}",
101                     namespacedObject.getNamespaceURI(),
102                     namespacedObject.getLocalName());
103        return createProperty(
104                getRDFNamespaceForJcrNamespace(namespacedObject
105                        .getNamespaceURI()), namespacedObject.getLocalName())
106                .asResource();
107    }
108
109    /**
110     * Get a RDF {@link Resource} for a {@link NodeType} JCR object.
111     * {@link Namespaced} is a Modeshape API type which is implemented by types
112     * that fulfill the JCR interfaces that represent definitions.
113     *
114     * @param nodeType the node type
115     * @return a Resource for the given NodeType
116     * @throws javax.jcr.RepositoryException if repository exception occurred
117     */
118    public static Resource getResource(final NodeType nodeType) throws RepositoryException {
119        return getResource((Namespaced) nodeType);
120    }
121
122    /**
123     * Get a RDF {@link Resource} for a {@link ItemDefinition} JCR object.
124     * {@link Namespaced} is a Modeshape API type which is implemented by types
125     * that fulfill the JCR interfaces that represent definitions.
126     *
127     * @param itemDefinition the given item definition
128     * @return a resource for the given ItemDefinition
129     * @throws javax.jcr.RepositoryException if repository exception occurred
130     */
131    public static Resource getResource(final ItemDefinition itemDefinition) throws RepositoryException {
132        return getResource((Namespaced) itemDefinition);
133    }
134}