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.http.commons.domain.ldp;
019
020import static java.util.Arrays.asList;
021import static java.util.Optional.ofNullable;
022import static org.fcrepo.kernel.api.RdfLexicon.EMBED_CONTAINED;
023import static org.fcrepo.kernel.api.RdfLexicon.INBOUND_REFERENCES;
024import static org.fcrepo.kernel.api.RdfLexicon.PREFER_CONTAINMENT;
025import static org.fcrepo.kernel.api.RdfLexicon.PREFER_MEMBERSHIP;
026import static org.fcrepo.kernel.api.RdfLexicon.PREFER_MINIMAL_CONTAINER;
027import static org.fcrepo.kernel.api.RdfLexicon.PREFER_SERVER_MANAGED;
028import static org.fcrepo.kernel.api.rdf.LdpTriplePreferences.PreferChoice.EXCLUDE;
029import static org.fcrepo.kernel.api.rdf.LdpTriplePreferences.PreferChoice.INCLUDE;
030
031import java.util.List;
032import java.util.Optional;
033
034import org.fcrepo.http.commons.domain.PreferTag;
035import org.fcrepo.kernel.api.rdf.LdpTriplePreferences;
036
037import org.apache.jena.rdf.model.Property;
038
039/**
040 * A subclass of {@link PreferTag} that contemplates the possible preferences for Linked Data Platform requests.
041 *
042 * @author ajs6f
043 */
044public class LdpPreferTag extends PreferTag implements LdpTriplePreferences {
045
046    private final PreferChoice minimal;
047
048    private final PreferChoice membership;
049
050    private final PreferChoice containment;
051
052    private final PreferChoice references;
053
054    private final PreferChoice embed;
055
056    private final PreferChoice managedProperties;
057
058    final List<String> includes;
059
060    final List<String> omits;
061
062    /**
063     * Standard constructor.
064     *
065     * @param preferTag the prefer tag
066     */
067    public LdpPreferTag(final PreferTag preferTag) {
068        super(preferTag);
069
070        final Optional<String> include = ofNullable(preferTag.getParams().get("include"));
071        final Optional<String> omit = ofNullable(preferTag.getParams().get("omit"));
072
073        includes = asList(include.orElse(" ").split(" "));
074        omits = asList(omit.orElse(" ").split(" "));
075
076        minimal = getChoice(PREFER_MINIMAL_CONTAINER);
077
078        membership = getChoice(PREFER_MEMBERSHIP);
079
080        containment = getChoice(PREFER_CONTAINMENT);
081
082        references = getChoice(INBOUND_REFERENCES);
083
084        embed = getChoice(EMBED_CONTAINED);
085
086        managedProperties = getChoice(PREFER_SERVER_MANAGED);
087    }
088
089    /**
090     * Determine what this tag's place in the Prefer header is.
091     * @param tag the tag to look for
092     * @return Whether the tag was included, omitted or not mentioned.
093     */
094    private PreferChoice getChoice(final Property tag) {
095        if (includes.contains(tag.toString())) {
096            return PreferChoice.INCLUDE;
097        } else if (omits.contains(tag.toString())) {
098            return PreferChoice.EXCLUDE;
099        }
100        return PreferChoice.SILENT;
101    }
102
103    @Override
104    public boolean displayUserRdf() {
105        // Displayed by default unless we asked to exclude minimal container.
106        return !minimal.equals(EXCLUDE);
107    }
108
109    @Override
110    public boolean displayMembership() {
111        // Displayed by default unless we specifically asked for it or didn't specifically ask for a minimal container
112        // AND ( we didn't exclude either managed properties or membership ).
113        return membership.equals(INCLUDE) || notIncludeMinimal() && (
114                        notExcludeManaged() && !membership.equals(EXCLUDE)
115        );
116    }
117
118    @Override
119    public boolean displayContainment() {
120        // Displayed by default unless we specifically asked for it or didn't specifically ask for a minimal container
121        // AND ( we didn't exclude either managed properties or containment ).
122        return containment.equals(INCLUDE) || notIncludeMinimal() && (
123                        notExcludeManaged() && !containment.equals(EXCLUDE)
124        );
125    }
126
127    @Override
128    public boolean displayReferences() {
129        // If we did ask for references. (Not shown by default).
130        return references.equals(INCLUDE);
131    }
132
133    @Override
134    public boolean displayEmbed() {
135        // If we did ask for embedded resources. (Not shown by default).
136        return embed.equals(INCLUDE);
137    }
138
139    @Override
140    public boolean displayServerManaged() {
141        // Displayed by default, unless excluded minimal container or managed properties.
142        return !minimal.equals(EXCLUDE) && notExcludeManaged();
143    }
144
145    /**
146     * @return whether we did not explicitly ask for a minimal container.
147     */
148    private boolean notIncludeMinimal() {
149        return !minimal.equals(INCLUDE);
150    }
151
152    /**
153     * @return whether we did not explicitly exclude managed properties.
154     */
155    private boolean notExcludeManaged() {
156        return !managedProperties.equals(EXCLUDE);
157    }
158}