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 com.google.common.collect.Iterators;
019import com.hp.hpl.jena.graph.Node;
020import com.hp.hpl.jena.rdf.model.RDFNode;
021import com.hp.hpl.jena.rdf.model.Resource;
022import org.fcrepo.kernel.api.models.FedoraResource;
023import org.fcrepo.kernel.api.identifiers.IdentifierConverter;
024import org.fcrepo.kernel.modeshape.rdf.converters.ValueConverter;
025import org.fcrepo.kernel.modeshape.rdf.impl.mappings.PropertyValueIterator;
026
027import javax.jcr.Property;
028import javax.jcr.RepositoryException;
029
030import java.util.Iterator;
031
032import static com.hp.hpl.jena.graph.NodeFactory.createURI;
033import static com.hp.hpl.jena.graph.Triple.create;
034import static com.hp.hpl.jena.rdf.model.ResourceFactory.createResource;
035import static org.fcrepo.kernel.api.FedoraTypes.LDP_DIRECT_CONTAINER;
036import static org.fcrepo.kernel.api.FedoraTypes.LDP_INDIRECT_CONTAINER;
037import static org.fcrepo.kernel.api.FedoraTypes.LDP_INSERTED_CONTENT_RELATION;
038import static org.fcrepo.kernel.api.FedoraTypes.LDP_IS_MEMBER_OF_RELATION;
039import static org.fcrepo.kernel.api.FedoraTypes.LDP_MEMBER_RESOURCE;
040import static org.fcrepo.kernel.api.RdfLexicon.MEMBER_SUBJECT;
041import static org.fcrepo.kernel.modeshape.rdf.converters.PropertyConverter.getPropertyNameFromPredicate;
042import static org.fcrepo.kernel.modeshape.rdf.impl.ReferencesRdfContext.REFERENCE_TYPES;
043
044/**
045 * @author cabeer
046 * @author ajs6f
047 * @since 10/7/14
048 */
049public class LdpIsMemberOfRdfContext extends NodeRdfContext {
050    private final ValueConverter valueConverter;
051
052    /**
053     * Default constructor.
054     *
055     * @param resource the resource
056     * @param idTranslator the id translator
057     * @throws javax.jcr.RepositoryException if repository exception
058     */
059    public LdpIsMemberOfRdfContext(final FedoraResource resource,
060                                   final IdentifierConverter<Resource, FedoraResource> idTranslator)
061            throws RepositoryException {
062        super(resource, idTranslator);
063
064        valueConverter = new ValueConverter(session(), translator());
065        final FedoraResource container = resource.getContainer();
066
067        if (container != null
068                && (container.hasType(LDP_DIRECT_CONTAINER) || container.hasType(LDP_INDIRECT_CONTAINER))
069                && container.hasProperty(LDP_IS_MEMBER_OF_RELATION)) {
070            concatIsMemberOfRelation(container);
071        }
072    }
073
074    private void concatIsMemberOfRelation(final FedoraResource container) throws RepositoryException {
075        final Property property = container.getProperty(LDP_IS_MEMBER_OF_RELATION);
076
077        final Resource memberRelation = createResource(property.getString());
078        final Node membershipResource = getMemberResource(container);
079
080        if (membershipResource == null) {
081            return;
082        }
083
084        final String insertedContainerProperty;
085
086        if (container.hasType(LDP_INDIRECT_CONTAINER)) {
087            if (container.hasProperty(LDP_INSERTED_CONTENT_RELATION)) {
088                insertedContainerProperty = container.getProperty(LDP_INSERTED_CONTENT_RELATION).getString();
089            } else {
090                return;
091            }
092        } else {
093            insertedContainerProperty = MEMBER_SUBJECT.getURI();
094        }
095
096        if (insertedContainerProperty.equals(MEMBER_SUBJECT.getURI())) {
097            concat(create(subject(), memberRelation.asNode(), membershipResource));
098        } else if (container.hasType(LDP_INDIRECT_CONTAINER)) {
099            final String insertedContentProperty = getPropertyNameFromPredicate(resource().getNode(), createResource
100                    (insertedContainerProperty), null);
101
102            if (!resource().hasProperty(insertedContentProperty)) {
103                return;
104            }
105
106            final PropertyValueIterator values
107                    = new PropertyValueIterator(resource().getProperty(insertedContentProperty));
108
109            final Iterator<RDFNode> insertedContentRelations = Iterators.filter(
110                    Iterators.transform(values, valueConverter),
111                    n -> n.isURIResource() && translator().inDomain(n.asResource()));
112
113            concat(Iterators.transform(insertedContentRelations,
114                    s -> create(s.asNode(), memberRelation.asNode(), membershipResource)));
115        }
116    }
117
118    /**
119     * Get the membership resource relation asserted by the container
120     * @param parent
121     * @return
122     * @throws RepositoryException
123     */
124    private Node getMemberResource(final FedoraResource parent) throws RepositoryException {
125        final Node membershipResource;
126
127        if (parent.hasProperty(LDP_MEMBER_RESOURCE)) {
128            final Property memberResource = parent.getProperty(LDP_MEMBER_RESOURCE);
129
130            if (REFERENCE_TYPES.contains(memberResource.getType())) {
131                membershipResource = nodeConverter().convert(memberResource.getNode()).asNode();
132            } else {
133                membershipResource = createURI(memberResource.getString());
134            }
135        } else {
136            membershipResource = uriFor(parent);
137        }
138
139        return membershipResource;
140    }
141}