Return-Path: X-Original-To: archive-asf-public-internal@cust-asf2.ponee.io Delivered-To: archive-asf-public-internal@cust-asf2.ponee.io Received: from cust-asf.ponee.io (cust-asf.ponee.io [163.172.22.183]) by cust-asf2.ponee.io (Postfix) with ESMTP id 0C51C200C6D for ; Sun, 7 May 2017 22:16:31 +0200 (CEST) Received: by cust-asf.ponee.io (Postfix) id 0AB2F160BC5; Sun, 7 May 2017 20:16:31 +0000 (UTC) Delivered-To: archive-asf-public@cust-asf.ponee.io Received: from mail.apache.org (hermes.apache.org [140.211.11.3]) by cust-asf.ponee.io (Postfix) with SMTP id D61F1160BB1 for ; Sun, 7 May 2017 22:16:28 +0200 (CEST) Received: (qmail 59528 invoked by uid 500); 7 May 2017 20:16:28 -0000 Mailing-List: contact commits-help@juneau.incubator.apache.org; run by ezmlm Precedence: bulk List-Help: List-Unsubscribe: List-Post: List-Id: Reply-To: dev@juneau.incubator.apache.org Delivered-To: mailing list commits@juneau.incubator.apache.org Received: (qmail 59519 invoked by uid 99); 7 May 2017 20:16:28 -0000 Received: from pnap-us-west-generic-nat.apache.org (HELO spamd4-us-west.apache.org) (209.188.14.142) by apache.org (qpsmtpd/0.29) with ESMTP; Sun, 07 May 2017 20:16:28 +0000 Received: from localhost (localhost [127.0.0.1]) by spamd4-us-west.apache.org (ASF Mail Server at spamd4-us-west.apache.org) with ESMTP id 8C4BDC02CA for ; Sun, 7 May 2017 20:16:27 +0000 (UTC) X-Virus-Scanned: Debian amavisd-new at spamd4-us-west.apache.org X-Spam-Flag: NO X-Spam-Score: -4.222 X-Spam-Level: X-Spam-Status: No, score=-4.222 tagged_above=-999 required=6.31 tests=[KAM_ASCII_DIVIDERS=0.8, RCVD_IN_DNSWL_HI=-5, RCVD_IN_MSPIKE_H3=-0.01, RCVD_IN_MSPIKE_WL=-0.01, RP_MATCHES_RCVD=-0.001, SPF_PASS=-0.001] autolearn=disabled Received: from mx1-lw-us.apache.org ([10.40.0.8]) by localhost (spamd4-us-west.apache.org [10.40.0.11]) (amavisd-new, port 10024) with ESMTP id xqfO5K6Blq8g for ; Sun, 7 May 2017 20:16:15 +0000 (UTC) Received: from mail.apache.org (hermes.apache.org [140.211.11.3]) by mx1-lw-us.apache.org (ASF Mail Server at mx1-lw-us.apache.org) with SMTP id 92DB45FBA1 for ; Sun, 7 May 2017 20:16:14 +0000 (UTC) Received: (qmail 59458 invoked by uid 99); 7 May 2017 20:16:14 -0000 Received: from git1-us-west.apache.org (HELO git1-us-west.apache.org) (140.211.11.23) by apache.org (qpsmtpd/0.29) with ESMTP; Sun, 07 May 2017 20:16:14 +0000 Received: by git1-us-west.apache.org (ASF Mail Server at git1-us-west.apache.org, from userid 33) id EEE38E00A3; Sun, 7 May 2017 20:16:13 +0000 (UTC) Content-Type: text/plain; charset="us-ascii" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit From: jamesbognar@apache.org To: commits@juneau.incubator.apache.org Date: Sun, 07 May 2017 20:16:14 -0000 Message-Id: In-Reply-To: <48bfc05f979c4bee9517131fd1d3f467@git.apache.org> References: <48bfc05f979c4bee9517131fd1d3f467@git.apache.org> X-Mailer: ASF-Git Admin Mailer Subject: [2/3] incubator-juneau git commit: Break up RestRequest into different functional classes. archived-at: Sun, 07 May 2017 20:16:31 -0000 http://git-wip-us.apache.org/repos/asf/incubator-juneau/blob/321f6bde/juneau-rest/src/main/java/org/apache/juneau/rest/RequestHeaders.java ---------------------------------------------------------------------- diff --git a/juneau-rest/src/main/java/org/apache/juneau/rest/RequestHeaders.java b/juneau-rest/src/main/java/org/apache/juneau/rest/RequestHeaders.java new file mode 100644 index 0000000..b0617bd --- /dev/null +++ b/juneau-rest/src/main/java/org/apache/juneau/rest/RequestHeaders.java @@ -0,0 +1,675 @@ +// *************************************************************************************************************************** +// * Licensed to the Apache Software Foundation (ASF) under one or more contributor license agreements. See the NOTICE file * +// * distributed with this work for additional information regarding copyright ownership. The ASF licenses this file * +// * to you under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance * +// * with the License. You may obtain a copy of the License at * +// * * +// * http://www.apache.org/licenses/LICENSE-2.0 * +// * * +// * Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an * +// * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the * +// * specific language governing permissions and limitations under the License. * +// *************************************************************************************************************************** +package org.apache.juneau.rest; + +import java.lang.reflect.*; +import java.util.*; + +import org.apache.juneau.*; +import org.apache.juneau.http.*; +import org.apache.juneau.http.Date; +import org.apache.juneau.internal.*; +import org.apache.juneau.parser.*; +import org.apache.juneau.urlencoding.*; + +/** + * Represents the headers in an HTTP request. + *

+ * Entries are stored in a case-insensitive map. + */ +public class RequestHeaders extends TreeMap { + private static final long serialVersionUID = 1L; + + private UrlEncodingParser parser; + private BeanSession beanSession; + private RequestQuery queryParams; + + RequestHeaders() { + super(String.CASE_INSENSITIVE_ORDER); + } + + RequestHeaders setParser(UrlEncodingParser parser) { + this.parser = parser; + return this; + } + + RequestHeaders setBeanSession(BeanSession beanSession) { + this.beanSession = beanSession; + return this; + } + + RequestHeaders setQueryParams(RequestQuery queryParams) { + this.queryParams = queryParams; + return this; + } + + /** + * Adds default entries to these headers. + *

+ * This includes the default headers defined on the servlet and method levels. + * + * @param defaultEntries The default entries. Can be null. + * @return This object (for method chaining). + */ + public RequestHeaders addDefault(Map defaultEntries) { + if (defaultEntries != null) { + for (Map.Entry e : defaultEntries.entrySet()) { + String key = e.getKey(), value = e.getValue(); + String[] v = get(key); + if (v == null) + put(key, new String[]{value}); + } + } + return this; + } + + /** + * Adds a set of header values to this object. + * + * @param name The header name. + * @param values The header values. + * @return This object (for method chaining). + */ + public RequestHeaders put(String name, Enumeration values) { + // Optimized for enumerations of one entry, the most-common case. + if (values.hasMoreElements()) { + String v = values.nextElement(); + if (! v.isEmpty()) { + String[] s = new String[]{v}; + while (values.hasMoreElements()) + s = ArrayUtils.append(s, values.nextElement()); + put(name, s); + } + } + return this; + } + + /** + * Returns the specified header value, or null if the header doesn't exist. + *

+ * If {@code allowHeaderParams} init parameter is true, then first looks for {@code &HeaderName=x} in the URL query string. + *

+ * @param name The header name. + * @return The header value, or null if it doesn't exist. + */ + public String getFirst(String name) { + return getFirst(name, null); + } + + /** + * Returns the specified header value, or a default value if the header doesn't exist. + *

+ * If {@code allowHeaderParams} init parameter is true, then first looks for {@code &HeaderName=x} in the URL query string. + * + * @param name The HTTP header name. + * @param def The default value to return if the header value isn't found. + * @return The header value, or the default value if the header isn't present. + */ + public String getFirst(String name, String def) { + String[] v = null; + if (queryParams != null) + v = queryParams.get(name); + if (v == null || v.length == 0) + v = get(name); + if (v == null || v.length == 0) + return def; + return v[0]; + } + + /** + * Sets a request header value. + * + * @param name The header name. + * @param value The header value. + */ + public void put(String name, Object value) { + super.put(name, new String[]{StringUtils.toString(value)}); + } + + /** + * Returns the specified header value converted to a POJO. + *

+ * The type can be any POJO type convertable from a String + * (See POJOs Convertable From Strings). + *

+ *

Examples:
+ *

+ * // Parse into an integer. + * int myheader = req.getHeader("My-Header", int.class); + * + * // Parse a UUID. + * UUID myheader = req.getHeader("My-Header", UUID.class); + *

+ * + * @param name The HTTP header name. + * @param type The class type to convert the header value to. + * @param The class type to convert the header value to. + * @return The parameter value converted to the specified class type. + */ + public T get(String name, Class type) { + String h = getFirst(name); + return beanSession.convertToType(h, type); + } + + /** + * Same as {@link #get(String, Class)} but returns a default value if not found. + * + * @param name The HTTP header name. + * @param def The default value if the header was not specified or is null. + * @param type The class type to convert the header value to. + * @param The class type to convert the header value to. + * @return The parameter value converted to the specified class type. + */ + public T get(String name, T def, Class type) { + String h = getFirst(name); + if (h == null) + return def; + return beanSession.convertToType(h, type); + } + + /** + * Returns the specified header value converted to a POJO. + *

+ * The type can be any POJO type convertable from a String + * (See POJOs Convertable From Strings). + *

+ *

Examples:
+ *

+ * // Parse into a linked-list of strings. + * List<String> myheader = req.getHeader("My-Header", LinkedList.class, String.class); + *

+ * + * @param name The HTTP header name. + * @param type The type of object to create. + *
Can be any of the following: {@link ClassMeta}, {@link Class}, {@link ParameterizedType}, {@link GenericArrayType} + * @param args The type arguments of the class if it's a collection or map. + *
Can be any of the following: {@link ClassMeta}, {@link Class}, {@link ParameterizedType}, {@link GenericArrayType} + *
Ignored if the main type is not a map or collection. + * @param The class type to convert the header value to. + * @return The parameter value converted to the specified class type. + * @throws ParseException If the header could not be converted to the specified type. + */ + public T get(String name, Type type, Type...args) throws ParseException { + String h = getFirst(name); + return parser.parsePart(h, type, args); + } + + /** + * Returns the Accept header on the request. + *

+ * Content-Types that are acceptable for the response. + * + *

Example:
+ *

+ * Accept: text/plain + *

+ * + * @return The parsed Accept header on the request, or null if not found. + * + */ + public Accept getAccept() { + return Accept.forString(getFirst("Accept")); + } + + /** + * Returns the Accept-Charset header on the request. + *

+ * Character sets that are acceptable. + * + *

Example:
+ *

+ * Accept-Charset: utf-8 + *

+ * + * @return The parsed Accept-Charset header on the request, or null if not found. + */ + public AcceptCharset getAcceptCharset() { + return AcceptCharset.forString(getFirst("Accept-Charset")); + } + + /** + * Returns the Accept-Encoding header on the request. + *

+ * List of acceptable encodings. + * + *

Example:
+ *

+ * Accept-Encoding: gzip, deflate + *

+ * + * @return The parsed Accept-Encoding header on the request, or null if not found. + */ + public AcceptEncoding getAcceptEncoding() { + return AcceptEncoding.forString(getFirst("Accept-Encoding")); + } + + /** + * Returns the Accept-Language header on the request. + *

+ * List of acceptable human languages for response. + * + *

Example:
+ *

+ * Accept-Language: en-US + *

+ * + * @return The parsed Accept-Language header on the request, or null if not found. + */ + public AcceptLanguage getAcceptLanguage() { + return AcceptLanguage.forString(getFirst("Accept-Language")); + } + + /** + * Returns the Authorization header on the request. + *

+ * Authentication credentials for HTTP authentication. + * + *

Example:
+ *

+ * Authorization: Basic QWxhZGRpbjpvcGVuIHNlc2FtZQ== + *

+ * + * @return The parsed Authorization header on the request, or null if not found. + */ + public Authorization getAuthorization() { + return Authorization.forString(getFirst("Authorization")); + } + + /** + * Returns the Cache-Control header on the request. + *

+ * Used to specify directives that must be obeyed by all caching mechanisms along the request-response chain. + * + *

Example:
+ *

+ * Cache-Control: no-cache + *

+ * + * @return The parsed Cache-Control header on the request, or null if not found. + */ + public CacheControl getCacheControl() { + return CacheControl.forString(getFirst("Cache-Control")); + } + + /** + * Returns the Connection header on the request. + *

+ * Control options for the current connection and list of hop-by-hop request fields. + * + *

Example:
+ *

+ * Connection: keep-alive + * Connection: Upgrade + *

+ * + * @return The parsed header on the request, or null if not found. + */ + public Connection getConnection() { + return Connection.forString(getFirst("Connection")); + } + + /** + * Returns the Content-Length header on the request. + *

+ * The length of the request body in octets (8-bit bytes). + * + *

Example:
+ *

+ * Content-Length: 348 + *

+ * + * @return The parsed Content-Length header on the request, or null if not found. + */ + public ContentLength getContentLength() { + return ContentLength.forString(getFirst("Content-Length")); + } + + /** + * Returns the Content-Type header on the request. + *

+ * The MIME type of the body of the request (used with POST and PUT requests). + * + *

Example:
+ *

+ * Content-Type: application/x-www-form-urlencoded + *

+ * + * @return The parsed Content-Type header on the request, or null if not found. + */ + public ContentType getContentType() { + return ContentType.forString(getFirst("Content-Type")); + } + + /** + * Returns the Date header on the request. + *

+ * The date and time that the message was originated (in "HTTP-date" format as defined by RFC 7231 Date/Time Formats). + * + *

Example:
+ *

+ * Date: Tue, 15 Nov 1994 08:12:31 GMT + *

+ * + * @return The parsed Date header on the request, or null if not found. + */ + public Date getDate() { + return Date.forString(getFirst("Date")); + } + + /** + * Returns the Expect header on the request. + *

+ * Indicates that particular server behaviors are required by the client. + * + *

Example:
+ *

+ * Expect: 100-continue + *

+ * + * @return The parsed Expect header on the request, or null if not found. + */ + public Expect getExpect() { + return Expect.forString(getFirst("Expect")); + } + + /** + * Returns the From header on the request. + *

+ * The email address of the user making the request. + * + *

Example:
+ *

+ * From: user@example.com + *

+ * + * @return The parsed From header on the request, or null if not found. + */ + public From getFrom() { + return From.forString(getFirst("From")); + } + + /** + * Returns the Host header on the request. + *

+ * The domain name of the server (for virtual hosting), and the TCP port number on which the server is listening. + * The port number may be omitted if the port is the standard port for the service requested. + * + *

Example:
+ *

+ * Host: en.wikipedia.org:8080 + * Host: en.wikipedia.org + *

+ * + * @return The parsed Host header on the request, or null if not found. + */ + public Host getHost() { + return Host.forString(getFirst("Host")); + } + + /** + * Returns the If-Match header on the request. + *

+ * Only perform the action if the client supplied entity matches the same entity on the server. + * This is mainly for methods like PUT to only update a resource if it has not been modified since the user last updated it. + * + *

Example:
+ *

+ * If-Match: "737060cd8c284d8af7ad3082f209582d" + *

+ * + * @return The parsed If-Match header on the request, or null if not found. + */ + public IfMatch getIfMatch() { + return IfMatch.forString(getFirst("If-Match")); + } + + /** + * Returns the If-Modified-Since header on the request. + *

+ * Allows a 304 Not Modified to be returned if content is unchanged. + * + *

Example:
+ *

+ * If-Modified-Since: Sat, 29 Oct 1994 19:43:31 GMT + *

+ * + * @return The parsed If-Modified-Since header on the request, or null if not found. + */ + public IfModifiedSince getIfModifiedSince() { + return IfModifiedSince.forString(getFirst("If-Modified-Since")); + } + + /** + * Returns the If-None-Match header on the request. + *

+ * Allows a 304 Not Modified to be returned if content is unchanged, see HTTP ETag. + * + *

Example:
+ *

+ * If-None-Match: "737060cd8c284d8af7ad3082f209582d" + *

+ * + * @return The parsed If-None-Match header on the request, or null if not found. + */ + public IfNoneMatch getIfNoneMatch() { + return IfNoneMatch.forString(getFirst("If-None-Match")); + } + + /** + * Returns the If-Range header on the request. + *

+ * If the entity is unchanged, send me the part(s) that I am missing; otherwise, send me the entire new entity. + * + *

Example:
+ *

+ * If-Range: "737060cd8c284d8af7ad3082f209582d" + *

+ * + * @return The parsed If-Range header on the request, or null if not found. + */ + public IfRange getIfRange() { + return IfRange.forString(getFirst("If-Range")); + } + + /** + * Returns the If-Unmodified-Since header on the request. + *

+ * Only send the response if the entity has not been modified since a specific time. + * + *

Example:
+ *

+ * If-Unmodified-Since: Sat, 29 Oct 1994 19:43:31 GMT + *

+ * + * @return The parsed If-Unmodified-Since header on the request, or null if not found. + */ + public IfUnmodifiedSince getIfUnmodifiedSince() { + return IfUnmodifiedSince.forString(getFirst("If-Unmodified-Since")); + } + + /** + * Returns the Max-Forwards header on the request. + *

+ * Limit the number of times the message can be forwarded through proxies or gateways. + * + *

Example:
+ *

+ * Max-Forwards: 10 + *

+ * + * @return The parsed Max-Forwards header on the request, or null if not found. + */ + public MaxForwards getMaxForwards() { + return MaxForwards.forString(getFirst("Max-Forwards")); + } + + /** + * Returns the Pragma header on the request. + *

+ * Implementation-specific fields that may have various effects anywhere along the request-response chain. + * + *

Example:
+ *

+ * Pragma: no-cache + *

+ * + * @return The parsed Pragma header on the request, or null if not found. + */ + public Pragma getPragma() { + return Pragma.forString(getFirst("Pragma")); + } + + /** + * Returns the Proxy-Authorization header on the request. + *

+ * Authorization credentials for connecting to a proxy. + * + *

Example:
+ *

+ * Proxy-Authorization: Basic QWxhZGRpbjpvcGVuIHNlc2FtZQ== + *

+ * + * @return The parsed Proxy-Authorization header on the request, or null if not found. + */ + public ProxyAuthorization getProxyAuthorization() { + return ProxyAuthorization.forString(getFirst("Proxy-Authorization")); + } + + /** + * Returns the Range header on the request. + *

+ * Request only part of an entity. Bytes are numbered from 0. + * + *

Example:
+ *

+ * Range: bytes=500-999 + *

+ * + * @return The parsed Range header on the request, or null if not found. + */ + public Range getRange() { + return Range.forString(getFirst("Range")); + } + + /** + * Returns the Referer header on the request. + *

+ * This is the address of the previous web page from which a link to the currently requested page was followed. + * + *

Example:
+ *

+ * Referer: http://en.wikipedia.org/wiki/Main_Page + *

+ * + * @return The parsed Referer header on the request, or null if not found. + */ + public Referer getReferer() { + return Referer.forString(getFirst("Referer")); + } + + /** + * Returns the TE header on the request. + *

+ * The transfer encodings the user agent is willing to accept: the same values as for the response header field + * Transfer-Encoding can be used, plus the "trailers" value (related to the "chunked" transfer method) to notify the + * server it expects to receive additional fields in the trailer after the last, zero-sized, chunk. + * + *

Example:
+ *

+ * TE: trailers, deflate + *

+ * + * @return The parsed TE header on the request, or null if not found. + */ + public TE getTE() { + return TE.forString(getFirst("TE")); + } + + /** + * Returns the Time-Zone header value on the request if there is one. + *

+ * Example: "GMT". + * + * @return The Time-Zone header value on the request, or null if not present. + */ + public TimeZone getTimeZone() { + String tz = getFirst("Time-Zone"); + if (tz != null) + return TimeZone.getTimeZone(tz); + return null; + } + + /** + * Returns the User-Agent header on the request. + *

+ * The user agent string of the user agent. + * + *

Example:
+ *

+ * User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:12.0) Gecko/20100101 Firefox/21.0 + *

+ * + * @return The parsed User-Agent header on the request, or null if not found. + */ + public UserAgent getUserAgent() { + return UserAgent.forString(getFirst("User-Agent")); + } + + /** + * Returns the Upgrade header on the request. + *

+ * Ask the server to upgrade to another protocol. + * + *

Example:
+ *

+ * Upgrade: HTTP/2.0, HTTPS/1.3, IRC/6.9, RTA/x11, websocket + *

+ * + * @return The parsed Upgrade header on the request, or null if not found. + */ + public Upgrade getUpgrade() { + return Upgrade.forString(getFirst("Upgrade")); + } + + /** + * Returns the Via header on the request. + *

+ * Informs the server of proxies through which the request was sent. + * + *

Example:
+ *

+ * Via: 1.0 fred, 1.1 example.com (Apache/1.1) + *

+ * + * @return The parsed Via header on the request, or null if not found. + */ + public Via getVia() { + return Via.forString(getFirst("Via")); + } + + /** + * Returns the Warning header on the request. + *

+ * A general warning about possible problems with the entity body. + * + *

Example:
+ *

+ * Warning: 199 Miscellaneous warning + *

+ * + * @return The parsed Warning header on the request, or null if not found. + */ + public Warning getWarning() { + return Warning.forString(getFirst("Warning")); + } +} http://git-wip-us.apache.org/repos/asf/incubator-juneau/blob/321f6bde/juneau-rest/src/main/java/org/apache/juneau/rest/RequestPathParams.java ---------------------------------------------------------------------- diff --git a/juneau-rest/src/main/java/org/apache/juneau/rest/RequestPathParams.java b/juneau-rest/src/main/java/org/apache/juneau/rest/RequestPathParams.java new file mode 100644 index 0000000..8a12a0e --- /dev/null +++ b/juneau-rest/src/main/java/org/apache/juneau/rest/RequestPathParams.java @@ -0,0 +1,137 @@ +// *************************************************************************************************************************** +// * Licensed to the Apache Software Foundation (ASF) under one or more contributor license agreements. See the NOTICE file * +// * distributed with this work for additional information regarding copyright ownership. The ASF licenses this file * +// * to you under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance * +// * with the License. You may obtain a copy of the License at * +// * * +// * http://www.apache.org/licenses/LICENSE-2.0 * +// * * +// * Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an * +// * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the * +// * specific language governing permissions and limitations under the License. * +// *************************************************************************************************************************** +package org.apache.juneau.rest; + +import java.lang.reflect.*; +import java.util.*; + +import org.apache.juneau.*; +import org.apache.juneau.parser.*; +import org.apache.juneau.urlencoding.*; + +/** + * Represents the path parameters on an HTTP request. + */ +@SuppressWarnings("unchecked") +public class RequestPathParams extends TreeMap { + private static final long serialVersionUID = 1L; + + private UrlEncodingParser parser; + private BeanSession beanSession; + + RequestPathParams() { + super(String.CASE_INSENSITIVE_ORDER); + } + + RequestPathParams setParser(UrlEncodingParser parser) { + this.parser = parser; + return this; + } + + RequestPathParams setBeanSession(BeanSession beanSession) { + this.beanSession = beanSession; + return this; + } + + /** + * Sets a request query parameter value. + * + * @param name The parameter name. + * @param value The parameter value. + */ + public void put(String name, Object value) { + put(name, value); + } + + /** + * Returns the specified path parameter converted to a POJO. + *

+ * The type can be any POJO type convertable from a String (See POJOs Convertable From Strings). + *

+ *

Examples:
+ *

+ * // Parse into an integer. + * int myparam = req.getPathParameter("myparam", int.class); + * + * // Parse into an int array. + * int[] myparam = req.getPathParameter("myparam", int[].class); + + * // Parse into a bean. + * MyBean myparam = req.getPathParameter("myparam", MyBean.class); + * + * // Parse into a linked-list of objects. + * List myparam = req.getPathParameter("myparam", LinkedList.class); + * + * // Parse into a map of object keys/values. + * Map myparam = req.getPathParameter("myparam", TreeMap.class); + *

+ * + * @param name The attribute name. + * @param type The class type to convert the attribute value to. + * @param The class type to convert the attribute value to. + * @return The attribute value converted to the specified class type. + * @throws ParseException + */ + public T get(String name, Class type) throws ParseException { + return parse(name, beanSession.getClassMeta(type)); + } + + /** + * Returns the specified path parameter converted to a POJO. + *

+ * The type can be any POJO type convertable from a String (See POJOs Convertable From Strings). + *

+ * Use this method if you want to parse into a parameterized Map/Collection object. + *

+ *

Examples:
+ *

+ * // Parse into a linked-list of strings. + * List<String> myparam = req.getPathParameter("myparam", LinkedList.class, String.class); + * + * // Parse into a linked-list of linked-lists of strings. + * List<List<String>> myparam = req.getPathParameter("myparam", LinkedList.class, LinkedList.class, String.class); + * + * // Parse into a map of string keys/values. + * Map<String,String> myparam = req.getPathParameter("myparam", TreeMap.class, String.class, String.class); + * + * // Parse into a map containing string keys and values of lists containing beans. + * Map<String,List<MyBean>> myparam = req.getPathParameter("myparam", TreeMap.class, String.class, List.class, MyBean.class); + *

+ * + * @param name The attribute name. + * @param type The type of object to create. + *
Can be any of the following: {@link ClassMeta}, {@link Class}, {@link ParameterizedType}, {@link GenericArrayType} + * @param args The type arguments of the class if it's a collection or map. + *
Can be any of the following: {@link ClassMeta}, {@link Class}, {@link ParameterizedType}, {@link GenericArrayType} + *
Ignored if the main type is not a map or collection. + * @param The class type to convert the attribute value to. + * @return The attribute value converted to the specified class type. + * @throws ParseException + */ + public T get(String name, Type type, Type...args) throws ParseException { + return (T)parse(name, beanSession.getClassMeta(type, args)); + } + + /* Workhorse method */ + T parse(String name, ClassMeta cm) throws ParseException { + Object attr = get(name); + T t = null; + if (attr != null) + t = parser.parsePart(attr.toString(), cm); + if (t == null && cm.isPrimitive()) + return cm.getPrimitiveDefault(); + return t; + } + +} http://git-wip-us.apache.org/repos/asf/incubator-juneau/blob/321f6bde/juneau-rest/src/main/java/org/apache/juneau/rest/RequestQuery.java ---------------------------------------------------------------------- diff --git a/juneau-rest/src/main/java/org/apache/juneau/rest/RequestQuery.java b/juneau-rest/src/main/java/org/apache/juneau/rest/RequestQuery.java new file mode 100644 index 0000000..6a9a564 --- /dev/null +++ b/juneau-rest/src/main/java/org/apache/juneau/rest/RequestQuery.java @@ -0,0 +1,287 @@ +// *************************************************************************************************************************** +// * Licensed to the Apache Software Foundation (ASF) under one or more contributor license agreements. See the NOTICE file * +// * distributed with this work for additional information regarding copyright ownership. The ASF licenses this file * +// * to you under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance * +// * with the License. You may obtain a copy of the License at * +// * * +// * http://www.apache.org/licenses/LICENSE-2.0 * +// * * +// * Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an * +// * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the * +// * specific language governing permissions and limitations under the License. * +// *************************************************************************************************************************** +package org.apache.juneau.rest; + +import java.lang.reflect.*; +import java.util.*; + +import javax.servlet.http.*; + +import org.apache.juneau.*; +import org.apache.juneau.internal.*; +import org.apache.juneau.parser.*; +import org.apache.juneau.urlencoding.*; + +/** + * Represents the query parameters in an HTTP request. + */ +@SuppressWarnings("unchecked") +public final class RequestQuery extends LinkedHashMap { + private static final long serialVersionUID = 1L; + + private UrlEncodingParser parser; + private BeanSession beanSession; + + RequestQuery setParser(UrlEncodingParser parser) { + this.parser = parser; + return this; + } + + RequestQuery setBeanSession(BeanSession beanSession) { + this.beanSession = beanSession; + return this; + } + + /** + * Sets a request query parameter value. + * + * @param name The parameter name. + * @param value The parameter value. + */ + public void put(String name, Object value) { + put(name, new String[]{StringUtils.toString(value)}); + } + + /** + * Returns a query parameter value. + *

+ * Same as {@link HttpServletRequest#getParameter(String)} except only looks in the URL string, not parameters from URL-Encoded FORM posts. + *

+ * This method can be used to retrieve a parameter without triggering the underlying servlet API to load and parse the request body. + * + * @param name The URL parameter name. + * @return The parameter value, or null if parameter not specified or has no value (e.g. "&foo". + */ + public String getFirst(String name) { + String[] v = get(name); + if (v == null || v.length == 0) + return null; + if (v.length == 1 && v[0] != null && v[0].isEmpty()) { + // Fix for behavior difference between Tomcat and WAS. + // getParameter("foo") on "&foo" in Tomcat returns "". + // getParameter("foo") on "&foo" in WAS returns null. + if (containsKey(name)) + return null; + } + return v[0]; + } + + /** + * Same as {@link #getFirst(String)} but returns the specified default value if the query parameter was not specified. + * + * @param name The URL parameter name. + * @param def The default value. + * @return The parameter value, or the default value if parameter not specified or has no value (e.g. "&foo". + */ + public String getFirst(String name, String def) { + String s = getFirst(name); + return s == null ? def : s; + } + + /** + * Returns the specified query parameter value converted to a POJO. + *

+ * This method can be used to retrieve a parameter without triggering the underlying servlet API to load and parse the request body. + *

+ *

Examples:
+ *

+ * // Parse into an integer. + * int myparam = req.getQueryParameter("myparam", int.class); + * + * // Parse into an int array. + * int[] myparam = req.getQueryParameter("myparam", int[].class); + + * // Parse into a bean. + * MyBean myparam = req.getQueryParameter("myparam", MyBean.class); + * + * // Parse into a linked-list of objects. + * List myparam = req.getQueryParameter("myparam", LinkedList.class); + * + * // Parse into a map of object keys/values. + * Map myparam = req.getQueryParameter("myparam", TreeMap.class); + *

+ * + * @param name The parameter name. + * @param type The class type to convert the parameter value to. + * @param The class type to convert the parameter value to. + * @return The parameter value converted to the specified class type. + * @throws ParseException + */ + public T get(String name, Class type) throws ParseException { + return get(name, beanSession.getClassMeta(type)); + } + + /** + * Same as {@link #get(String, Class)} except returns a default value if not found. + * + * @param name The parameter name. + * @param def The default value if the parameter was not specified or is null. + * @param type The class type to convert the parameter value to. + * @param The class type to convert the parameter value to. + * @return The parameter value converted to the specified class type. + * @throws ParseException + */ + public T get(String name, T def, Class type) throws ParseException { + return get(name, def, beanSession.getClassMeta(type)); + } + + /** + * Returns the specified query parameter value converted to a POJO. + *

+ * This method can be used to retrieve a parameter without triggering the underlying servlet API to load and parse the request body. + *

+ * Use this method if you want to parse into a parameterized Map/Collection object. + *

+ *

Examples:
+ *

+ * // Parse into a linked-list of strings. + * Listt<String> myparam = req.getQueryParameter("myparam", LinkedList.class, String.class); + * + * // Parse into a linked-list of linked-lists of strings. + * Listt<List<String>> myparam = req.getQueryParameter("myparam", LinkedList.class, LinkedList.class, String.class); + * + * // Parse into a map of string keys/values. + * Map<String,String> myparam = req.getQueryParameter("myparam", TreeMap.class, String.class, String.class); + * + * // Parse into a map containing string keys and values of lists containing beans. + * Map<String,List<MyBean>> myparam = req.getQueryParameter("myparam", TreeMap.class, String.class, List.class, MyBean.class); + *

+ * + * @param name The parameter name. + * @param type The type of object to create. + *
Can be any of the following: {@link ClassMeta}, {@link Class}, {@link ParameterizedType}, {@link GenericArrayType} + * @param args The type arguments of the class if it's a collection or map. + *
Can be any of the following: {@link ClassMeta}, {@link Class}, {@link ParameterizedType}, {@link GenericArrayType} + *
Ignored if the main type is not a map or collection. + * @param The class type to convert the parameter value to. + * @return The parameter value converted to the specified class type. + * @throws ParseException + */ + public T get(String name, Type type, Type...args) throws ParseException { + return (T)parse(name, beanSession.getClassMeta(type, args)); + } + + /** + * Same as {@link #get(String, Class)} except returns a default value if not found. + * + * @param name The parameter name. + * @param type The type of object to create. + *
Can be any of the following: {@link ClassMeta}, {@link Class}, {@link ParameterizedType}, {@link GenericArrayType} + * @param args The type arguments of the class if it's a collection or map. + *
Can be any of the following: {@link ClassMeta}, {@link Class}, {@link ParameterizedType}, {@link GenericArrayType} + *
Ignored if the main type is not a map or collection. + * @param def The default value if the parameter was not specified or is null. + * @param The class type to convert the parameter value to. + * @return The parameter value converted to the specified class type. + * @throws ParseException + */ + public T get(String name, Object def, Type type, Type...args) throws ParseException { + return (T)parse(name, def, beanSession.getClassMeta(type, args)); + } + + /** + * Same as {@link #get(String, Class)} except for use on multi-part parameters + * (e.g. "&key=1&key=2&key=3" instead of "&key=(1,2,3)"). + *

+ * This method must only be called when parsing into classes of type Collection or array. + * + * @param name The query parameter name. + * @param c The class type to convert the parameter value to. + * @param The class type to convert the parameter value to. + * @return The query parameter value converted to the specified class type. + * @throws ParseException + */ + public T getAll(String name, Class c) throws ParseException { + return getAll(name, beanSession.getClassMeta(c)); + } + + /** + * Same as {@link #get(String, Type, Type...)} except for use on multi-part parameters + * (e.g. "&key=1&key=2&key=3" instead of "&key=(1,2,3)"). + *

+ * This method must only be called when parsing into classes of type Collection or array. + * + * @param name The query parameter name. + * @param type The type of object to create. + *
Can be any of the following: {@link ClassMeta}, {@link Class}, {@link ParameterizedType}, {@link GenericArrayType} + * @param args The type arguments of the class if it's a collection or map. + *
Can be any of the following: {@link ClassMeta}, {@link Class}, {@link ParameterizedType}, {@link GenericArrayType} + *
Ignored if the main type is not a map or collection. + * @param The class type to convert the parameter value to. + * @return The query parameter value converted to the specified class type. + * @throws ParseException + */ + public T getAll(String name, Type type, Type...args) throws ParseException { + return (T)parseAll(name, beanSession.getClassMeta(type, args)); + } + + /** + * Returns true if the request contains any of the specified query parameters. + * + * @param params The list of parameters to check for. + * @return true if the request contains any of the specified query parameters. + */ + public boolean containsAnyKeys(String...params) { + for (String p : params) + if (containsKey(p)) + return true; + return false; + } + + /* Workhorse method */ + private T parse(String name, T def, ClassMeta cm) throws ParseException { + String val = getFirst(name); + if (val == null) + return def; + return parseValue(val, cm); + } + + /* Workhorse method */ + private T parse(String name, ClassMeta cm) throws ParseException { + String val = getFirst(name); + if (cm.isPrimitive() && (val == null || val.isEmpty())) + return cm.getPrimitiveDefault(); + return parseValue(val, cm); + } + + /* Workhorse method */ + @SuppressWarnings("rawtypes") + private T parseAll(String name, ClassMeta cm) throws ParseException { + String[] p = get(name); + if (p == null) + return null; + if (cm.isArray()) { + List c = new ArrayList(); + for (int i = 0; i < p.length; i++) + c.add(parseValue(p[i], cm.getElementType())); + return (T)ArrayUtils.toArray(c, cm.getElementType().getInnerClass()); + } else if (cm.isCollection()) { + try { + Collection c = (Collection)(cm.canCreateNewInstance() ? cm.newInstance() : new ObjectList()); + for (int i = 0; i < p.length; i++) + c.add(parseValue(p[i], cm.getElementType())); + return (T)c; + } catch (ParseException e) { + throw e; + } catch (Exception e) { + // Typically an instantiation exception. + throw new ParseException(e); + } + } + throw new ParseException("Invalid call to getQueryParameters(String, ClassMeta). Class type must be a Collection or array."); + } + + private T parseValue(String val, ClassMeta c) throws ParseException { + return parser.parsePart(val, c); + } +} http://git-wip-us.apache.org/repos/asf/incubator-juneau/blob/321f6bde/juneau-rest/src/main/java/org/apache/juneau/rest/RestContext.java ---------------------------------------------------------------------- diff --git a/juneau-rest/src/main/java/org/apache/juneau/rest/RestContext.java b/juneau-rest/src/main/java/org/apache/juneau/rest/RestContext.java index 97ab2d4..54a3fa0 100644 --- a/juneau-rest/src/main/java/org/apache/juneau/rest/RestContext.java +++ b/juneau-rest/src/main/java/org/apache/juneau/rest/RestContext.java @@ -444,7 +444,7 @@ public final class RestContext extends Context { if (m != null) { try { // Parse the args and invoke the method. - Parser p = req.getParser(); + Parser p = req.getBody().getParser(); Object input = p.isReaderParser() ? req.getReader() : req.getInputStream(); Object output = m.invoke(o, p.parseArgs(input, m.getGenericParameterTypes())); res.setOutput(output); http://git-wip-us.apache.org/repos/asf/incubator-juneau/blob/321f6bde/juneau-rest/src/main/java/org/apache/juneau/rest/RestParam.java ---------------------------------------------------------------------- diff --git a/juneau-rest/src/main/java/org/apache/juneau/rest/RestParam.java b/juneau-rest/src/main/java/org/apache/juneau/rest/RestParam.java new file mode 100644 index 0000000..a900c14 --- /dev/null +++ b/juneau-rest/src/main/java/org/apache/juneau/rest/RestParam.java @@ -0,0 +1,978 @@ +// *************************************************************************************************************************** +// * Licensed to the Apache Software Foundation (ASF) under one or more contributor license agreements. See the NOTICE file * +// * distributed with this work for additional information regarding copyright ownership. The ASF licenses this file * +// * to you under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance * +// * with the License. You may obtain a copy of the License at * +// * * +// * http://www.apache.org/licenses/LICENSE-2.0 * +// * * +// * Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an * +// * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the * +// * specific language governing permissions and limitations under the License. * +// *************************************************************************************************************************** +package org.apache.juneau.rest; + +import static org.apache.juneau.rest.RestParamType.*; + +import java.io.*; +import java.lang.reflect.*; +import java.util.*; +import java.util.logging.*; + +import javax.servlet.*; +import javax.servlet.http.*; + +import org.apache.juneau.*; +import org.apache.juneau.dto.swagger.*; +import org.apache.juneau.http.*; +import org.apache.juneau.http.Date; +import org.apache.juneau.ini.*; +import org.apache.juneau.internal.*; +import org.apache.juneau.parser.*; +import org.apache.juneau.utils.*; + +/** + * REST java method parameter resolver. + */ +public abstract class RestParam { + + /** + * Standard set of method parameter resolvers. + */ + public static final Map,RestParam> STANDARD_RESOLVERS; + + static { + Map,RestParam> m = new HashMap,RestParam>(); + + @SuppressWarnings("rawtypes") + Class[] r = new Class[] { + + // Standard top-level objects + HttpServletRequestObject.class, + RestRequestObject.class, + HttpServletResponseObject.class, + RestResponseObject.class, + + // Headers + AcceptHeader.class, + AcceptCharsetHeader.class, + AcceptEncodingHeader.class, + AcceptLanguageHeader.class, + AuthorizationHeader.class, + CacheControlHeader.class, + ConnectionHeader.class, + ContentLengthHeader.class, + ContentTypeHeader.class, + DateHeader.class, + ExpectHeader.class, + FromHeader.class, + HostHeader.class, + IfMatchHeader.class, + IfModifiedSinceHeader.class, + IfNoneMatchHeader.class, + IfRangeHeader.class, + IfUnmodifiedSinceHeader.class, + MaxForwardsHeader.class, + PragmaHeader.class, + ProxyAuthorizationHeader.class, + RangeHeader.class, + RefererHeader.class, + TEHeader.class, + UserAgentHeader.class, + UpgradeHeader.class, + ViaHeader.class, + WarningHeader.class, + TimeZoneHeader.class, + + // Other objects + ResourceBundleObject.class, + MessageBundleObject.class, + InputStreamObject.class, + ServletInputStreamObject.class, + ReaderObject.class, + OutputStreamObject.class, + ServletOutputStreamObject.class, + WriterObject.class, + RequestHeadersObject.class, + RequestQueryParamsObject.class, + RequestFormDataObject.class, + HttpMethodObject.class, + LoggerObject.class, + JuneauLoggerObject.class, + RestContextObject.class, + ParserObject.class, + LocaleObject.class, + SwaggerObject.class, + RequestPathParamsObject.class, + RequestBodyObject.class, + ConfigFileObject.class, + }; + + for (Class c : r) { + try { + RestParam mpr = (RestParam)c.newInstance(); + m.put(mpr.forClass(), mpr); + } catch (Exception e) { + e.printStackTrace(); + } + } + + STANDARD_RESOLVERS = Collections.unmodifiableMap(m); + } + + final RestParamType paramType; + final String name; + final Type type; + + /** + * Constructor. + * + * @param paramType The Swagger parameter type. + * @param name The parameter name. + * Can be null if parameter doesn't have a name (e.g. the request body). + * @param type The object type to convert the parameter to. + */ + protected RestParam(RestParamType paramType, String name, Type type) { + this.paramType = paramType; + this.name = name; + this.type = type; + } + + /** + * Resolves the parameter object. + * + * @param req The rest request. + * @param res The rest response. + * @return The resolved object. + * @throws Exception + */ + public abstract Object resolve(RestRequest req, RestResponse res) throws Exception; + + /** + * Returns the parameter class type that this parameter resolver is meant for. + * @return The parameter class type, or null if the type passed in isn't an instance of {@link Class}. + */ + protected Class forClass() { + if (type instanceof Class) + return (Class)type; + return null; + } + + /** + * Returns the swagger parameter type for this parameter as shown in the Swagger doc. + * @return the swagger parameter type for this parameter. + */ + protected RestParamType getParamType() { + return paramType; + } + + /** + * Returns the parameter name for this parameter as shown in the Swagger doc. + * @return the parameter name for this parameter. + */ + protected String getName() { + return name; + } + + //------------------------------------------------------------------------------------------------------------------- + // Request / Response retrievers + //------------------------------------------------------------------------------------------------------------------- + + static final class HttpServletRequestObject extends RestParam { + + protected HttpServletRequestObject() { + super(OTHER, null, HttpServletRequest.class); + } + + @Override /* RestParam */ + public Object resolve(RestRequest req, RestResponse res) { + return req; + } + } + + static final class HttpServletResponseObject extends RestParam { + + protected HttpServletResponseObject() { + super(OTHER, null, HttpServletResponse.class); + } + + @Override /* RestParam */ + public Object resolve(RestRequest req, RestResponse res) { + return res; + } + } + + static final class RestRequestObject extends RestParam { + + protected RestRequestObject() { + super(OTHER, null, RestRequest.class); + } + + @Override /* RestParam */ + public Object resolve(RestRequest req, RestResponse res) { + return req; + } + } + + static final class RestResponseObject extends RestParam { + + protected RestResponseObject() { + super(OTHER, null, RestResponse.class); + } + + @Override /* RestParam */ + public Object resolve(RestRequest req, RestResponse res) { + return res; + } + } + + //------------------------------------------------------------------------------------------------------------------- + // Header retrievers + //------------------------------------------------------------------------------------------------------------------- + + static final class AcceptHeader extends RestParam { + + protected AcceptHeader() { + super(HEADER, "Accept-Header", AcceptHeader.class); + } + + @Override /* RestParam */ + public Object resolve(RestRequest req, RestResponse res) { + return req.getHeaders().getAccept(); + } + } + + static final class AcceptCharsetHeader extends RestParam { + + protected AcceptCharsetHeader() { + super(HEADER, "Accept-Charset", AcceptCharset.class); + } + + @Override /* RestParam */ + public AcceptCharset resolve(RestRequest req, RestResponse res) { + return req.getHeaders().getAcceptCharset(); + } + } + + static final class AcceptEncodingHeader extends RestParam { + + protected AcceptEncodingHeader() { + super(HEADER, "Accept-Encoding", AcceptEncoding.class); + } + + @Override + public AcceptEncoding resolve(RestRequest req, RestResponse res) { + return req.getHeaders().getAcceptEncoding(); + } + } + + static final class AcceptLanguageHeader extends RestParam { + + protected AcceptLanguageHeader() { + super(HEADER, "Accept-Language", AcceptLanguage.class); + } + + @Override + public AcceptLanguage resolve(RestRequest req, RestResponse res) { + return req.getHeaders().getAcceptLanguage(); + } + } + + static final class AuthorizationHeader extends RestParam { + + protected AuthorizationHeader() { + super(HEADER, "Authorization", Authorization.class); + } + + @Override + public Authorization resolve(RestRequest req, RestResponse res) { + return req.getHeaders().getAuthorization(); + } + } + + static final class CacheControlHeader extends RestParam { + + protected CacheControlHeader() { + super(HEADER, "Cache-Control", CacheControl.class); + } + + @Override + public CacheControl resolve(RestRequest req, RestResponse res) { + return req.getHeaders().getCacheControl(); + } + } + + static final class ConnectionHeader extends RestParam { + + protected ConnectionHeader() { + super(HEADER, "Connection", Connection.class); + } + + @Override + public Connection resolve(RestRequest req, RestResponse res) { + return req.getHeaders().getConnection(); + } + } + + static final class ContentLengthHeader extends RestParam { + + protected ContentLengthHeader() { + super(HEADER, "Content-Length", ContentLength.class); + } + + @Override + public ContentLength resolve(RestRequest req, RestResponse res) { + return req.getHeaders().getContentLength(); + } + } + + static final class ContentTypeHeader extends RestParam { + + protected ContentTypeHeader() { + super(HEADER, "Content-Type", ContentType.class); + } + + @Override + public ContentType resolve(RestRequest req, RestResponse res) { + return req.getHeaders().getContentType(); + } + } + + static final class DateHeader extends RestParam { + + protected DateHeader() { + super(HEADER, "Date", Date.class); + } + + @Override + public Date resolve(RestRequest req, RestResponse res) { + return req.getHeaders().getDate(); + } + } + + static final class ExpectHeader extends RestParam { + + protected ExpectHeader() { + super(HEADER, "Expect", Expect.class); + } + + @Override + public Expect resolve(RestRequest req, RestResponse res) { + return req.getHeaders().getExpect(); + } + } + + static final class FromHeader extends RestParam { + + protected FromHeader() { + super(HEADER, "From", From.class); + } + + @Override + public From resolve(RestRequest req, RestResponse res) { + return req.getHeaders().getFrom(); + } + } + + static final class HostHeader extends RestParam { + + protected HostHeader() { + super(HEADER, "Host", Host.class); + } + + @Override + public Host resolve(RestRequest req, RestResponse res) { + return req.getHeaders().getHost(); + } + } + + static final class IfMatchHeader extends RestParam { + + protected IfMatchHeader() { + super(HEADER, "If-Match", IfMatch.class); + } + + @Override + public IfMatch resolve(RestRequest req, RestResponse res) { + return req.getHeaders().getIfMatch(); + } + } + + static final class IfModifiedSinceHeader extends RestParam { + + protected IfModifiedSinceHeader() { + super(HEADER, "If-Modified-Since", IfModifiedSince.class); + } + + @Override + public IfModifiedSince resolve(RestRequest req, RestResponse res) { + return req.getHeaders().getIfModifiedSince(); + } + } + + static final class IfNoneMatchHeader extends RestParam { + + protected IfNoneMatchHeader() { + super(HEADER, "If-None-Match", IfNoneMatch.class); + } + + @Override + public IfNoneMatch resolve(RestRequest req, RestResponse res) { + return req.getHeaders().getIfNoneMatch(); + } + } + + static final class IfRangeHeader extends RestParam { + + protected IfRangeHeader() { + super(HEADER, "If-Range", IfRange.class); + } + + @Override + public IfRange resolve(RestRequest req, RestResponse res) { + return req.getHeaders().getIfRange(); + } + } + + static final class IfUnmodifiedSinceHeader extends RestParam { + + protected IfUnmodifiedSinceHeader() { + super(HEADER, "If-Unmodified-Since", IfUnmodifiedSince.class); + } + + @Override + public IfUnmodifiedSince resolve(RestRequest req, RestResponse res) { + return req.getHeaders().getIfUnmodifiedSince(); + } + } + + static final class MaxForwardsHeader extends RestParam { + + protected MaxForwardsHeader() { + super(HEADER, "Max-Forwards", MaxForwards.class); + } + + @Override + public MaxForwards resolve(RestRequest req, RestResponse res) { + return req.getHeaders().getMaxForwards(); + } + } + + static final class PragmaHeader extends RestParam { + + protected PragmaHeader() { + super(HEADER, "Pragma", Pragma.class); + } + + @Override + public Pragma resolve(RestRequest req, RestResponse res) { + return req.getHeaders().getPragma(); + } + } + + static final class ProxyAuthorizationHeader extends RestParam { + + protected ProxyAuthorizationHeader() { + super(HEADER, "Proxy-Authorization", ProxyAuthorization.class); + } + + @Override + public ProxyAuthorization resolve(RestRequest req, RestResponse res) { + return req.getHeaders().getProxyAuthorization(); + } + } + + static final class RangeHeader extends RestParam { + + protected RangeHeader() { + super(HEADER, "Range", Range.class); + } + + @Override + public Range resolve(RestRequest req, RestResponse res) { + return req.getHeaders().getRange(); + } + } + + static final class RefererHeader extends RestParam { + + protected RefererHeader() { + super(HEADER, "Referer", Referer.class); + } + + @Override + public Referer resolve(RestRequest req, RestResponse res) { + return req.getHeaders().getReferer(); + } + } + + static final class TEHeader extends RestParam { + + protected TEHeader() { + super(HEADER, "TE", TE.class); + } + + @Override + public TE resolve(RestRequest req, RestResponse res) { + return req.getHeaders().getTE(); + } + } + + static final class UserAgentHeader extends RestParam { + + protected UserAgentHeader() { + super(HEADER, "User-Agent", UserAgent.class); + } + + @Override + public UserAgent resolve(RestRequest req, RestResponse res) { + return req.getHeaders().getUserAgent(); + } + } + + static final class UpgradeHeader extends RestParam { + + protected UpgradeHeader() { + super(HEADER, "Upgrade", Upgrade.class); + } + + @Override + public Upgrade resolve(RestRequest req, RestResponse res) { + return req.getHeaders().getUpgrade(); + } + } + + static final class ViaHeader extends RestParam { + + protected ViaHeader() { + super(HEADER, "Via", Via.class); + } + + @Override + public Via resolve(RestRequest req, RestResponse res) { + return req.getHeaders().getVia(); + } + } + + static final class WarningHeader extends RestParam { + + protected WarningHeader() { + super(HEADER, "Warning", Warning.class); + } + + @Override + public Warning resolve(RestRequest req, RestResponse res) { + return req.getHeaders().getWarning(); + } + } + + static final class TimeZoneHeader extends RestParam { + + protected TimeZoneHeader() { + super(HEADER, "Time-Zone", TimeZone.class); + } + + @Override + public TimeZone resolve(RestRequest req, RestResponse res) { + return req.getHeaders().getTimeZone(); + } + } + + //------------------------------------------------------------------------------------------------------------------- + // Annotated retrievers + //------------------------------------------------------------------------------------------------------------------- + + static final class PathParameterObject extends RestParam { + + protected PathParameterObject(String name, Type type) { + super(PATH, name, type); + } + + @Override /* RestParam */ + public Object resolve(RestRequest req, RestResponse res) throws Exception { + return req.getPathParams().get(name, type); + } + } + + static final class BodyObject extends RestParam { + + protected BodyObject(Type type) { + super(BODY, null, type); + } + + @Override /* RestParam */ + public Object resolve(RestRequest req, RestResponse res) throws Exception { + return req.getBody().asType(type); + } + } + + static final class HeaderObject extends RestParam { + + protected HeaderObject(String name, Type type) { + super(HEADER, name, type); + } + + @Override /* RestParam */ + public Object resolve(RestRequest req, RestResponse res) throws Exception { + return req.getHeaders().get(name, type); + } + } + + static final class MethodObject extends RestParam { + + protected MethodObject() { + super(OTHER, null, null); + } + + @Override /* RestParam */ + public Object resolve(RestRequest req, RestResponse res) throws Exception { + return req.getMethod(); + } + } + + static final class FormDataObject extends RestParam { + private final boolean multiPart, plainParams; + + protected FormDataObject(String name, Type type, boolean multiPart, boolean plainParams) { + super(FORMDATA, name, type); + this.multiPart = multiPart; + this.plainParams = plainParams; + } + + @Override /* RestParam */ + public Object resolve(RestRequest req, RestResponse res) throws Exception { + BeanSession bs = req.getBeanSession(); + if (multiPart) + return req.getFormData().getAll(name, type); + if (plainParams) + return bs.convertToType(req.getFormData(name), bs.getClassMeta(type)); + return req.getFormData().get(name, type); + } + } + + static final class QueryObject extends RestParam { + private final boolean multiPart, plainParams; + + protected QueryObject(String name, Type type, boolean multiPart, boolean plainParams) { + super(QUERY, name, type); + this.multiPart = multiPart; + this.plainParams = plainParams; + } + + @Override /* RestParam */ + public Object resolve(RestRequest req, RestResponse res) throws Exception { + BeanSession bs = req.getBeanSession(); + if (multiPart) + return req.getQuery().getAll(name, type); + if (plainParams) + return bs.convertToType(req.getQuery(name), bs.getClassMeta(type)); + return req.getQuery().get(name, type); + } + } + + static final class HasFormDataObject extends RestParam { + + protected HasFormDataObject(String name, Type type) { + super(FORMDATA, name, type); + } + + @Override /* RestParam */ + public Object resolve(RestRequest req, RestResponse res) throws Exception { + BeanSession bs = req.getBeanSession(); + return bs.convertToType(req.getFormData().containsKey(name), bs.getClassMeta(type)); + } + } + + static final class HasQueryObject extends RestParam { + + protected HasQueryObject(String name, Type type) { + super(QUERY, name, type); + } + + @Override /* RestParam */ + public Object resolve(RestRequest req, RestResponse res) throws Exception { + BeanSession bs = req.getBeanSession(); + return bs.convertToType(req.getQuery().containsKey(name), bs.getClassMeta(type)); + } + } + + static final class PathRemainderObject extends RestParam { + + protected PathRemainderObject() { + super(OTHER, null, null); + } + + @Override /* RestParam */ + public Object resolve(RestRequest req, RestResponse res) throws Exception { + return req.getPathRemainder(); + } + } + + static final class PropsObject extends RestParam { + + protected PropsObject() { + super(OTHER, null, null); + } + + @Override /* RestParam */ + public Object resolve(RestRequest req, RestResponse res) throws Exception { + return req.getProperties(); + } + } + + //------------------------------------------------------------------------------------------------------------------- + // Other retrievers + //------------------------------------------------------------------------------------------------------------------- + + static final class ResourceBundleObject extends RestParam { + + protected ResourceBundleObject() { + super(OTHER, null, ResourceBundle.class); + } + + @Override /* RestParam */ + public Object resolve(RestRequest req, RestResponse res) throws Exception { + return req.getResourceBundle(); + } + } + + static final class MessageBundleObject extends RestParam { + + protected MessageBundleObject() { + super(OTHER, null, MessageBundle.class); + } + + @Override /* RestParam */ + public Object resolve(RestRequest req, RestResponse res) throws Exception { + return req.getResourceBundle(); + } + } + + static final class InputStreamObject extends RestParam { + + protected InputStreamObject() { + super(OTHER, null, InputStream.class); + } + + @Override /* RestParam */ + public Object resolve(RestRequest req, RestResponse res) throws Exception { + return req.getInputStream(); + } + } + + static final class ServletInputStreamObject extends RestParam { + + protected ServletInputStreamObject() { + super(OTHER, null, ServletInputStream.class); + } + + @Override /* RestParam */ + public Object resolve(RestRequest req, RestResponse res) throws Exception { + return req.getInputStream(); + } + } + + static final class ReaderObject extends RestParam { + + protected ReaderObject() { + super(OTHER, null, Reader.class); + } + + @Override /* RestParam */ + public Object resolve(RestRequest req, RestResponse res) throws Exception { + return req.getReader(); + } + } + + static final class OutputStreamObject extends RestParam { + + protected OutputStreamObject() { + super(OTHER, null, OutputStream.class); + } + + @Override /* RestParam */ + public Object resolve(RestRequest req, RestResponse res) throws Exception { + return res.getOutputStream(); + } + } + + static final class ServletOutputStreamObject extends RestParam { + + protected ServletOutputStreamObject() { + super(OTHER, null, ServletOutputStream.class); + } + + @Override /* RestParam */ + public Object resolve(RestRequest req, RestResponse res) throws Exception { + return res.getOutputStream(); + } + } + + static final class WriterObject extends RestParam { + + protected WriterObject() { + super(OTHER, null, Writer.class); + } + + @Override /* RestParam */ + public Object resolve(RestRequest req, RestResponse res) throws Exception { + return res.getWriter(); + } + } + + static final class RequestHeadersObject extends RestParam { + + protected RequestHeadersObject() { + super(OTHER, null, RequestHeaders.class); + } + + @Override /* RestParam */ + public Object resolve(RestRequest req, RestResponse res) throws Exception { + return req.getHeaders(); + } + } + + static final class RequestQueryParamsObject extends RestParam { + + protected RequestQueryParamsObject() { + super(OTHER, null, RequestQuery.class); + } + + @Override /* RestParam */ + public Object resolve(RestRequest req, RestResponse res) throws Exception { + return req.getQuery(); + } + } + + static final class RequestFormDataObject extends RestParam { + + protected RequestFormDataObject() { + super(OTHER, null, RequestFormData.class); + } + + @Override /* RestParam */ + public Object resolve(RestRequest req, RestResponse res) throws Exception { + return req.getFormData(); + } + } + + static final class HttpMethodObject extends RestParam { + + protected HttpMethodObject() { + super(OTHER, null, HttpMethod.class); + } + + @Override /* RestParam */ + public Object resolve(RestRequest req, RestResponse res) throws Exception { + return req.getHttpMethod(); + } + } + + static final class LoggerObject extends RestParam { + + protected LoggerObject() { + super(OTHER, null, Logger.class); + } + + @Override /* RestParam */ + public Object resolve(RestRequest req, RestResponse res) throws Exception { + return req.getContext().getLogger().getLogger(); + } + } + + static final class JuneauLoggerObject extends RestParam { + + protected JuneauLoggerObject() { + super(OTHER, null, JuneauLogger.class); + } + + @Override /* RestParam */ + public Object resolve(RestRequest req, RestResponse res) throws Exception { + return req.getContext().getLogger().getLogger(); + } + } + + static final class RestContextObject extends RestParam { + + protected RestContextObject() { + super(OTHER, null, RestContext.class); + } + + @Override /* RestParam */ + public Object resolve(RestRequest req, RestResponse res) throws Exception { + return req.getContext(); + } + } + + static final class ParserObject extends RestParam { + + protected ParserObject() { + super(OTHER, null, Parser.class); + } + + @Override /* RestParam */ + public Object resolve(RestRequest req, RestResponse res) throws Exception { + return req.getBody().getParser(); + } + } + + static final class LocaleObject extends RestParam { + + protected LocaleObject() { + super(OTHER, null, Locale.class); + } + + @Override /* RestParam */ + public Object resolve(RestRequest req, RestResponse res) throws Exception { + return req.getLocale(); + } + } + + static final class SwaggerObject extends RestParam { + + protected SwaggerObject() { + super(OTHER, null, Swagger.class); + } + + @Override /* RestParam */ + public Object resolve(RestRequest req, RestResponse res) throws Exception { + return req.getSwagger(); + } + } + + static final class RequestPathParamsObject extends RestParam { + + protected RequestPathParamsObject() { + super(OTHER, null, RequestPathParams.class); + } + + @Override /* RestParam */ + public Object resolve(RestRequest req, RestResponse res) throws Exception { + return req.getPathParams(); + } + } + + static final class RequestBodyObject extends RestParam { + + protected RequestBodyObject() { + super(BODY, null, RequestBody.class); + } + + @Override /* RestParam */ + public Object resolve(RestRequest req, RestResponse res) throws Exception { + return req.getBody(); + } + } + + static final class ConfigFileObject extends RestParam { + + protected ConfigFileObject() { + super(OTHER, null, ConfigFile.class); + } + + @Override /* RestParam */ + public Object resolve(RestRequest req, RestResponse res) throws Exception { + return req.getConfigFile(); + } + } +} http://git-wip-us.apache.org/repos/asf/incubator-juneau/blob/321f6bde/juneau-rest/src/main/java/org/apache/juneau/rest/RestParamType.java ---------------------------------------------------------------------- diff --git a/juneau-rest/src/main/java/org/apache/juneau/rest/RestParamType.java b/juneau-rest/src/main/java/org/apache/juneau/rest/RestParamType.java new file mode 100644 index 0000000..70fe2eb --- /dev/null +++ b/juneau-rest/src/main/java/org/apache/juneau/rest/RestParamType.java @@ -0,0 +1,48 @@ +// *************************************************************************************************************************** +// * Licensed to the Apache Software Foundation (ASF) under one or more contributor license agreements. See the NOTICE file * +// * distributed with this work for additional information regarding copyright ownership. The ASF licenses this file * +// * to you under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance * +// * with the License. You may obtain a copy of the License at * +// * * +// * http://www.apache.org/licenses/LICENSE-2.0 * +// * * +// * Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an * +// * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the * +// * specific language governing permissions and limitations under the License. * +// *************************************************************************************************************************** +package org.apache.juneau.rest; + +/** + * Represents the possible parameter types as defined by the Swagger 2.0 specification. + */ +public enum RestParamType { + + /** Path variable */ + PATH("path"), + + /** Header value */ + HEADER("header"), + + /** Form data entry */ + FORMDATA("formData"), + + /** Query parameter */ + QUERY("query"), + + /** Request body */ + BODY("body"), + + /** Not a standard Swagger-defined field */ + OTHER("other"); + + private final String value; + + private RestParamType(String value) { + this.value = value; + } + + @Override /* Object */ + public String toString() { + return value; + } +}