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.services;
007
008import static org.apache.jena.datatypes.xsd.XSDDatatype.XSDlong;
009import static org.apache.jena.datatypes.xsd.impl.XSDDateTimeType.XSDdateTime;
010import static org.apache.jena.graph.NodeFactory.createLiteral;
011import static org.apache.jena.graph.NodeFactory.createURI;
012import static org.apache.jena.vocabulary.RDF.type;
013import static org.fcrepo.kernel.api.RdfLexicon.CREATED_BY;
014import static org.fcrepo.kernel.api.RdfLexicon.CREATED_DATE;
015import static org.fcrepo.kernel.api.RdfLexicon.HAS_MESSAGE_DIGEST;
016import static org.fcrepo.kernel.api.RdfLexicon.HAS_MIME_TYPE;
017import static org.fcrepo.kernel.api.RdfLexicon.HAS_ORIGINAL_NAME;
018import static org.fcrepo.kernel.api.RdfLexicon.HAS_SIZE;
019import static org.fcrepo.kernel.api.RdfLexicon.LAST_MODIFIED_BY;
020import static org.fcrepo.kernel.api.RdfLexicon.LAST_MODIFIED_DATE;
021
022import java.util.ArrayList;
023import java.util.List;
024import java.util.stream.Stream;
025
026import org.apache.jena.graph.Triple;
027import org.fcrepo.kernel.api.models.Binary;
028import org.fcrepo.kernel.api.models.FedoraResource;
029import org.fcrepo.kernel.api.models.TimeMap;
030import org.fcrepo.kernel.api.models.Tombstone;
031import org.fcrepo.kernel.api.rdf.DefaultRdfStream;
032import org.fcrepo.kernel.api.services.ManagedPropertiesService;
033import org.springframework.stereotype.Component;
034
035/**
036 * Retrieve the managed properties as triples
037 *
038 * @author dbernstein
039 * @since 2020-01-07
040 */
041@Component
042public class ManagedPropertiesServiceImpl implements ManagedPropertiesService {
043
044    @Override
045    public Stream<Triple> get(final FedoraResource resource) {
046        final List<Triple> triples = new ArrayList<>();
047
048        final var describedResource = resource.getDescribedResource();
049        final var subject = createURI(resolveId(describedResource));
050
051        var createdBy = resource.getCreatedBy();
052        var createdDate = resource.getCreatedDate();
053        var lastModifiedBy = resource.getLastModifiedBy();
054        var lastModifiedDate = resource.getLastModifiedDate();
055
056        if (createdDate == null && resource.getOriginalResource() instanceof Tombstone) {
057            final var deletedResource = ((Tombstone)resource.getOriginalResource()).getDeletedObject();
058            createdBy = deletedResource.getCreatedBy();
059            createdDate = deletedResource.getCreatedDate();
060            lastModifiedBy = deletedResource.getLastModifiedBy();
061            lastModifiedDate = deletedResource.getLastModifiedDate();
062        }
063
064        if (describedResource instanceof Binary) {
065            final Binary binary = (Binary) describedResource;
066
067            createdBy = binary.getCreatedBy();
068            createdDate = binary.getCreatedDate();
069            lastModifiedBy = binary.getLastModifiedBy();
070            lastModifiedDate = binary.getLastModifiedDate();
071
072            triples.add(Triple.create(subject, HAS_SIZE.asNode(),
073                    createLiteral(String.valueOf(binary.getContentSize()), XSDlong)));
074            if (binary.getFilename() != null) {
075                triples.add(Triple.create(subject, HAS_ORIGINAL_NAME.asNode(), createLiteral(binary.getFilename())));
076            }
077            if (binary.getMimeType() != null) {
078                triples.add(Triple.create(subject, HAS_MIME_TYPE.asNode(), createLiteral(binary.getMimeType())));
079            }
080            if (binary.getContentDigests() != null) {
081                for (var digest : binary.getContentDigests()) {
082                    triples.add(Triple.create(subject, HAS_MESSAGE_DIGEST.asNode(),
083                            createURI(digest.toString())));
084                }
085
086            }
087        }
088
089        triples.add(Triple.create(subject, CREATED_DATE.asNode(),
090                                  createLiteral(createdDate.toString(), XSDdateTime)));
091        triples.add(Triple.create(subject, LAST_MODIFIED_DATE.asNode(),
092                                  createLiteral(lastModifiedDate.toString(), XSDdateTime)));
093        if (createdBy != null) {
094            triples.add(Triple.create(subject, CREATED_BY.asNode(), createLiteral(createdBy)));
095        }
096        if (lastModifiedBy != null) {
097            triples.add(Triple.create(subject, LAST_MODIFIED_BY.asNode(), createLiteral(lastModifiedBy)));
098        }
099
100        describedResource.getSystemTypes(true).forEach(triple -> {
101            triples.add(Triple.create(subject, type.asNode(), createURI(triple.toString())));
102        });
103
104        return new DefaultRdfStream(subject, triples.stream());
105    }
106
107    private String resolveId(final FedoraResource resource) {
108        if (resource instanceof TimeMap) {
109            return resource.getFedoraId().getFullId();
110        }
111        return resource.getId();
112    }
113
114}