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-2015 ForgeRock AS.
015 */
016
017package org.forgerock.json.resource;
018
019import java.util.List;
020import java.util.Map;
021
022import org.forgerock.http.routing.Version;
023import org.forgerock.json.JsonPointer;
024import org.forgerock.json.JsonValue;
025import org.forgerock.util.i18n.PreferredLocales;
026
027/**
028 * Common attributes of all JSON resource requests.
029 */
030public interface Request {
031
032    // TODO: many of these fields are not used by action requests. Perhaps they
033    // should be pushed down? For example, a bulk update operation would not use
034    // any of these parameters.
035
036    // TODO: include support for something similar to LDAP controls?
037
038    /**
039     * The name of the field which contains the additional query parameters in the JSON representation.
040     */
041    String FIELD_ADDITIONAL_PARAMETERS = "additionalParameters";
042    /**
043     * The name of the field which contains the fields in the JSON representation.
044     */
045    String FIELD_FIELDS = "fields";
046    /**
047     * The name of the field which contains the resource name in the JSON representation.
048     */
049    String FIELD_RESOURCE_PATH = "resourcePath";
050
051    /**
052     * Applies a {@code RequestVisitor} to this {@code Request}.
053     *
054     * @param <R>
055     *         The return type of the visitor's methods.
056     * @param <P>
057     *         The type of the additional parameters to the visitor's methods.
058     * @param v
059     *         The request visitor.
060     * @param p
061     *         Optional additional visitor parameter.
062     * @return A result as specified by the visitor.
063     */
064    <R, P> R accept(final RequestVisitor<R, P> v, final P p);
065
066    /**
067     * Adds one or more fields which should be included with each JSON resource returned by this request.
068     *
069     * @param fields
070     *         The fields which should be included with each JSON resource returned by this request.
071     * @return This request.
072     * @throws UnsupportedOperationException
073     *         If this request does not permit changes to the fields.
074     */
075    Request addField(JsonPointer... fields);
076
077    /**
078     * Adds one or more fields which should be included with each JSON resource returned by this request.
079     *
080     * @param fields
081     *         The fields which should be included with each JSON resource returned by this request.
082     * @return This request.
083     * @throws IllegalArgumentException
084     *         If one or more of the provided field identifiers could not be parsed as a JSON pointer.
085     * @throws UnsupportedOperationException
086     *         If this request does not permit changes to the fields.
087     */
088    Request addField(String... fields);
089
090    /**
091     * Returns the additional parameter which should be used to control the behavior of this action request.
092     *
093     * @param name
094     *         The name of the additional parameter.
095     * @return The additional parameter which should be used to control the behavior of this action request
096     */
097    String getAdditionalParameter(String name);
098
099    /**
100     * Returns the additional parameters which should be used to control the behavior of this action request. The
101     * returned map may be modified if permitted by this action request.
102     *
103     * @return The additional parameters which should be used to control the behavior of this action request (never
104     * {@code null}).
105     */
106    Map<String, String> getAdditionalParameters();
107
108    /**
109     * Returns the list of fields which should be included with each JSON resource returned by this request. The
110     * returned list may be modified if permitted by this query request. An empty list indicates that all fields should
111     * be included.
112     * <p>
113     * <b>NOTE:</b> field filtering alters the structure of a JSON resource and MUST only be performed once while
114     * processing a request. It is therefore the responsibility of front-end implementations (e.g. HTTP listeners,
115     * Servlets, etc) to perform field filtering. Request handler and resource provider implementations SHOULD NOT
116     * filter fields, but MAY choose to optimise their processing in order to return a resource containing only the
117     * fields targeted by the field filters.
118     *
119     * @return The list of fields which should be included with each JSON resource returned by this request (never
120     * {@code null}).
121     */
122    List<JsonPointer> getFields();
123
124    /**
125     * Get the locale preference for the request.
126     *
127     * @return The {@code PreferredLocales} instance for the request.
128     */
129    PreferredLocales getPreferredLocales();
130
131    /**
132     * Returns the type of this request.
133     *
134     * @return The type of this request.
135     */
136    RequestType getRequestType();
137
138    /**
139     * Returns the non-{@code null} path of the JSON resource to which this request should be targeted. The resource
140     * path is relative and never begins or ends with a forward slash, but may be empty.
141     * <p>
142     * <b>NOTE</b>: for resource provider implementations the resource path is relative to the current resource being
143     * accessed. See the description of {@link org.forgerock.http.routing.UriRouterContext} for more information.
144     *
145     * @return The non-{@code null} path of the JSON resource to which this request should be targeted, which may be the
146     * empty string.
147     */
148    String getResourcePath();
149
150    /**
151     * Returns the non-{@code null} path of the JSON resource to which this request should be targeted. The resource
152     * path is relative and never begins or ends with a forward slash, but may be empty.
153     * <p>
154     * <b>NOTE</b>: for resource provider implementations the resource path is relative to the current resource being
155     * accessed. See the description of {@link org.forgerock.http.routing.UriRouterContext} for more information.
156     *
157     * @return The non-{@code null} path of the JSON resource to which this request should be targeted, which may be the
158     * empty string.
159     */
160    ResourcePath getResourcePathObject();
161
162    /**
163     * Gets the requested API version of the resource.
164     *
165     * @return The requested API version of the resource.
166     */
167    Version getResourceVersion();
168
169    /**
170     * Sets an additional parameter which should be used to control the behavior of this action request.
171     *
172     * @param name
173     *         The name of the additional parameter.
174     * @param value
175     *         The additional parameter's value.
176     * @return This request.
177     * @throws BadRequestException
178     *         If this request does not permit the additional parameter to be set.
179     * @throws UnsupportedOperationException
180     *         If this request does not permit changes to the additional parameters.
181     */
182    Request setAdditionalParameter(String name, String value) throws BadRequestException;
183
184    /**
185     * Set the locale preference for the request.
186     *
187     * @param preferredLocales
188     *         The {@code PreferredLocales} instance for the request.
189     * @return This request.
190     */
191    Request setPreferredLocales(PreferredLocales preferredLocales);
192
193    /**
194     * Sets the non-{@code null} path of the JSON resource to which this request should be targeted. The resource path
195     * is relative and never begins or ends with a forward slash, but may be empty.
196     * <p>
197     * <b>NOTE</b>: for resource provider implementations the resource path is relative to the current resource being
198     * accessed. See the description of {@link org.forgerock.http.routing.UriRouterContext} for more information.
199     *
200     * @param path
201     *         The non-{@code null} path of the JSON resource to which this request should be targeted, which may be the
202     *         empty string. The path should be URL-encoded.
203     * @return This request.
204     * @throws UnsupportedOperationException
205     *         If this request does not permit changes to the JSON resource path.
206     */
207    Request setResourcePath(String path);
208
209    /**
210     * Sets the non-{@code null} path of the JSON resource to which this request should be targeted. The resource path
211     * is relative and never begins or ends with a forward slash, but may be empty.
212     * <p>
213     * <b>NOTE</b>: for resource provider implementations the resource path is relative to the current resource being
214     * accessed. See the description of {@link org.forgerock.http.routing.UriRouterContext} for more information.
215     *
216     * @param path
217     *         The non-{@code null} path of the JSON resource to which this request should be targeted, which may be the
218     *         empty string.
219     * @return This request.
220     * @throws UnsupportedOperationException
221     *         If this request does not permit changes to the JSON resource path.
222     */
223    Request setResourcePath(ResourcePath path);
224
225    /**
226     * Sets the requested API version of the resource.
227     *
228     * @param resourceVersion
229     *         The requested API version of the resource.
230     * @return This request.
231     */
232    Request setResourceVersion(Version resourceVersion);
233
234    /**
235     * Return a JsonValue representation of this request.
236     *
237     * @return this request as a JsonValue
238     */
239    JsonValue toJsonValue();
240}