001// *************************************************************************************************************************** 002// * Licensed to the Apache Software Foundation (ASF) under one or more contributor license agreements. See the NOTICE file * 003// * distributed with this work for additional information regarding copyright ownership. The ASF licenses this file * 004// * to you under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance * 005// * with the License. You may obtain a copy of the License at * 006// * * 007// * http://www.apache.org/licenses/LICENSE-2.0 * 008// * * 009// * Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an * 010// * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the * 011// * specific language governing permissions and limitations under the License. * 012// *************************************************************************************************************************** 013package org.apache.juneau.rest; 014 015import java.io.*; 016import java.lang.reflect.*; 017import java.util.*; 018 019import javax.servlet.*; 020import javax.servlet.http.*; 021 022import org.apache.juneau.*; 023import org.apache.juneau.config.*; 024import org.apache.juneau.cp.Messages; 025import org.apache.juneau.dto.swagger.*; 026import org.apache.juneau.http.header.*; 027import org.apache.juneau.http.header.Date; 028import org.apache.juneau.parser.*; 029import org.apache.juneau.reflect.*; 030 031/** 032 * REST java method parameter resolver. 033 * 034 * <p> 035 * Used to resolve instances of classes being passed to Java REST methods. 036 * 037 * <p> 038 * By default, the following parameter types can be passed into Java methods in any order: 039 * 040 * <h5 class='topic'>Standard top-level objects</h5> 041 * <ul> 042 * <li><b>Standard top-level objects</b> 043 * <ul> 044 * <li class='jc'>{@link HttpServletRequest} 045 * <li class='jc'>{@link RestRequest} 046 * <li class='jc'>{@link HttpServletResponse} 047 * <li class='jc'>{@link RestResponse} 048 * </ul> 049 * <li><b>Headers</b> 050 * <ul> 051 * <li class='jc'>{@link Accept} 052 * <li class='jc'>{@link AcceptCharset} 053 * <li class='jc'>{@link AcceptEncoding} 054 * <li class='jc'>{@link AcceptLanguage} 055 * <li class='jc'>{@link Authorization} 056 * <li class='jc'>{@link CacheControl} 057 * <li class='jc'>{@link Connection} 058 * <li class='jc'>{@link ContentLength} 059 * <li class='jc'>{@link ContentType} 060 * <li class='jc'>{@link Date} 061 * <li class='jc'>{@link Expect} 062 * <li class='jc'>{@link From} 063 * <li class='jc'>{@link Host} 064 * <li class='jc'>{@link IfMatch} 065 * <li class='jc'>{@link IfModifiedSince} 066 * <li class='jc'>{@link IfNoneMatch} 067 * <li class='jc'>{@link IfRange} 068 * <li class='jc'>{@link IfUnmodifiedSince} 069 * <li class='jc'>{@link MaxForwards} 070 * <li class='jc'>{@link Pragma} 071 * <li class='jc'>{@link ProxyAuthorization} 072 * <li class='jc'>{@link Range} 073 * <li class='jc'>{@link Referer} 074 * <li class='jc'>{@link TE} 075 * <li class='jc'>{@link TimeZone} 076 * <li class='jc'>{@link UserAgent} 077 * <li class='jc'>{@link Upgrade} 078 * <li class='jc'>{@link Via} 079 * <li class='jc'>{@link Warning} 080 * </ul> 081 * <li><b>Other objects</b> 082 * <ul> 083 * <li class='jc'>{@link Config} 084 * <li class='jc'>{@link InputStream} 085 * <li class='jc'>{@link Locale} 086 * <li class='jc'>{@link Messages} 087 * <li class='jc'>{@link OutputStream} 088 * <li class='jc'>{@link Parser} 089 * <li class='jc'>{@link Reader} 090 * <li class='jc'>{@link RequestBody} 091 * <li class='jc'>{@link RequestFormData} 092 * <li class='jc'>{@link RequestHeaders} 093 * <li class='jc'>{@link RequestAttributes} 094 * <li class='jc'>{@link RequestPath} 095 * <li class='jc'>{@link RequestQuery} 096 * <li class='jc'>{@link ResourceBundle} 097 * <li class='jc'>{@link RestContext} 098 * <li class='jc'>{@link ServletInputStream} 099 * <li class='jc'>{@link ServletOutputStream} 100 * <li class='jc'>{@link Swagger} 101 * <li class='jc'>{@link UriContext} 102 * <li class='jc'>{@link UriResolver} 103 * <li class='jc'>{@link Writer} 104 * </ul> 105 * </ul> 106 * 107 * <ul class='seealso'> 108 * <li class='jf'>{@link RestContext#REST_paramResolvers} 109 * <li class='link'>{@doc RestmParameters} 110 * </ul> 111 */ 112public abstract class RestMethodParam { 113 114 final RestParamType paramType; 115 final ParamInfo mpi; 116 final String name; 117 final Type type; 118 final Class<?> c; 119 120 /** 121 * Constructor. 122 * 123 * @param paramType The Swagger parameter type. 124 * @param mpi The method parameter. 125 * @param name 126 * The parameter name. 127 * Can be <jk>null</jk> if parameter doesn't have a name (e.g. the request body). 128 * @param type The object type to convert the parameter to. 129 */ 130 protected RestMethodParam(RestParamType paramType, ParamInfo mpi, String name, Type type) { 131 this.paramType = paramType; 132 this.mpi = mpi; 133 this.name = name; 134 this.type = type; 135 this.c = type instanceof Class ? (Class<?>)type : type instanceof ParameterizedType ? (Class<?>)((ParameterizedType)type).getRawType() : null; 136 } 137 138 /** 139 * Constructor. 140 * 141 * @param paramType The Swagger parameter type. 142 * @param mpi The method parameter. 143 * @param name 144 * The parameter name. 145 * Can be <jk>null</jk> if parameter doesn't have a name (e.g. the request body). 146 */ 147 protected RestMethodParam(RestParamType paramType, ParamInfo mpi, String name) { 148 this(paramType, mpi, name, mpi.getParameterType().innerType()); 149 } 150 151 /** 152 * Constructor. 153 * 154 * @param paramType The Swagger parameter type. 155 * @param mpi The method parameter. 156 */ 157 protected RestMethodParam(RestParamType paramType, ParamInfo mpi) { 158 this(paramType, mpi, null, mpi.getParameterType().innerType()); 159 } 160 161 /** 162 * Constructor. 163 * 164 * @param paramType The Swagger parameter type. 165 * @param type The object type to convert the parameter to. 166 */ 167 protected RestMethodParam(RestParamType paramType, Type type) { 168 this(paramType, null, null, type); 169 } 170 171 /** 172 * Constructor. 173 * 174 * @param paramType The Swagger parameter type. 175 * @param type The object type to convert the parameter to. 176 */ 177 protected RestMethodParam(RestParamType paramType, ClassInfo type) { 178 this(paramType, null, null, type.innerType()); 179 } 180 181 /** 182 * Constructor. 183 * 184 * @param paramType The Swagger parameter type. 185 * @param name 186 * The parameter name. 187 * Can be <jk>null</jk> if parameter doesn't have a name (e.g. the request body). 188 * @param type The object type to convert the parameter to. 189 */ 190 protected RestMethodParam(RestParamType paramType, String name, Type type) { 191 this(paramType, null, name, type); 192 } 193 194 /** 195 * Resolves the parameter object. 196 * 197 * @param req The rest request. 198 * @param res The rest response. 199 * @return The resolved object. 200 * @throws Exception Generic error occurred. 201 */ 202 public abstract Object resolve(RestRequest req, RestResponse res) throws Exception; 203 204 /** 205 * Returns the parameter class type that this parameter resolver is meant for. 206 * 207 * @return The parameter class type, or <jk>null</jk> if the type passed in isn't an instance of {@link Class}. 208 */ 209 protected Class<?> forClass() { 210 if (type instanceof Class) 211 return (Class<?>)type; 212 return null; 213 } 214 215 /** 216 * Returns the swagger parameter type for this parameter as shown in the Swagger doc. 217 * 218 * @return the swagger parameter type for this parameter. 219 */ 220 protected RestParamType getParamType() { 221 return paramType; 222 } 223 224 /** 225 * Returns the parameter info. 226 * 227 * @return The parameter info. 228 */ 229 public ParamInfo getMethodParamInfo() { 230 return mpi; 231 } 232 233 /** 234 * Returns the parameter name for this parameter as shown in the Swagger doc. 235 * 236 * @return the parameter name for this parameter. 237 */ 238 protected String getName() { 239 return name; 240 } 241 242 /** 243 * Returns the parameter class type. 244 * 245 * @return the parameter class type. 246 */ 247 public Type getType() { 248 return type; 249 } 250 251 /** 252 * Returns the parameter class type. 253 * 254 * @return the parameter class type. 255 */ 256 public Class<?> getTypeClass() { 257 return c; 258 } 259}