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 com.google.common.collect.Iterators;
019import com.hp.hpl.jena.rdf.model.Resource;
020
021import org.fcrepo.kernel.api.exception.RepositoryRuntimeException;
022import org.fcrepo.kernel.api.models.FedoraResource;
023import org.fcrepo.kernel.api.identifiers.IdentifierConverter;
024import org.fcrepo.kernel.modeshape.rdf.impl.mappings.PropertyValueIterator;
025import org.slf4j.Logger;
026
027import javax.jcr.AccessDeniedException;
028import javax.jcr.Node;
029import javax.jcr.Property;
030import javax.jcr.RepositoryException;
031import javax.jcr.Value;
032
033import java.util.Iterator;
034import java.util.List;
035import java.util.Objects;
036import java.util.function.Function;
037
038import static java.util.Arrays.asList;
039import static org.fcrepo.kernel.api.utils.UncheckedPredicate.uncheck;
040import static org.fcrepo.kernel.modeshape.identifiers.NodeResourceConverter.nodeConverter;
041import static org.fcrepo.kernel.modeshape.rdf.converters.ValueConverter.nodeForValue;
042import static org.fcrepo.kernel.modeshape.rdf.impl.ReferencesRdfContext.REFERENCE_TYPES;
043import static org.fcrepo.kernel.modeshape.utils.FedoraTypesUtils.isSkolemNode;
044import static org.slf4j.LoggerFactory.getLogger;
045
046/**
047 * Embed triples describing all skolem nodes in the RDF stream
048 *
049 * @author cabeer
050 * @author ajs6f
051 * @since 10/9/14
052 */
053public class SkolemNodeRdfContext extends NodeRdfContext {
054
055    private static final Logger LOGGER = getLogger(SkolemNodeRdfContext.class);
056
057    private static final List<Class<? extends NodeRdfContext>> contexts =
058            asList(TypeRdfContext.class, PropertiesRdfContext.class, SkolemNodeRdfContext.class);
059    /**
060     * Default constructor.
061     *
062     * @param resource the resource
063     * @param idTranslator the idTranslator
064     * @throws javax.jcr.RepositoryException if repository exception occurred
065     */
066    public SkolemNodeRdfContext(final FedoraResource resource,
067                               final IdentifierConverter<Resource, FedoraResource> idTranslator)
068            throws RepositoryException {
069        super(resource, idTranslator);
070        concat(flatMap(getBlankNodesIterator(), n -> nodeConverter.convert(n).getTriples(idTranslator, contexts)));
071    }
072
073    @SuppressWarnings("unchecked")
074    private Iterator<Node> getBlankNodesIterator() throws RepositoryException {
075        final Iterator<Property> properties = resource().getNode().getProperties();
076
077        final Iterator<Property> references = Iterators.filter(properties,
078                uncheck((final Property p) -> REFERENCE_TYPES.contains(p.getType()))::test);
079
080        final Iterator<Node> nodes = Iterators.transform(new PropertyValueIterator(references), valueToNode::apply);
081
082        return Iterators.filter(nodes, n -> Objects.nonNull(n) && isSkolemNode.test(n));
083    }
084
085    private final Function<Value, Node> valueToNode = v -> {
086        try {
087            return nodeForValue(session(), v);
088
089        } catch (final AccessDeniedException e) {
090            LOGGER.error("Link inaccessible by requesting user: {}, {}", v, session().getUserID());
091            return null;
092
093        } catch (final RepositoryException e) {
094            throw new RepositoryRuntimeException(e);
095        }
096    };
097}