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 org.fcrepo.kernel.modeshape.identifiers.NodeResourceConverter.nodeConverter; 019import static org.fcrepo.kernel.modeshape.rdf.converters.ValueConverter.nodeForValue; 020import static javax.jcr.PropertyType.PATH; 021import static javax.jcr.PropertyType.REFERENCE; 022import static javax.jcr.PropertyType.WEAKREFERENCE; 023 024import com.google.common.base.Function; 025import com.google.common.base.Predicate; 026import com.google.common.collect.Iterators; 027import com.hp.hpl.jena.graph.Triple; 028import com.hp.hpl.jena.rdf.model.Resource; 029import org.fcrepo.kernel.api.exception.RepositoryRuntimeException; 030import org.fcrepo.kernel.api.identifiers.IdentifierConverter; 031import org.fcrepo.kernel.api.models.FedoraResource; 032import org.fcrepo.kernel.modeshape.rdf.impl.mappings.PropertyToTriple; 033import org.fcrepo.kernel.modeshape.rdf.impl.mappings.PropertyValueIterator; 034 035import javax.jcr.Node; 036import javax.jcr.Property; 037import javax.jcr.RepositoryException; 038import javax.jcr.Value; 039 040import java.util.Iterator; 041 042/** 043 * Accumulate inbound references to a given resource 044 * 045 * @author cabeer 046 * @author escowles 047 */ 048public class ReferencesRdfContext extends NodeRdfContext { 049 050 private final PropertyToTriple property2triple; 051 052 /** 053 * Add the inbound references from other nodes to this resource to the stream 054 * 055 * @param resource the resource 056 * @param idTranslator the id translator 057 * @throws RepositoryException if repository exception occurred 058 */ 059 060 public ReferencesRdfContext(final FedoraResource resource, 061 final IdentifierConverter<Resource, FedoraResource> idTranslator) 062 throws RepositoryException { 063 super(resource, idTranslator); 064 property2triple = new PropertyToTriple(resource.getNode().getSession(), idTranslator); 065 putReferencesIntoContext(resource.getNode()); 066 } 067 068 private void putReferencesIntoContext(final Node node) throws RepositoryException { 069 concat(Iterators.concat(Iterators.transform( 070 Iterators.concat(node.getReferences(), node.getWeakReferences()), property2triple))); 071 concat(Iterators.concat(Iterators.transform(Iterators.concat(Iterators.transform( 072 Iterators.concat(node.getReferences(), node.getWeakReferences()), potentialProxies)), triplesForValue))); 073 } 074 075 /* References from LDP indirect containers are generated dynamically by LdpContainerRdfContext, so they won't 076 show up in getReferences()/getWeakReferences(). Instead, we should check referrers to see if they are 077 members of an IndirectContainer and generate the appropriate inbound references. */ 078 private Function<Property, Iterator<Value>> potentialProxies = new Function<Property, Iterator<Value>>() { 079 @Override 080 public Iterator<Value> apply(final Property p) { 081 try { 082 return Iterators.filter(new PropertyValueIterator(p.getParent().getProperties()), isReference); 083 } catch (RepositoryException ex) { 084 throw new RepositoryRuntimeException(ex); 085 } 086 } 087 }; 088 private Function<Value, Iterator<Triple>> triplesForValue = new Function<Value, Iterator<Triple>>() { 089 @Override 090 public Iterator<Triple> apply(final Value v) { 091 try { 092 return new LdpContainerRdfContext(nodeConverter.convert(nodeForValue(session(), v)), translator()); 093 } catch (RepositoryException ex) { 094 throw new RepositoryRuntimeException(ex); 095 } 096 } 097 }; 098 private Predicate<Value> isReference = new Predicate<Value>() { 099 @Override 100 public boolean apply(final Value v) { 101 return v.getType() == PATH || v.getType() == REFERENCE || v.getType() == WEAKREFERENCE; 102 } 103 }; 104 105}