001/*
002 * The contents of this file are subject to the license and copyright
003 * detailed in the LICENSE and NOTICE files at the root of the source
004 * tree.
005 */
006package org.fcrepo.kernel.impl.models;
007
008import org.apache.jena.graph.Node;
009import org.apache.jena.graph.Triple;
010import org.fcrepo.kernel.api.RdfStream;
011import org.fcrepo.kernel.api.Transaction;
012import org.fcrepo.kernel.api.cache.UserTypesCache;
013import org.fcrepo.kernel.api.exception.PathNotFoundException;
014import org.fcrepo.kernel.api.exception.PathNotFoundRuntimeException;
015import org.fcrepo.kernel.api.identifiers.FedoraId;
016import org.fcrepo.kernel.api.models.FedoraResource;
017import org.fcrepo.kernel.api.models.NonRdfSourceDescription;
018import org.fcrepo.kernel.api.models.ResourceFactory;
019import org.fcrepo.kernel.api.rdf.DefaultRdfStream;
020import org.fcrepo.persistence.api.PersistentStorageSessionManager;
021
022import java.net.URI;
023import java.util.List;
024import java.util.stream.Stream;
025
026import static org.apache.jena.graph.NodeFactory.createURI;
027import static org.fcrepo.kernel.api.RdfLexicon.RDF_SOURCE;
028
029/**
030 * Implementation of a non-rdf source description
031 *
032 * @author bbpennel
033 */
034public class NonRdfSourceDescriptionImpl extends FedoraResourceImpl implements NonRdfSourceDescription {
035
036    private static final URI RDF_SOURCE_URI = URI.create(RDF_SOURCE.getURI());
037
038    /**
039     * Construct a description resource
040     *
041     * @param fedoraID internal identifier
042     * @param transaction transaction
043     * @param pSessionManager session manager
044     * @param resourceFactory resource factory
045     * @param userTypesCache the user types cache
046     */
047    public NonRdfSourceDescriptionImpl(final FedoraId fedoraID,
048                                       final Transaction transaction,
049                                       final PersistentStorageSessionManager pSessionManager,
050                                       final ResourceFactory resourceFactory,
051                                       final UserTypesCache userTypesCache) {
052        super(fedoraID, transaction, pSessionManager, resourceFactory, userTypesCache);
053    }
054
055    @Override
056    public String getId() {
057        return getFedoraId().getResourceId();
058    }
059
060    @Override
061    public FedoraResource getDescribedResource() {
062        // Get a FedoraId for the binary
063        FedoraId describedId = getFedoraId().asBaseId();
064        if (getFedoraId().isMemento()) {
065            describedId = describedId.asMemento(getFedoraId().getMementoInstant());
066        }
067        try {
068            return this.resourceFactory.getResource(transaction, describedId);
069        } catch (final PathNotFoundException e) {
070            throw new PathNotFoundRuntimeException(e.getMessage(), e);
071        }
072    }
073
074    @Override
075    public List<URI> getSystemTypes(final boolean forRdf) {
076        var types = resolveSystemTypes(forRdf);
077
078        if (types == null) {
079            types = super.getSystemTypes(forRdf);
080            // NonRdfSource gets the ldp:Resource and adds ldp:RDFSource types.
081            types.add(RDF_SOURCE_URI);
082        }
083
084        return types;
085    }
086
087    @Override
088    public RdfStream getTriples() {
089        // Remap the subject to the described resource
090        // TODO: With FCREPO-3819 and FCREPO-3820, this will no longer be necessary.
091        //       But existing sites might have RDF with NonRdfSourceDescription subjects, so leave it for now.
092        final Node describedID = createURI(this.getDescribedResource().getId());
093        final Stream<Triple> triples = super.getTriples().map(t -> {
094            if (t.getSubject().hasURI(this.getId())) {
095                return new Triple(describedID, t.getPredicate(), t.getObject());
096            } else {
097                return t;
098            }
099        });
100        return new DefaultRdfStream(describedID, triples);
101    }
102}