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