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.routing;
018
019import static org.forgerock.http.routing.Version.version;
020
021import org.forgerock.services.context.Context;
022import org.forgerock.services.context.AbstractContext;
023import org.forgerock.json.JsonValue;
024
025/**
026 * A {@link Context} which is created when a request is and has been routed
027 * based on resource API version. The context includes:
028 * <ul>
029 *     <li>the default version behaviour, if the request does not contain a
030 *     resource API version</li>
031 *     <li>whether a warning is issued to the client, if the request does not
032 *     contain a resource API version</li>
033 *     <li>the API version of the framework that was used to handle the request</li>
034 *     <li>the API version of the resource that was routed to</li>
035 * </ul>
036 */
037public class ApiVersionRouterContext extends AbstractContext {
038
039    private static final String DEFAULT_VERSION_BEHAVIOUR = "defaultVersionBehaviour";
040    private static final String WARNING_ENABLED = "warningEnabled";
041
042    private Version protocolVersion;
043    private Version resourceVersion;
044
045    /**
046     * Creates a new resource API version routing context having the provided
047     * parent, default versioning behaviour and whether warnings will be
048     * issued.
049     *
050     * @param parent The parent context.
051     * @param defaultVersionBehaviour The default version behaviour.
052     * @param warningEnabled Whether warnings will be issued to the client.
053     */
054    public ApiVersionRouterContext(Context parent, DefaultVersionBehaviour defaultVersionBehaviour,
055            boolean warningEnabled) {
056        this(parent);
057        if (defaultVersionBehaviour != null) {
058            data.put(DEFAULT_VERSION_BEHAVIOUR, defaultVersionBehaviour.toString());
059        }
060        data.put(WARNING_ENABLED, warningEnabled);
061    }
062
063    /**
064     * Restore from JSON representation.
065     *
066     * @param savedContext The JSON representation from which this context's
067     *                     attributes should be parsed.
068     * @param classLoader The {@code ClassLoader} which can properly resolve
069     *                    the persisted class-name.
070     */
071    public ApiVersionRouterContext(JsonValue savedContext, ClassLoader classLoader) {
072        super(savedContext, classLoader);
073        if (data.isDefined("protocolVersion")) {
074            this.protocolVersion = version(data.get("protocolVersion").asString());
075        }
076        if (data.isDefined("resourceVersion")) {
077            this.protocolVersion = version(data.get("resourceVersion").asString());
078        }
079    }
080
081    /**
082     * Creates a new resource API version routing context having the provided
083     * parent.
084     *
085     * @param parent The parent context.
086     */
087    ApiVersionRouterContext(Context parent) {
088        super(parent, "apiVersionRouter");
089    }
090
091    /**
092     * Gets the default version behaviour if the request does not contain a
093     * resource API version.
094     *
095     * @return The default version behaviour.
096     */
097    public DefaultVersionBehaviour getDefaultVersionBehaviour() {
098        if (data.isDefined(DEFAULT_VERSION_BEHAVIOUR) && data.get(DEFAULT_VERSION_BEHAVIOUR).isNotNull()) {
099            return data.get(DEFAULT_VERSION_BEHAVIOUR).asEnum(DefaultVersionBehaviour.class);
100        } else {
101            return null;
102        }
103    }
104
105    /**
106     * Gets whether a warning should be issued to the calling client if the
107     * request does not contain a resource API version.
108     *
109     * @return {@code true} if warnings should be issued to the client.
110     */
111    public boolean isWarningEnabled() {
112        return data.get(WARNING_ENABLED).defaultTo(true).asBoolean();
113    }
114
115    /**
116     * Sets the protocol API version of the framework used to handle the request.
117     *
118     * @param protocolVersion The framework protocol API version.
119     */
120    public void setProtocolVersion(Version protocolVersion) {
121        this.protocolVersion = protocolVersion;
122        data.put("protocolVersion", protocolVersion.toString());
123    }
124
125    /**
126     * Gets the protocol API version of the framework used to handle the request.
127     *
128     * @return The framework protocol API version.
129     */
130    public Version getProtocolVersion() {
131        return protocolVersion;
132    }
133
134    /**
135     * Sets the API version of the resource that the request was routed to.
136     *
137     * @param resourceVersion The resource API version.
138     */
139    void setResourceVersion(Version resourceVersion) {
140        this.resourceVersion = resourceVersion;
141        data.put("resourceVersion", resourceVersion.toString());
142    }
143
144    /**
145     * Gets the API version of the resource that the request was routed to.
146     *
147     * @return The resource API version.
148     */
149    public Version getResourceVersion() {
150        return resourceVersion;
151    }
152}