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 the resource
051     * @param idTranslator the id translator
052     * @throws RepositoryException if repository exception occurred
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
068        if (primaryNodeType != null) {
069            nodeTypesB.add(primaryNodeType);
070        }
071
072        try {
073            final Set<NodeType> primarySupertypes = ImmutableSet.<NodeType>builder()
074                    .add(primaryNodeType.getSupertypes()).build();
075            nodeTypesB.addAll(primarySupertypes);
076        } catch (NullPointerException e) {
077            // ignore
078        }
079
080        final NodeType[] mixinNodeTypesArr = resource().getNode().getMixinNodeTypes();
081
082        if (mixinNodeTypesArr != null) {
083            final Set<NodeType> mixinNodeTypes = ImmutableSet.<NodeType>builder().add(mixinNodeTypesArr).build();
084            nodeTypesB.addAll(mixinNodeTypes);
085
086            final ImmutableSet.Builder<NodeType> mixinSupertypes = ImmutableSet.<NodeType>builder();
087            for (final NodeType mixinNodeType : mixinNodeTypes) {
088                mixinSupertypes.addAll(ImmutableSet.<NodeType>builder().add(mixinNodeType.getSupertypes()).build());
089            }
090
091            nodeTypesB.addAll(mixinSupertypes.build());
092        }
093
094        final ImmutableList<NodeType> nodeTypes = nodeTypesB.build();
095        final Iterator<NodeType> nodeTypesIt = nodeTypes.iterator();
096
097        concat(Iterators.transform(nodeTypesIt, nodetype2triple()));
098    }
099
100    private Function<NodeType, Triple> nodetype2triple() {
101        return new Function<NodeType, Triple>() {
102
103            @Override
104            public Triple apply(final NodeType nodeType) {
105                try {
106                    final String name = nodeType.getName();
107                    final String prefix = name.split(":")[0];
108                    final String typeName = name.split(":")[1];
109                    final String namespace = getJcrUri(prefix);
110                    final com.hp.hpl.jena.graph.Node rdfType =
111                            createURI(getRDFNamespaceForJcrNamespace(namespace)
112                                    + typeName);
113                    LOGGER.trace("Translating mixin: {} w/ namespace: {} into resource: {}", name, namespace, rdfType);
114                    return create(subject(), type.asNode(), rdfType);
115                } catch (final RepositoryException e) {
116                    throw propagate(e);
117                }
118            }
119
120        };
121    }
122
123    private String getJcrUri(final String prefix) throws RepositoryException {
124        return resource().getNode().getSession().getWorkspace().getNamespaceRegistry()
125                .getURI(prefix);
126    }
127
128}