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 com.google.common.base.Function;
019import com.google.common.collect.ImmutableList;
020import com.google.common.collect.ImmutableSet;
021import com.google.common.collect.Iterators;
022import com.hp.hpl.jena.graph.Triple;
023import com.hp.hpl.jena.rdf.model.Resource;
024import org.fcrepo.kernel.models.FedoraResource;
025import org.fcrepo.kernel.identifiers.IdentifierConverter;
026import org.slf4j.Logger;
027
028import javax.jcr.RepositoryException;
029import javax.jcr.nodetype.NodeType;
030import java.util.Iterator;
031import java.util.Set;
032
033import static com.google.common.base.Throwables.propagate;
034import static com.hp.hpl.jena.graph.NodeFactory.createURI;
035import static com.hp.hpl.jena.graph.Triple.create;
036import static com.hp.hpl.jena.vocabulary.RDF.type;
037import static org.fcrepo.kernel.impl.rdf.JcrRdfTools.getRDFNamespaceForJcrNamespace;
038import static org.slf4j.LoggerFactory.getLogger;
039
040/**
041 * @author cabeer
042 * @since 10/1/14
043 */
044public class TypeRdfContext extends NodeRdfContext {
045    private static final Logger LOGGER = getLogger(TypeRdfContext.class);
046
047    /**
048     * Default constructor.
049     *
050     * @param resource
051     * @param idTranslator
052     * @throws javax.jcr.RepositoryException
053     */
054    public TypeRdfContext(final FedoraResource resource,
055                          final IdentifierConverter<Resource, FedoraResource> idTranslator)
056            throws RepositoryException {
057        super(resource, idTranslator);
058
059        //include rdf:type for primaryType, mixins, and their supertypes
060        concatRdfTypes();
061    }
062
063    private void concatRdfTypes() throws RepositoryException {
064        final ImmutableList.Builder<NodeType> nodeTypesB = ImmutableList.<NodeType>builder();
065
066        final NodeType primaryNodeType = resource().getNode().getPrimaryNodeType();
067        nodeTypesB.add(primaryNodeType);
068
069        if (primaryNodeType != null && primaryNodeType.getSupertypes() != null) {
070            final Set<NodeType> primarySupertypes = ImmutableSet.<NodeType>builder()
071                    .add(primaryNodeType.getSupertypes()).build();
072            nodeTypesB.addAll(primarySupertypes);
073        }
074
075        final NodeType[] mixinNodeTypesArr = resource().getNode().getMixinNodeTypes();
076
077        if (mixinNodeTypesArr != null) {
078            final Set<NodeType> mixinNodeTypes = ImmutableSet.<NodeType>builder().add(mixinNodeTypesArr).build();
079            nodeTypesB.addAll(mixinNodeTypes);
080
081            final ImmutableSet.Builder<NodeType> mixinSupertypes = ImmutableSet.<NodeType>builder();
082            for (final NodeType mixinNodeType : mixinNodeTypes) {
083                mixinSupertypes.addAll(ImmutableSet.<NodeType>builder().add(mixinNodeType.getSupertypes()).build());
084            }
085
086            nodeTypesB.addAll(mixinSupertypes.build());
087        }
088
089        final ImmutableList<NodeType> nodeTypes = nodeTypesB.build();
090        final Iterator<NodeType> nodeTypesIt = nodeTypes.iterator();
091
092        concat(Iterators.transform(nodeTypesIt, nodetype2triple()));
093    }
094
095    private Function<NodeType, Triple> nodetype2triple() {
096        return new Function<NodeType, Triple>() {
097
098            @Override
099            public Triple apply(final NodeType nodeType) {
100                try {
101                    final String fullTypeName = nodeType.getName();
102                    LOGGER.trace("Translating JCR mixin name: {}", fullTypeName);
103                    final String prefix = fullTypeName.split(":")[0];
104                    final String typeName = fullTypeName.split(":")[1];
105                    final String namespace = getJcrUri(prefix);
106                    LOGGER.trace("with JCR namespace: {}", namespace);
107                    final com.hp.hpl.jena.graph.Node rdfType =
108                            createURI(getRDFNamespaceForJcrNamespace(namespace)
109                                    + typeName);
110                    LOGGER.trace("into RDF resource: {}", rdfType);
111                    return create(subject(), type.asNode(), rdfType);
112                } catch (final RepositoryException e) {
113                    throw propagate(e);
114                }
115            }
116
117        };
118    }
119
120    private String getJcrUri(final String prefix) throws RepositoryException {
121        return resource().getNode().getSession().getWorkspace().getNamespaceRegistry()
122                .getURI(prefix);
123    }
124
125}