001/*
002 * The contents of this file are subject to the terms of the Common Development and
003 * Distribution License (the License). You may not use this file except in compliance with the
004 * License.
005 *
006 * You can obtain a copy of the License at legal/CDDLv1.0.txt. See the License for the
007 * specific language governing permission and limitations under the License.
008 *
009 * When distributing Covered Software, include this CDDL Header Notice in each file and include
010 * the License file at legal/CDDLv1.0.txt. If applicable, add the following below the CDDL
011 * Header, with the fields enclosed by brackets [] replaced by your own identifying
012 * information: "Portions copyright [year] [name of copyright owner]".
013 *
014 * Copyright 2015 ForgeRock AS.
015 */
016
017package org.forgerock.http.header;
018
019import static java.util.Collections.*;
020import static org.forgerock.http.header.HeaderUtil.*;
021
022import java.util.List;
023
024import org.forgerock.http.protocol.Header;
025import org.forgerock.http.protocol.Message;
026import org.forgerock.http.routing.Version;
027import org.forgerock.util.Pair;
028import org.forgerock.util.Reject;
029
030/**
031 * Processes the <strong>{@code Content-API-Version}</strong> message header.
032 * Represents the protocol and resource versions of the returned content.
033 */
034public final class ContentApiVersionHeader extends Header {
035
036    /**
037     * Constructs a new header, initialized from the specified message.
038     *
039     * @param message The message to initialize the header from.
040     * @return The parsed header.
041     */
042    public static ContentApiVersionHeader valueOf(Message message) {
043        String headerValue = parseSingleValuedHeader(message, NAME);
044        return valueOf(headerValue);
045    }
046
047    /**
048     * Constructs a new header, initialized from the specified string.
049     *
050     * @param headerValue The value to initialize the header from.
051     * @return The parsed header.
052     */
053    public static ContentApiVersionHeader valueOf(String headerValue) {
054        Pair<Version, Version> parsedValue = AcceptApiVersionHeader.parse(headerValue);
055        return new ContentApiVersionHeader(parsedValue.getFirst(), parsedValue.getSecond());
056    }
057
058    /** The name of this header. */
059    public static final String NAME = "Content-API-Version";
060    private static final String PROTOCOL = "protocol";
061    private static final String RESOURCE = "resource";
062
063    private final Version protocolVersion;
064    private final Version resourceVersion;
065
066    /**
067     * Constructs a new header, initialized with the specified protocol and
068     * resource versions.
069     *
070     * @param protocolVersion The protocol version of the content of the
071     *                        returned content.
072     * @param resourceVersion The resource version of the returned content.
073     */
074    public ContentApiVersionHeader(Version protocolVersion, Version resourceVersion) {
075        Reject.ifNull(resourceVersion);
076        this.protocolVersion = protocolVersion;
077        this.resourceVersion = resourceVersion;
078    }
079
080    @Override
081    public String getName() {
082        return NAME;
083    }
084
085    /**
086     * Gets the protocol version of the content of the returned content.
087     *
088     * @return The protocol version of the content of the returned content.
089     */
090    public Version getProtocolVersion() {
091        return protocolVersion;
092    }
093
094    /**
095     * Gets the resource version of the returned content.
096     *
097     * @return The resource version of the returned content.
098     */
099    public Version getResourceVersion() {
100        return resourceVersion;
101    }
102
103    @Override
104    public List<String> getValues() {
105        if (protocolVersion == null) {
106            return singletonList(String.format(RESOURCE + "=%s", resourceVersion));
107        } else {
108            return singletonList(String.format(PROTOCOL + "=%s," + RESOURCE + "=%s", protocolVersion, resourceVersion));
109        }
110    }
111
112    static class Factory extends AbstractSingleValuedHeaderFactory<ContentApiVersionHeader> {
113
114        @Override
115        public ContentApiVersionHeader parse(String value) {
116            return valueOf(value);
117        }
118    }
119}