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 2012-2016 ForgeRock AS.
015 */
016
017package org.forgerock.json.resource.http;
018
019import static org.forgerock.json.resource.http.HttpUtils.*;
020
021import java.net.URI;
022
023import org.forgerock.json.resource.CrestApplication;
024import org.forgerock.services.context.Context;
025import org.forgerock.http.Filter;
026import org.forgerock.http.Handler;
027import org.forgerock.http.filter.Filters;
028import org.forgerock.http.handler.Handlers;
029import org.forgerock.json.resource.ConnectionFactory;
030import org.forgerock.json.resource.RequestHandler;
031import org.forgerock.json.resource.Resources;
032import org.forgerock.util.Reject;
033
034/**
035 * <p>A CREST HTTP utility class which creates instances of the {@link HttpAdapter}
036 * to handle CREST HTTP requests.</p>
037 *
038 * <p>Instances must be provided with a {@code ConnectionFactory} in order to
039 * operate and optionally a {@code HttpContextFactory}.</p>
040 */
041public final class CrestHttp {
042
043    private CrestHttp() {
044    }
045
046    /**
047     * Creates a new JSON resource HTTP Handler with the provided connection
048     * factory and no context factory.
049     *
050     * @param connectionFactory
051     *            The connection factory.
052     * @return A CREST HTTP {@code Handler}.
053     * @deprecated Use {@link #newHttpHandler(CrestApplication)} instead.
054     */
055    @Deprecated
056    @SuppressWarnings("deprecation")
057    public static Handler newHttpHandler(ConnectionFactory connectionFactory) {
058        Reject.ifNull(connectionFactory);
059        return Handlers.chainOf(new HttpAdapter(connectionFactory), newOptionsFilter());
060    }
061
062    /**
063     * Creates a new JSON resource HTTP Handler with the provided connection
064     * factory and a context factory which will always return the provided
065     * request context.
066     *
067     * @param connectionFactory
068     *            The connection factory.
069     * @param parentContext
070     *            The parent request context which should be used as the parent
071     *            context of each request context.
072     * @return A HTTP Handler.
073     * @deprecated Use {@link #newHttpHandler(CrestApplication)} instead.
074     */
075    @Deprecated
076    @SuppressWarnings("deprecation")
077    public static Handler newHttpHandler(ConnectionFactory connectionFactory, Context parentContext) {
078        Reject.ifNull(connectionFactory);
079        Reject.ifNull(parentContext);
080        return Handlers.chainOf(new HttpAdapter(connectionFactory, parentContext), newOptionsFilter());
081    }
082
083    /**
084     * Creates a new JSON resource HTTP Handler with the provided connection
085     * factory and context factory.
086     *
087     * @param connectionFactory
088     *            The connection factory.
089     * @param contextFactory
090     *            The context factory which will be used to obtain the parent
091     *            context of each request context.
092     * @return A HTTP Handler.
093     * @deprecated Use {@link #newHttpHandler(CrestApplication)} instead.
094     */
095    @Deprecated
096    @SuppressWarnings("deprecation")
097    public static Handler newHttpHandler(ConnectionFactory connectionFactory, HttpContextFactory contextFactory) {
098        Reject.ifNull(connectionFactory);
099        Reject.ifNull(contextFactory);
100        return Handlers.chainOf(new HttpAdapter(connectionFactory, contextFactory), newOptionsFilter());
101    }
102
103    /**
104     * Creates a new JSON resource HTTP handler with the provided CREST request handler.
105     *
106     * @param handler The {@link RequestHandler}.
107     * @return A HTTP Handler.
108     * @deprecated Use {@link #newHttpHandler(CrestApplication)} instead.
109     */
110    @Deprecated
111    @SuppressWarnings("deprecation")
112    public static Handler newHttpHandler(RequestHandler handler) {
113        Reject.ifNull(handler);
114        return Handlers.chainOf(new HttpAdapter(Resources.newInternalConnectionFactory(handler)), newOptionsFilter());
115    }
116
117    /**
118     * Creates a new JSON resource HTTP handler with the provided CREST request handler.
119     *
120     * @param application The application.
121     * @return The handler
122     */
123    public static Handler newHttpHandler(CrestApplication application) {
124        Reject.ifNull(application);
125        return Handlers.chainOf(new HttpAdapter(application, null), newOptionsFilter());
126    }
127
128    /**
129     * Creates a new JSON resource HTTP handler with the provided CREST request handler.
130     *
131     * @param application The application.
132     * @param factory A factory for creating parent HTTP Contexts.
133     * @return The handler
134     */
135    public static Handler newHttpHandler(CrestApplication application, HttpContextFactory factory) {
136        Reject.ifNull(application);
137        return Handlers.chainOf(new HttpAdapter(application, factory), newOptionsFilter());
138    }
139
140    /**
141     * Creates a new JSON resource HTTP handler with the provided CREST request handler.
142     *
143     * @param application The application.
144     * @param context The parent context to use for all contexts.
145     * @return The handler
146     */
147    public static Handler newHttpHandler(CrestApplication application, Context context) {
148        Reject.ifNull(application);
149        return Handlers.chainOf(new HttpAdapter(application, staticContextFactory(context)), newOptionsFilter());
150    }
151
152    /**
153     * Creates a new {@link RequestHandler} that map back and forth JSON resource objects to CHF objects.
154     *
155     * @param handler
156     *         HTTP {@link Handler} responsible for emitting the HTTP request build from JSON resource {@link
157     *         org.forgerock.json.resource.Request}s.
158     * @param uri
159     *         base URI used to build the target URI for built HTTP message
160     * @return a JSON resource {@link RequestHandler}
161     */
162    public static RequestHandler newRequestHandler(Handler handler, final URI uri) {
163        return new CrestAdapter(handler, uri);
164    }
165
166    /**
167     * Creates a new {@link ConnectionFactory} that map back and forth JSON resource objects to CHF objects.
168     * <p>
169     * Convenience method. Note that ConnectionFactory is going to be removed soon, so you may not need this.
170     *
171     * @param handler
172     *         HTTP {@link Handler} responsible for emitting the HTTP request build from JSON resource {@link
173     *         org.forgerock.json.resource.Request}s.
174     * @param uri
175     *         base URI used to build the target URI for built HTTP message
176     * @return a JSON resource {@link RequestHandler}
177     */
178    public static ConnectionFactory newConnectionFactory(Handler handler, final URI uri) {
179        return Resources.newInternalConnectionFactory(newRequestHandler(handler, uri));
180    }
181
182    private static Filter newOptionsFilter() {
183        return Filters.newOptionsFilter(METHOD_DELETE,
184                                        METHOD_GET,
185                                        METHOD_HEAD,
186                                        METHOD_PATCH,
187                                        METHOD_PUT,
188                                        METHOD_OPTIONS,
189                                        METHOD_TRACE);
190    }
191}