001/*
002 * Licensed to DuraSpace under one or more contributor license agreements.
003 * See the NOTICE file distributed with this work for additional information
004 * regarding copyright ownership.
005 *
006 * DuraSpace licenses this file to you under the Apache License,
007 * Version 2.0 (the "License"); you may not use this file except in
008 * compliance with the License.  You may obtain a copy of the License at
009 *
010 *     http://www.apache.org/licenses/LICENSE-2.0
011 *
012 * Unless required by applicable law or agreed to in writing, software
013 * distributed under the License is distributed on an "AS IS" BASIS,
014 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
015 * See the License for the specific language governing permissions and
016 * limitations under the License.
017 */
018package org.fcrepo.kernel.modeshape.rdf.impl.mappings;
019
020import com.hp.hpl.jena.graph.Node;
021import com.hp.hpl.jena.graph.Triple;
022import com.hp.hpl.jena.rdf.model.Resource;
023import org.modeshape.jcr.api.Namespaced;
024import org.slf4j.Logger;
025
026import javax.jcr.RepositoryException;
027import javax.jcr.nodetype.ItemDefinition;
028import javax.jcr.nodetype.NodeType;
029
030import java.util.stream.Stream;
031import java.util.function.Function;
032
033import static java.util.stream.Stream.of;
034import static com.google.common.base.Throwables.propagate;
035import static com.hp.hpl.jena.graph.NodeFactory.createLiteral;
036import static com.hp.hpl.jena.graph.Triple.create;
037import static com.hp.hpl.jena.rdf.model.ResourceFactory.createProperty;
038import static com.hp.hpl.jena.vocabulary.RDF.Property;
039import static com.hp.hpl.jena.vocabulary.RDF.type;
040import static com.hp.hpl.jena.vocabulary.RDFS.domain;
041import static com.hp.hpl.jena.vocabulary.RDFS.label;
042import static org.fcrepo.kernel.modeshape.rdf.JcrRdfTools.getRDFNamespaceForJcrNamespace;
043import static org.slf4j.LoggerFactory.getLogger;
044
045
046/**
047 * Utility for moving generic Item Definitions into RDFS triples
048 * @author cbeer
049 * @author ajs6f
050 *
051 * @since Oct 2013
052 *
053 * @param <T> the property of T
054 */
055public class ItemDefinitionToTriples<T extends ItemDefinition> implements Function<T, Stream<Triple>> {
056
057    private static final Logger LOGGER = getLogger(ItemDefinitionToTriples.class);
058
059    private Node context;
060
061    /**
062     * Translate ItemDefinitions into triples. The definitions will hang off
063     * the provided RDF Node
064     * @param context the context
065     */
066    public ItemDefinitionToTriples(final Node context) {
067        this.context = context;
068    }
069
070    @Override
071    public Stream<Triple> apply(final T input) {
072
073        try {
074            final Node propertyDefinitionNode = getResource(input).asNode();
075
076            LOGGER.trace("Adding triples for nodeType: {} with child nodes: {}",
077                         context.getURI(),
078                         propertyDefinitionNode.getURI());
079
080            return of(
081                    create(propertyDefinitionNode, type.asNode(), Property.asNode()),
082                    create(propertyDefinitionNode, domain.asNode(), context),
083                    create(propertyDefinitionNode, label.asNode(), createLiteral(input.getName())));
084        } catch (final RepositoryException e) {
085            throw propagate(e);
086        }
087    }
088
089    /**
090     * Get a RDF {@link Resource} for a {@link Namespaced} JCR object.
091     * {@link Namespaced} is a Modeshape API type which is implemented by types
092     * that fulfill the JCR interfaces that represent definitions.
093     *
094     * @param namespacedObject the namespace object
095     * @return a resource for the given Namespaced JCR object
096     * @throws javax.jcr.RepositoryException if repository exception occurred
097     */
098    public static Resource getResource(final Namespaced namespacedObject)
099        throws RepositoryException {
100        // TODO find a better way to create an explicitly-namespaced resource
101        // if Jena offers one, since this isn't actually a Property
102        LOGGER.trace("Creating RDF resource for {}:{}",
103                     namespacedObject.getNamespaceURI(),
104                     namespacedObject.getLocalName());
105        return createProperty(
106                getRDFNamespaceForJcrNamespace(namespacedObject
107                        .getNamespaceURI()), namespacedObject.getLocalName())
108                .asResource();
109    }
110
111    /**
112     * Get a RDF {@link Resource} for a {@link NodeType} JCR object.
113     * {@link Namespaced} is a Modeshape API type which is implemented by types
114     * that fulfill the JCR interfaces that represent definitions.
115     *
116     * @param nodeType the node type
117     * @return a Resource for the given NodeType
118     * @throws javax.jcr.RepositoryException if repository exception occurred
119     */
120    public static Resource getResource(final NodeType nodeType) throws RepositoryException {
121        return getResource((Namespaced) nodeType);
122    }
123
124    /**
125     * Get a RDF {@link Resource} for a {@link ItemDefinition} JCR object.
126     * {@link Namespaced} is a Modeshape API type which is implemented by types
127     * that fulfill the JCR interfaces that represent definitions.
128     *
129     * @param itemDefinition the given item definition
130     * @return a resource for the given ItemDefinition
131     * @throws javax.jcr.RepositoryException if repository exception occurred
132     */
133    public static Resource getResource(final ItemDefinition itemDefinition) throws RepositoryException {
134        return getResource((Namespaced) itemDefinition);
135    }
136}