001/* 002 * Licensed to DuraSpace under one or more contributor license agreements. 003 * See the NOTICE file distributed with this work for additional information 004 * regarding copyright ownership. 005 * 006 * DuraSpace licenses this file to you under the Apache License, 007 * Version 2.0 (the "License"); you may not use this file except in 008 * compliance with the License. You may obtain a copy of the License at 009 * 010 * http://www.apache.org/licenses/LICENSE-2.0 011 * 012 * Unless required by applicable law or agreed to in writing, software 013 * distributed under the License is distributed on an "AS IS" BASIS, 014 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 015 * See the License for the specific language governing permissions and 016 * limitations under the License. 017 */ 018package org.fcrepo.kernel.modeshape.rdf.impl; 019 020import static org.apache.jena.graph.NodeFactory.createLiteral; 021import static org.apache.jena.graph.Triple.create; 022import static org.apache.jena.rdf.model.ResourceFactory.createProperty; 023import static org.apache.jena.rdf.model.ResourceFactory.createTypedLiteral; 024import static org.fcrepo.kernel.api.FedoraTypes.FCR_VERSIONS; 025import static org.fcrepo.kernel.api.RdfLexicon.CREATED_DATE; 026import static org.fcrepo.kernel.api.RdfLexicon.HAS_VERSION; 027import static org.fcrepo.kernel.api.RdfLexicon.HAS_VERSION_LABEL; 028import static org.fcrepo.kernel.modeshape.utils.StreamUtils.iteratorToStream; 029import static org.fcrepo.kernel.modeshape.utils.UncheckedPredicate.uncheck; 030import static org.slf4j.LoggerFactory.getLogger; 031 032import java.util.Arrays; 033import java.util.stream.Stream; 034 035import javax.jcr.RepositoryException; 036import javax.jcr.version.Version; 037import javax.jcr.version.VersionHistory; 038import org.apache.jena.rdf.model.Resource; 039 040import org.fcrepo.kernel.api.identifiers.IdentifierConverter; 041import org.fcrepo.kernel.api.models.FedoraResource; 042import org.fcrepo.kernel.api.rdf.DefaultRdfStream; 043import org.fcrepo.kernel.modeshape.utils.UncheckedFunction; 044 045import org.apache.jena.graph.Node; 046import org.apache.jena.graph.Triple; 047 048import org.slf4j.Logger; 049 050 051/** 052 * {@link org.fcrepo.kernel.api.RdfStream} that supplies {@link Triple}s concerning 053 * the versions of a selected {@link Node}. 054 * 055 * @author ajs6f 056 * @since Oct 15, 2013 057 */ 058public class VersionsRdfContext extends DefaultRdfStream { 059 060 private final VersionHistory versionHistory; 061 062 private static final Logger LOGGER = getLogger(VersionsRdfContext.class); 063 064 /** 065 * Ordinary constructor. 066 * 067 * @param resource the resource 068 * @param idTranslator the id translator 069 * @throws RepositoryException if repository exception occurred 070 */ 071 public VersionsRdfContext(final FedoraResource resource, 072 final IdentifierConverter<Resource, FedoraResource> idTranslator) 073 throws RepositoryException { 074 super(idTranslator.reverse().convert(resource).asNode()); 075 this.versionHistory = resource.getVersionHistory(); 076 concat(versionTriples()); 077 } 078 079 @SuppressWarnings("unchecked") 080 private Stream<Triple> versionTriples() throws RepositoryException { 081 return iteratorToStream(versionHistory.getAllVersions()) 082 /* Discard jcr:rootVersion */ 083 .filter(uncheck((final Version v) -> !v.getName().equals(versionHistory.getRootVersion().getName()))) 084 /* Omit unlabelled versions */ 085 .filter(uncheck((final Version v) -> { 086 final String[] labels = versionHistory.getVersionLabels(v); 087 if (labels.length == 0) { 088 LOGGER.warn("An unlabeled version for {} was found! Omitting from version listing!", 089 topic().getURI()); 090 } else if (labels.length > 1) { 091 LOGGER.info("Multiple version labels found for {}! Using first label, \"{}\".", topic().getURI()); 092 } 093 return labels.length > 0; 094 })) 095 .flatMap(UncheckedFunction.uncheck((final Version v) -> { 096 final String[] labels = versionHistory.getVersionLabels(v); 097 final Node versionSubject 098 = createProperty(topic() + "/" + FCR_VERSIONS + "/" + labels[0]).asNode(); 099 100 return Stream.concat( 101 Arrays.stream(labels).map(x -> create(versionSubject, HAS_VERSION_LABEL.asNode(), 102 createLiteral(x))), 103 104 Stream.of(create(topic(), HAS_VERSION.asNode(), versionSubject), 105 create(versionSubject, CREATED_DATE.asNode(), 106 createTypedLiteral(v.getCreated()).asNode()))); 107 })); 108 } 109}