
io.muserver.rest.ResourceMethodParam Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of mu-server Show documentation
Show all versions of mu-server Show documentation
A simple but powerful web server framework
The newest version!
package io.muserver.rest;
import io.muserver.*;
import io.muserver.openapi.ExternalDocumentationObject;
import io.muserver.openapi.ParameterObjectBuilder;
import jakarta.ws.rs.*;
import jakarta.ws.rs.container.Suspended;
import jakarta.ws.rs.core.Context;
import jakarta.ws.rs.core.Cookie;
import jakarta.ws.rs.core.MultivaluedMap;
import jakarta.ws.rs.core.PathSegment;
import jakarta.ws.rs.ext.ParamConverter;
import jakarta.ws.rs.ext.ParamConverterProvider;
import java.io.File;
import java.io.IOException;
import java.lang.annotation.Annotation;
import java.lang.reflect.Parameter;
import java.lang.reflect.ParameterizedType;
import java.lang.reflect.Type;
import java.lang.reflect.WildcardType;
import java.util.*;
import java.util.regex.Pattern;
import java.util.stream.Collectors;
import static io.muserver.openapi.ParameterObjectBuilder.parameterObject;
import static io.muserver.openapi.SchemaObjectBuilder.schemaObjectFrom;
import static java.util.Collections.emptyList;
abstract class ResourceMethodParam {
final int index;
final Parameter parameterHandle;
final ValueSource source;
final DescriptionData descriptionData;
final boolean isRequired;
ResourceMethodParam(int index, ValueSource source, Parameter parameterHandle, DescriptionData descriptionData, boolean isRequired) {
this.index = index;
this.source = source;
this.parameterHandle = parameterHandle;
this.descriptionData = descriptionData;
this.isRequired = isRequired;
}
static ResourceMethodParam fromParameter(int index, Parameter parameterHandle, List paramConverterProviders, UriPattern methodPattern) {
Pattern pattern = null;
ValueSource source = getSource(parameterHandle);
boolean isRequired = source == ValueSource.PATH_PARAM || hasDeclared(parameterHandle, Required.class);
if (source == ValueSource.MESSAGE_BODY) {
DescriptionData descriptionData = DescriptionData.fromAnnotation(parameterHandle, null);
return new MessageBodyParam(index, source, parameterHandle, descriptionData, isRequired);
} else if (source == ValueSource.CONTEXT) {
return new ContextParam(index, source, parameterHandle);
} else if (source == ValueSource.SUSPENDED) {
return new SuspendedParam(index, source, parameterHandle);
} else {
boolean encodedRequested = hasDeclared(parameterHandle, Encoded.class);
boolean isDeprecated = hasDeclared(parameterHandle, Deprecated.class);
ParamConverter> converter = getParamConverter(parameterHandle, paramConverterProviders);
boolean lazyDefaultValue = converter.getClass().getDeclaredAnnotation(ParamConverter.Lazy.class) != null;
boolean explicitDefault = hasDeclared(parameterHandle, DefaultValue.class);
Object defaultValue = getDefaultValue(parameterHandle, converter, lazyDefaultValue);
isRequired |= (!explicitDefault && parameterHandle.getType().isPrimitive());
String key = source == ValueSource.COOKIE_PARAM ? parameterHandle.getDeclaredAnnotation(CookieParam.class).value()
: source == ValueSource.HEADER_PARAM ? parameterHandle.getDeclaredAnnotation(HeaderParam.class).value()
: source == ValueSource.MATRIX_PARAM ? parameterHandle.getDeclaredAnnotation(MatrixParam.class).value()
: source == ValueSource.FORM_PARAM ? parameterHandle.getDeclaredAnnotation(FormParam.class).value()
: source == ValueSource.PATH_PARAM ? parameterHandle.getDeclaredAnnotation(PathParam.class).value()
: source == ValueSource.QUERY_PARAM ? parameterHandle.getDeclaredAnnotation(QueryParam.class).value()
: "";
if (key.length() == 0) {
throw new WebApplicationException("No parameter specified for the " + source + " in " + parameterHandle);
}
if (source == ValueSource.PATH_PARAM && methodPattern != null) {
String regex = methodPattern.regexFor(key);
if (regex != null) {
pattern = Pattern.compile(regex);
}
}
DescriptionData descriptionData = DescriptionData.fromAnnotation(parameterHandle, key);
return new RequestBasedParam(index, source, parameterHandle, defaultValue, encodedRequested, lazyDefaultValue, converter, descriptionData, key, isDeprecated, isRequired, pattern, explicitDefault);
}
}
static class RequestBasedParam extends ResourceMethodParam {
private final Object defaultValue;
final boolean encodedRequested;
private final boolean lazyDefaultValue;
private final ParamConverter paramConverter;
final String key;
final boolean isDeprecated;
private final Pattern pattern;
private final boolean explicitDefault;
ParameterObjectBuilder createDocumentationBuilder() {
ParameterObjectBuilder builder = parameterObject()
.withIn(source.openAPIIn)
.withRequired(isRequired)
.withDeprecated(isDeprecated ? true : null)
.withName(key);
ExternalDocumentationObject externalDoc = null;
if (descriptionData != null) {
String desc = descriptionData.summaryAndDescription();
builder
.withDescription(key.equals(desc) ? null : desc)
.withExample(descriptionData.example);
externalDoc = descriptionData.externalDocumentation;
}
Pattern patternIfNotDefault = this.pattern == null || UriPattern.DEFAULT_CAPTURING_GROUP_PATTERN.equals(this.pattern.pattern()) ? null : this.pattern;
return builder.withSchema(
schemaObjectFrom(parameterHandle.getType(), parameterHandle.getParameterizedType(), isRequired)
.withDefaultValue(source == ValueSource.PATH_PARAM || !hasExplicitDefault() ? null : defaultValue())
.withExternalDocs(externalDoc)
.withPattern(patternIfNotDefault)
.build()
);
}
RequestBasedParam(int index, ValueSource source, Parameter parameterHandle, Object defaultValue, boolean encodedRequested, boolean lazyDefaultValue, ParamConverter paramConverter, DescriptionData descriptionData, String key, boolean isDeprecated, boolean isRequired, Pattern pattern, boolean explicitDefault) {
super(index, source, parameterHandle, descriptionData, isRequired);
this.defaultValue = defaultValue;
this.encodedRequested = encodedRequested;
this.lazyDefaultValue = lazyDefaultValue;
this.paramConverter = paramConverter;
this.key = key;
this.isDeprecated = isDeprecated;
this.pattern = pattern;
this.explicitDefault = explicitDefault;
}
/**
* @return True if the API author has explicitly set a default value for the param
* using the {@link DefaultValue} annotation.
*/
public boolean hasExplicitDefault() {
return explicitDefault;
}
public Object defaultValue() {
boolean skipConverter = defaultValue != null && !lazyDefaultValue;
return convertValue(parameterHandle, paramConverter, skipConverter, defaultValue);
}
public Object getValue(JaxRSRequest jaxRequest, RequestMatcher.MatchedMethod matchedMethod, CollectionParameterStrategy cps) throws IOException {
MuRequest muRequest = jaxRequest.muRequest;
Class> paramClass = parameterHandle.getType();
if (UploadedFile.class.isAssignableFrom(paramClass)) {
return muRequest.uploadedFile(key);
} else if (File.class.isAssignableFrom(paramClass)) {
UploadedFile uf = muRequest.uploadedFile(key);
return uf == null ? null : uf.asFile();
} else if (Collection.class.isAssignableFrom(paramClass)) {
Type t = parameterHandle.getParameterizedType();
if (t instanceof ParameterizedType) {
Type[] actualTypeArguments = ((ParameterizedType) t).getActualTypeArguments();
if (actualTypeArguments.length == 1) {
Type argType = actualTypeArguments[0];
boolean isUploadedFileList = (argType instanceof Class> && UploadedFile.class.isAssignableFrom((Class>) argType));
if (!isUploadedFileList && argType instanceof WildcardType) {
WildcardType wt = (WildcardType) argType;
for (Type upperBound : wt.getUpperBounds()) {
if (upperBound instanceof Class> && UploadedFile.class.isAssignableFrom((Class>) upperBound)) {
isUploadedFileList = true;
break;
}
}
}
if (isUploadedFileList) {
List uploadedFiles = muRequest.uploadedFiles(key);
if (Set.class.isAssignableFrom(paramClass)) {
return new HashSet<>(uploadedFiles);
}
return uploadedFiles;
}
}
}
}
if (paramClass.isAssignableFrom(PathSegment.class)) {
PathSegment seg = matchedMethod.pathParams.get(key);
if (seg != null && encodedRequested) {
return ((MuPathSegment) seg).toEncoded();
}
return seg;
} else if (paramClass.equals(Cookie.class)) {
List cookieValues = cookieValue(muRequest, key);
return cookieValues.isEmpty() ? null : new Cookie(key, cookieValues.get(0));
} else if (paramClass.equals(io.muserver.Cookie.class)) {
List cookieValues = cookieValue(muRequest, key);
return cookieValues.isEmpty() ? null : new CookieBuilder().withName(key).withValue(cookieValues.get(0)).build();
}
Collection
© 2015 - 2025 Weber Informatics LLC | Privacy Policy