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;
017
018import static com.google.common.collect.ImmutableList.copyOf;
019import static com.google.common.collect.Iterators.forArray;
020import static com.hp.hpl.jena.graph.NodeFactory.createLiteral;
021import static com.hp.hpl.jena.graph.Triple.create;
022import static com.hp.hpl.jena.vocabulary.RDF.type;
023import static com.hp.hpl.jena.vocabulary.RDFS.Class;
024import static com.hp.hpl.jena.vocabulary.RDFS.label;
025import static com.hp.hpl.jena.vocabulary.RDFS.subClassOf;
026import static org.fcrepo.kernel.modeshape.rdf.impl.mappings.ItemDefinitionToTriples.getResource;
027import static org.fcrepo.kernel.modeshape.utils.UncheckedFunction.uncheck;
028import static org.slf4j.LoggerFactory.getLogger;
029
030import java.util.Iterator;
031import java.util.function.Predicate;
032
033import com.google.common.collect.Collections2;
034import com.google.common.collect.Iterators;
035import com.hp.hpl.jena.graph.Node;
036
037import org.fcrepo.kernel.modeshape.rdf.impl.mappings.NodeDefinitionToTriples;
038import org.fcrepo.kernel.modeshape.rdf.impl.mappings.PropertyDefinitionToTriples;
039import org.fcrepo.kernel.api.utils.iterators.RdfStream;
040
041import org.slf4j.Logger;
042
043import javax.jcr.RepositoryException;
044import javax.jcr.nodetype.ItemDefinition;
045import javax.jcr.nodetype.NodeType;
046import javax.jcr.nodetype.NodeTypeManager;
047
048/**
049 * Assemble {@link com.hp.hpl.jena.graph.Triple}s derived from the {@link NodeType}s in a repository.
050 *
051 * @author cbeer
052 */
053public class NodeTypeRdfContext extends RdfStream {
054
055    private static final Logger LOGGER = getLogger(NodeTypeRdfContext.class);
056
057    private static final Predicate<ItemDefinition> isWildcardResidualDefinition = x -> x.getName().equals("*");
058
059    /**
060     * Convert the NodeTypeManager to an RDF stream, including both primary and
061     * mixin node types.
062     *
063     * @param nodeTypeManager the node type manager
064     * @throws RepositoryException if repository exception occurred
065     */
066    @SuppressWarnings("unchecked")
067    public NodeTypeRdfContext(final NodeTypeManager nodeTypeManager) throws RepositoryException {
068        super();
069
070        concat(new NodeTypeRdfContext(nodeTypeManager.getPrimaryNodeTypes()));
071        concat(new NodeTypeRdfContext(nodeTypeManager.getMixinNodeTypes()));
072    }
073
074    /**
075     * Convert a NodeType iterator into an RDF stream
076     *
077     * @param nodeTypeIterator the node type iterator
078     * @throws RepositoryException if repository exception occurred
079     */
080    public NodeTypeRdfContext(final Iterator<NodeType> nodeTypeIterator)
081        throws RepositoryException {
082        super();
083
084        while (nodeTypeIterator.hasNext()) {
085            concat(new NodeTypeRdfContext(nodeTypeIterator.next()));
086        }
087    }
088
089    /**
090     * Convert a NodeType into an RDF stream by capturing the supertypes, node
091     * definitions, and property definitions of the type as RDFS triples.
092     *
093     * @param nodeType the node type
094     * @throws RepositoryException if repository exception occurred
095     */
096    public NodeTypeRdfContext(final NodeType nodeType)
097        throws RepositoryException {
098        super();
099
100        final Node nodeTypeResource = getResource(nodeType).asNode();
101        final String nodeTypeName = nodeType.getName();
102
103        LOGGER.trace("Adding triples for nodeType: {} with URI: {}",
104                nodeTypeName, nodeTypeResource.getURI());
105
106        concat(Collections2.transform(copyOf(nodeType.getDeclaredSupertypes()),
107                    uncheck((final NodeType x) -> {
108                        final Node supertypeNode = getResource(x).asNode();
109                        LOGGER.trace(
110                                "Adding triple for nodeType: {} with subclass: {}",
111                                nodeTypeName, supertypeNode.getURI());
112                        return create(nodeTypeResource,
113                                subClassOf.asNode(), supertypeNode);
114                    })::apply));
115
116        concat(Iterators.concat(
117            Iterators.transform(Iterators.filter(
118                forArray(nodeType.getDeclaredChildNodeDefinitions()),
119                isWildcardResidualDefinition.negate()::test),
120                (new NodeDefinitionToTriples(nodeTypeResource))::apply)));
121
122        concat(Iterators.concat(
123            Iterators.transform(Iterators.filter(
124                forArray(nodeType.getDeclaredPropertyDefinitions()),
125                isWildcardResidualDefinition.negate()::test),
126                (new PropertyDefinitionToTriples(nodeTypeResource))::apply)));
127
128        concat(create(nodeTypeResource, type.asNode(), Class.asNode()), create(
129                nodeTypeResource, label.asNode(), createLiteral(nodeTypeName)));
130    }
131
132
133}