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