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