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 static com.google.common.base.Throwables.propagate;
019import static com.hp.hpl.jena.graph.NodeFactory.createLiteral;
020import static com.hp.hpl.jena.graph.Triple.create;
021import static com.hp.hpl.jena.rdf.model.ResourceFactory.createProperty;
022import static com.hp.hpl.jena.rdf.model.ResourceFactory.createTypedLiteral;
023import static org.fcrepo.kernel.api.FedoraTypes.FCR_VERSIONS;
024import static org.fcrepo.kernel.api.RdfLexicon.CREATED_DATE;
025import static org.fcrepo.kernel.api.RdfLexicon.HAS_VERSION;
026import static org.fcrepo.kernel.api.RdfLexicon.HAS_VERSION_LABEL;
027import static org.slf4j.LoggerFactory.getLogger;
028
029import java.util.Iterator;
030import java.util.function.Function;
031
032import javax.jcr.RepositoryException;
033import javax.jcr.version.Version;
034import javax.jcr.version.VersionHistory;
035import com.hp.hpl.jena.rdf.model.Resource;
036
037import org.fcrepo.kernel.api.identifiers.IdentifierConverter;
038import org.fcrepo.kernel.api.models.FedoraResource;
039import org.fcrepo.kernel.api.utils.iterators.RdfStream;
040
041import com.google.common.collect.Iterators;
042import com.hp.hpl.jena.graph.Node;
043import com.hp.hpl.jena.graph.Triple;
044
045import org.slf4j.Logger;
046
047
048/**
049 * {@link RdfStream} that supplies {@link Triple}s concerning
050 * the versions of a selected {@link Node}.
051 *
052 * @author ajs6f
053 * @since Oct 15, 2013
054 */
055public class VersionsRdfContext extends RdfStream {
056
057    private final VersionHistory versionHistory;
058
059    private final IdentifierConverter<Resource, FedoraResource> idTranslator;
060
061    private final Node subject;
062
063    private static final Logger LOGGER = getLogger(VersionsRdfContext.class);
064
065    /**
066     * Ordinary constructor.
067     *
068     * @param resource the resource
069     * @param idTranslator the id translator
070     * @throws RepositoryException if repository exception occurred
071     */
072    public VersionsRdfContext(final FedoraResource resource,
073                              final IdentifierConverter<Resource, FedoraResource> idTranslator)
074        throws RepositoryException {
075        super();
076        this.idTranslator = idTranslator;
077        this.subject = idTranslator.reverse().convert(resource).asNode();
078        versionHistory = resource.getVersionHistory();
079
080        concat(versionTriples());
081    }
082
083    @SuppressWarnings("unchecked")
084    private Iterator<Triple> versionTriples() throws RepositoryException {
085        final Iterator<Version> allVersions = versionHistory.getAllVersions();
086        return Iterators.concat(Iterators.transform(allVersions, version2triples::apply));
087    }
088
089    private final Function<Version, Iterator<Triple>> version2triples = new Function<Version, Iterator<Triple>> () {
090
091        @Override
092        public Iterator<Triple> apply(final Version version) {
093
094            try {
095                    /* Discard jcr:rootVersion */
096                if (version.getName().equals(versionHistory.getRootVersion().getName())) {
097                    LOGGER.trace("Skipped root version from triples");
098                    return new RdfStream();
099                }
100
101                final String[] labels = versionHistory.getVersionLabels(version);
102                if (labels.length == 0) {
103                    LOGGER.warn("An unlabeled version for {} was found!  Omitting from version listing!",
104                            subject.getURI());
105                    return new RdfStream();
106                } else if (labels.length > 1) {
107                    LOGGER.info("Multiple version labels found for {}!  Using first label, \"{}\".",
108                            subject.getURI(), labels[0]);
109                }
110                final Node versionSubject
111                        = createProperty(subject + "/" + FCR_VERSIONS + "/" + labels[0]).asNode();
112
113
114                final RdfStream results = new RdfStream();
115
116                results.concat(create(subject, HAS_VERSION.asNode(),
117                        versionSubject));
118
119                for (final String label : labels) {
120                    results.concat(create(versionSubject, HAS_VERSION_LABEL
121                            .asNode(), createLiteral(label)));
122                }
123                results.concat(create(versionSubject, CREATED_DATE.asNode(),
124                        createTypedLiteral(version.getCreated()).asNode()));
125
126                return results;
127
128            } catch (final RepositoryException e) {
129                throw propagate(e);
130            }
131        }
132    };
133
134
135}