001/** 002 * Copyright 2014 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 */ 016 017package org.fcrepo.kernel.impl.rdf.impl; 018 019import com.google.common.base.Function; 020import com.google.common.base.Predicate; 021import com.google.common.collect.Iterators; 022import com.hp.hpl.jena.graph.NodeFactory; 023import com.hp.hpl.jena.graph.Triple; 024import com.hp.hpl.jena.rdf.model.RDFNode; 025import com.hp.hpl.jena.rdf.model.Resource; 026import org.fcrepo.kernel.models.NonRdfSourceDescription; 027import org.fcrepo.kernel.models.FedoraResource; 028import org.fcrepo.kernel.exception.RepositoryRuntimeException; 029import org.fcrepo.kernel.identifiers.IdentifierConverter; 030import org.fcrepo.kernel.impl.rdf.converters.ValueConverter; 031import org.fcrepo.kernel.impl.rdf.impl.mappings.PropertyValueIterator; 032import org.fcrepo.kernel.utils.iterators.PropertyIterator; 033import org.slf4j.Logger; 034 035import javax.jcr.Node; 036import javax.jcr.Property; 037import javax.jcr.RepositoryException; 038import javax.jcr.Value; 039import java.util.Iterator; 040 041import static com.google.common.collect.Iterators.singletonIterator; 042import static com.hp.hpl.jena.graph.Triple.create; 043import static com.hp.hpl.jena.rdf.model.ResourceFactory.createResource; 044import static java.util.Collections.emptyIterator; 045import static org.fcrepo.kernel.FedoraJcrTypes.LDP_BASIC_CONTAINER; 046import static org.fcrepo.kernel.FedoraJcrTypes.LDP_DIRECT_CONTAINER; 047import static org.fcrepo.kernel.FedoraJcrTypes.LDP_HAS_MEMBER_RELATION; 048import static org.fcrepo.kernel.FedoraJcrTypes.LDP_INDIRECT_CONTAINER; 049import static org.fcrepo.kernel.FedoraJcrTypes.LDP_INSERTED_CONTENT_RELATION; 050import static org.fcrepo.kernel.FedoraJcrTypes.LDP_MEMBER_RESOURCE; 051import static org.fcrepo.kernel.RdfLexicon.LDP_MEMBER; 052import static org.fcrepo.kernel.RdfLexicon.MEMBER_SUBJECT; 053import static org.fcrepo.kernel.impl.identifiers.NodeResourceConverter.nodeConverter; 054import static org.fcrepo.kernel.impl.rdf.converters.PropertyConverter.getPropertyNameFromPredicate; 055import static org.slf4j.LoggerFactory.getLogger; 056 057/** 058 * @author cabeer 059 * @since 9/25/14 060 */ 061public class LdpContainerRdfContext extends NodeRdfContext { 062 private static final Logger LOGGER = getLogger(ChildrenRdfContext.class); 063 064 /** 065 * Default constructor. 066 * 067 * @param resource 068 * @param idTranslator 069 * @throws javax.jcr.RepositoryException 070 */ 071 public LdpContainerRdfContext(final FedoraResource resource, 072 final IdentifierConverter<Resource, FedoraResource> idTranslator) 073 throws RepositoryException { 074 super(resource, idTranslator); 075 final Iterator<Property> properties = Iterators.filter(new PropertyIterator(resource.getNode().getReferences 076 (LDP_MEMBER_RESOURCE)), new Predicate<Property>() { 077 078 079 @Override 080 public boolean apply(final Property input) { 081 try { 082 final Node container = input.getParent(); 083 return container.isNodeType(LDP_DIRECT_CONTAINER) || container.isNodeType(LDP_INDIRECT_CONTAINER); 084 } catch (final RepositoryException e) { 085 throw new RepositoryRuntimeException(e); 086 } 087 } 088 }); 089 090 if (properties.hasNext()) { 091 LOGGER.trace("Found membership containers for {}", resource); 092 concat(membershipContext(properties)); 093 } 094 } 095 096 private Iterator<Triple> membershipContext(final Iterator<Property> properties) { 097 return Iterators.concat(Iterators.transform(properties, nodes2triples())); 098 } 099 100 private Function<Property, Iterator<Triple>> nodes2triples() { 101 return new Function<Property,Iterator<Triple>>() { 102 103 @Override 104 public Iterator<Triple> apply(final Property input) { 105 try { 106 final FedoraResource resource = nodeConverter.convert(input.getParent()); 107 108 return memberRelations(resource); 109 } catch (RepositoryException e) { 110 throw new RepositoryRuntimeException(e); 111 } 112 } 113 }; 114 } 115 116 /** 117 * Get the member relations assert on the subject by the given node 118 * @param container 119 * @return 120 * @throws RepositoryException 121 */ 122 private Iterator<Triple> memberRelations(final FedoraResource container) throws RepositoryException { 123 final com.hp.hpl.jena.graph.Node memberRelation; 124 125 if (container.hasProperty(LDP_HAS_MEMBER_RELATION)) { 126 final Property property = container.getProperty(LDP_HAS_MEMBER_RELATION); 127 memberRelation = NodeFactory.createURI(property.getString()); 128 } else if (container.hasType(LDP_BASIC_CONTAINER)) { 129 memberRelation = LDP_MEMBER.asNode(); 130 } else { 131 return emptyIterator(); 132 } 133 134 final String insertedContainerProperty; 135 136 if (container.hasType(LDP_INDIRECT_CONTAINER)) { 137 if (container.hasProperty(LDP_INSERTED_CONTENT_RELATION)) { 138 insertedContainerProperty = container.getProperty(LDP_INSERTED_CONTENT_RELATION).getString(); 139 } else { 140 return emptyIterator(); 141 } 142 } else { 143 insertedContainerProperty = MEMBER_SUBJECT.getURI(); 144 } 145 146 final Iterator<FedoraResource> memberNodes = container.getChildren(); 147 148 return Iterators.concat(Iterators.transform(memberNodes, new Function<FedoraResource, Iterator<Triple>>() { 149 @Override 150 public Iterator<Triple> apply(final FedoraResource child) { 151 152 try { 153 final com.hp.hpl.jena.graph.Node childSubject; 154 if (child instanceof NonRdfSourceDescription) { 155 childSubject = translator().reverse() 156 .convert(((NonRdfSourceDescription) child).getDescribedResource()) 157 .asNode(); 158 } else { 159 childSubject = translator().reverse().convert(child).asNode(); 160 } 161 162 if (insertedContainerProperty.equals(MEMBER_SUBJECT.getURI())) { 163 164 return singletonIterator(create(subject(), memberRelation, childSubject)); 165 } else { 166 167 final String insertedContentProperty = getPropertyNameFromPredicate(resource().getNode(), 168 createResource(insertedContainerProperty), 169 null); 170 171 if (!child.hasProperty(insertedContentProperty)) { 172 return emptyIterator(); 173 } 174 175 final PropertyValueIterator values 176 = new PropertyValueIterator(child.getProperty(insertedContentProperty)); 177 178 return Iterators.transform(values, new Function<Value, Triple>() { 179 @Override 180 public Triple apply(final Value input) { 181 final RDFNode membershipResource = new ValueConverter(session(), translator()) 182 .convert(input); 183 return create(subject(), memberRelation, membershipResource.asNode()); 184 } 185 }); 186 } 187 } catch (final RepositoryException e) { 188 throw new RepositoryRuntimeException(e); 189 } 190 } 191 })); 192 } 193 194}