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.camel;
019
020import static java.util.Arrays.stream;
021import static java.util.Collections.emptyList;
022import static java.util.stream.Collectors.toList;
023import static org.slf4j.LoggerFactory.getLogger;
024
025import java.net.URI;
026import java.util.HashMap;
027import java.util.List;
028import java.util.Map;
029
030import org.slf4j.Logger;
031
032/**
033 * A class representing the value of an HTTP Prefer header
034 *
035 * @author Aaron Coburn
036 */
037public class FcrepoPrefer {
038
039    private static final Logger LOGGER = getLogger(FcrepoPrefer.class);
040
041    private static final String LINK_DELIM = "\\s*;\\s*";
042
043    private static final String OMIT = "omit";
044
045    private static final String INCLUDE = "include";
046
047    private String returnType = null;
048
049    private List<URI> omit;
050
051    private List<URI> include;
052
053    /**
054     * Create a representation of a Prefer header.
055     *
056     * @param prefer the value for a Prefer header
057     */
058    public FcrepoPrefer(final String prefer) {
059        parse(prefer);
060    }
061
062    /**
063     * Whether a minimal representation has been requested
064     * @return whether this is a minimal request
065     */
066    public boolean isMinimal() {
067        return returnType != null && returnType.equals("minimal");
068    }
069
070    /**
071     * Whether a non-minimal representation has been requested
072     * @return whether this is a non-minimal request
073     */
074    public boolean isRepresentation() {
075        return returnType != null && returnType.equals("representation");
076    }
077
078    /**
079     * Retrieve the omit portion of a Prefer header
080     *
081     * @return the omit portion of a Prefer header
082     */
083    public List<URI> getOmit() {
084        return omit;
085    }
086
087    /**
088     * Retrieve the include portion of the prefer header
089     *
090     * @return the include portion of a Prefer header
091     */
092    public List<URI> getInclude() {
093        return include;
094    }
095
096    /**
097     * Parse the value of a prefer header
098     */
099    private void parse(final String prefer) {
100        if (prefer != null) {
101            final Map<String, String> data = new HashMap<>();
102
103            for (final String section : prefer.split(LINK_DELIM)) {
104                final String[] parts = section.split("=");
105                if (parts.length == 2) {
106                    final String value;
107                    if (parts[1].startsWith("\"") && parts[1].endsWith("\"")) {
108                        value = parts[1].substring(1, parts[1].length() - 1);
109                    } else {
110                        value = parts[1];
111                    }
112                    data.put(parts[0], value);
113                }
114            }
115            this.returnType = data.get("return");
116            this.include = getUris(data.get(INCLUDE));
117            this.omit = getUris(data.get(OMIT));
118        } else {
119            LOGGER.warn("Could not parse a null Prefer value");
120        }
121    }
122
123    private List<URI> getUris(final String uris) {
124        if (uris != null) {
125            return stream(uris.split("\\s+")).filter(uri -> uri.length() > 0).map(URI::create).collect(toList());
126        }
127        return emptyList();
128    }
129}