You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@juneau.apache.org by ja...@apache.org on 2022/07/09 14:07:24 UTC
[juneau] 01/01: Add @Query(def) annotation.
This is an automated email from the ASF dual-hosted git repository.
jamesbognar pushed a commit to branch jbFixRestNpe
in repository https://gitbox.apache.org/repos/asf/juneau.git
commit 848c9e20563e75908623c9e01e4d570873943e5c
Author: JamesBognar <ja...@salesforce.com>
AuthorDate: Sat Jul 9 10:07:04 2022 -0400
Add @Query(def) annotation.
---
.../apache/juneau/http/annotation/FormData.java | 7 ++
.../juneau/http/annotation/FormDataAnnotation.java | 33 ++++++-
.../org/apache/juneau/http/annotation/Header.java | 7 ++
.../juneau/http/annotation/HeaderAnnotation.java | 33 ++++++-
.../org/apache/juneau/http/annotation/Path.java | 7 ++
.../juneau/http/annotation/PathAnnotation.java | 33 ++++++-
.../org/apache/juneau/http/annotation/Query.java | 7 ++
.../juneau/http/annotation/QueryAnnotation.java | 38 +++++--
.../org/apache/juneau/rest/arg/FormDataArg.java | 5 +-
.../java/org/apache/juneau/rest/arg/HeaderArg.java | 5 +-
.../java/org/apache/juneau/rest/arg/PathArg.java | 5 +-
.../java/org/apache/juneau/rest/arg/QueryArg.java | 8 +-
.../juneau/rest/httppart/RequestFormParam.java | 13 +++
.../apache/juneau/rest/httppart/RequestHeader.java | 14 ++-
.../juneau/rest/httppart/RequestPathParam.java | 14 ++-
.../juneau/rest/httppart/RequestQueryParam.java | 14 ++-
.../http/annotation/FormDataAnnotation_Test.java | 5 +
.../http/annotation/HeaderAnnotation_Test.java | 5 +
.../http/annotation/PathAnnotation_Test.java | 5 +
.../http/annotation/QueryAnnotation_Test.java | 5 +
.../juneau/rest/annotation/FormData_Test.java | 108 ++++++++++++++++++++
.../apache/juneau/rest/annotation/Header_Test.java | 110 +++++++++++++++++++++
.../apache/juneau/rest/annotation/Query_Test.java | 103 +++++++++++++++++++
23 files changed, 560 insertions(+), 24 deletions(-)
diff --git a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/http/annotation/FormData.java b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/http/annotation/FormData.java
index 38171ac22..ddc248e9c 100644
--- a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/http/annotation/FormData.java
+++ b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/http/annotation/FormData.java
@@ -122,6 +122,13 @@ import org.apache.juneau.oapi.*;
@ContextApply(FormDataAnnotation.Applier.class)
public @interface FormData {
+ /**
+ * Default value for this parameter.
+ *
+ * @return The annotation value.
+ */
+ String def() default "";
+
/**
* FORM parameter name.
*
diff --git a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/http/annotation/FormDataAnnotation.java b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/http/annotation/FormDataAnnotation.java
index 171f5ecc4..90aa0ff37 100644
--- a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/http/annotation/FormDataAnnotation.java
+++ b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/http/annotation/FormDataAnnotation.java
@@ -96,6 +96,18 @@ public class FormDataAnnotation {
return n;
}
+ /**
+ * Finds the default value from the specified list of annotations.
+ *
+ * @param pi The parameter.
+ * @return The last matching default value, or {@link Value#empty()} if not found.
+ */
+ public static Value<String> findDef(ParamInfo pi) {
+ Value<String> n = Value.empty();
+ pi.forEachAnnotation(FormData.class, x -> isNotEmpty(x.def()), x -> n.set(x.def()));
+ return n;
+ }
+
//-----------------------------------------------------------------------------------------------------------------
// Builder
//-----------------------------------------------------------------------------------------------------------------
@@ -112,7 +124,7 @@ public class FormDataAnnotation {
Class<? extends HttpPartParser> parser = HttpPartParser.Void.class;
Class<? extends HttpPartSerializer> serializer = HttpPartSerializer.Void.class;
Schema schema = SchemaAnnotation.DEFAULT;
- String name="", value="";
+ String def="", name="", value="";
/**
* Constructor.
@@ -130,6 +142,17 @@ public class FormDataAnnotation {
return new Impl(this);
}
+ /**
+ * Sets the {@link FormData#def} property on this annotation.
+ *
+ * @param value The new value for this property.
+ * @return This object.
+ */
+ public Builder def(String value) {
+ this.def = value;
+ return this;
+ }
+
/**
* Sets the {@link FormData#name} property on this annotation.
*
@@ -228,11 +251,12 @@ public class FormDataAnnotation {
private final Class<? extends HttpPartParser> parser;
private final Class<? extends HttpPartSerializer> serializer;
- private final String name, value;
+ private final String name, value, def;
private final Schema schema;
Impl(Builder b) {
super(b);
+ this.def = b.def;
this.name = b.name;
this.parser = b.parser;
this.schema = b.schema;
@@ -241,6 +265,11 @@ public class FormDataAnnotation {
postConstruct();
}
+ @Override /* FormData */
+ public String def() {
+ return def;
+ }
+
@Override /* FormData */
public String name() {
return name;
diff --git a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/http/annotation/Header.java b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/http/annotation/Header.java
index 5292cc8bb..0057df7d7 100644
--- a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/http/annotation/Header.java
+++ b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/http/annotation/Header.java
@@ -88,6 +88,13 @@ import org.apache.juneau.oapi.*;
@ContextApply(HeaderAnnotation.Applier.class)
public @interface Header {
+ /**
+ * Default value for this parameter.
+ *
+ * @return The annotation value.
+ */
+ String def() default "";
+
/**
* HTTP header name.
* <p>
diff --git a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/http/annotation/HeaderAnnotation.java b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/http/annotation/HeaderAnnotation.java
index 8d4154542..1358a0d30 100644
--- a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/http/annotation/HeaderAnnotation.java
+++ b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/http/annotation/HeaderAnnotation.java
@@ -97,6 +97,18 @@ public class HeaderAnnotation {
return n;
}
+ /**
+ * Finds the default value from the specified list of annotations.
+ *
+ * @param pi The parameter.
+ * @return The last matching default value, or {@link Value#empty()} if not found.
+ */
+ public static Value<String> findDef(ParamInfo pi) {
+ Value<String> n = Value.empty();
+ pi.forEachAnnotation(Header.class, x -> isNotEmpty(x.def()), x -> n.set(x.def()));
+ return n;
+ }
+
//-----------------------------------------------------------------------------------------------------------------
// Builder
//-----------------------------------------------------------------------------------------------------------------
@@ -113,7 +125,7 @@ public class HeaderAnnotation {
Class<? extends HttpPartParser> parser = HttpPartParser.Void.class;
Class<? extends HttpPartSerializer> serializer = HttpPartSerializer.Void.class;
Schema schema = SchemaAnnotation.DEFAULT;
- String name="", value="";
+ String name="", value="", def="";
/**
* Constructor.
@@ -131,6 +143,17 @@ public class HeaderAnnotation {
return new Impl(this);
}
+ /**
+ * Sets the {@link Header#def} property on this annotation.
+ *
+ * @param value The new value for this property.
+ * @return This object.
+ */
+ public Builder def(String value) {
+ this.def = value;
+ return this;
+ }
+
/**
* Sets the {@link Header#name} property on this annotation.
*
@@ -229,11 +252,12 @@ public class HeaderAnnotation {
private final Class<? extends HttpPartParser> parser;
private final Class<? extends HttpPartSerializer> serializer;
- private final String name, value;
+ private final String name, value, def;
private final Schema schema;
Impl(Builder b) {
super(b);
+ this.def = b.def;
this.name = b.name;
this.parser = b.parser;
this.schema = b.schema;
@@ -242,6 +266,11 @@ public class HeaderAnnotation {
postConstruct();
}
+ @Override /* Header */
+ public String def() {
+ return def;
+ }
+
@Override /* Header */
public String name() {
return name;
diff --git a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/http/annotation/Path.java b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/http/annotation/Path.java
index d78dd307f..e87eed997 100644
--- a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/http/annotation/Path.java
+++ b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/http/annotation/Path.java
@@ -85,6 +85,13 @@ import org.apache.juneau.oapi.*;
@ContextApply(PathAnnotation.Applier.class)
public @interface Path {
+ /**
+ * Default value for this parameter.
+ *
+ * @return The annotation value.
+ */
+ String def() default "";
+
/**
* URL path variable name.
*
diff --git a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/http/annotation/PathAnnotation.java b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/http/annotation/PathAnnotation.java
index 32c92609d..44d06f760 100644
--- a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/http/annotation/PathAnnotation.java
+++ b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/http/annotation/PathAnnotation.java
@@ -96,6 +96,18 @@ public class PathAnnotation {
return n;
}
+ /**
+ * Finds the default value from the specified list of annotations.
+ *
+ * @param pi The parameter.
+ * @return The last matching default value, or {@link Value#empty()} if not found.
+ */
+ public static Value<String> findDef(ParamInfo pi) {
+ Value<String> n = Value.empty();
+ pi.forEachAnnotation(Path.class, x -> isNotEmpty(x.def()), x -> n.set(x.def()));
+ return n;
+ }
+
//-----------------------------------------------------------------------------------------------------------------
// Builder
//-----------------------------------------------------------------------------------------------------------------
@@ -112,7 +124,7 @@ public class PathAnnotation {
Class<? extends HttpPartParser> parser = HttpPartParser.Void.class;
Class<? extends HttpPartSerializer> serializer = HttpPartSerializer.Void.class;
Schema schema = SchemaAnnotation.DEFAULT;
- String name="", value="";
+ String name="", value="", def="";
/**
* Constructor.
@@ -141,6 +153,17 @@ public class PathAnnotation {
return this;
}
+ /**
+ * Sets the {@link Path#name} property on this annotation.
+ *
+ * @param value The new value for this property.
+ * @return This object.
+ */
+ public Builder def(String value) {
+ this.def = value;
+ return this;
+ }
+
/**
* Sets the {@link Path#parser} property on this annotation.
*
@@ -228,11 +251,12 @@ public class PathAnnotation {
private final Class<? extends HttpPartParser> parser;
private final Class<? extends HttpPartSerializer> serializer;
- private final String name, value;
+ private final String name, value, def;
private final Schema schema;
Impl(Builder b) {
super(b);
+ this.def = b.def;
this.name = b.name;
this.parser = b.parser;
this.schema = b.schema;
@@ -246,6 +270,11 @@ public class PathAnnotation {
return name;
}
+ @Override /* Path */
+ public String def() {
+ return def;
+ }
+
@Override /* Path */
public Class<? extends HttpPartParser> parser() {
return parser;
diff --git a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/http/annotation/Query.java b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/http/annotation/Query.java
index 01bf7fa41..05f1f4dd2 100644
--- a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/http/annotation/Query.java
+++ b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/http/annotation/Query.java
@@ -96,6 +96,13 @@ import org.apache.juneau.oapi.*;
@ContextApply(QueryAnnotation.Applier.class)
public @interface Query {
+ /**
+ * Default value for this parameter.
+ *
+ * @return The annotation value.
+ */
+ String def() default "";
+
/**
* URL query parameter name.
*
diff --git a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/http/annotation/QueryAnnotation.java b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/http/annotation/QueryAnnotation.java
index f9fa1d108..3959b1972 100644
--- a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/http/annotation/QueryAnnotation.java
+++ b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/http/annotation/QueryAnnotation.java
@@ -81,10 +81,7 @@ public class QueryAnnotation {
}
/**
- * Finds the name from the specified lists of annotations.
- *
- * <p>
- * The last matching name found is returned.
+ * Finds the name from the specified list of annotations.
*
* @param pi The parameter.
* @return The last matching name, or {@link Value#empty()} if not found.
@@ -96,6 +93,18 @@ public class QueryAnnotation {
return n;
}
+ /**
+ * Finds the default value from the specified list of annotations.
+ *
+ * @param pi The parameter.
+ * @return The last matching default value, or {@link Value#empty()} if not found.
+ */
+ public static Value<String> findDef(ParamInfo pi) {
+ Value<String> n = Value.empty();
+ pi.forEachAnnotation(Query.class, x -> isNotEmpty(x.def()), x -> n.set(x.def()));
+ return n;
+ }
+
//-----------------------------------------------------------------------------------------------------------------
// Builder
//-----------------------------------------------------------------------------------------------------------------
@@ -112,7 +121,7 @@ public class QueryAnnotation {
Class<? extends HttpPartParser> parser = HttpPartParser.Void.class;
Class<? extends HttpPartSerializer> serializer = HttpPartSerializer.Void.class;
Schema schema = SchemaAnnotation.DEFAULT;
- String name="", value="";
+ String name="", value="", def="";
/**
* Constructor.
@@ -130,6 +139,17 @@ public class QueryAnnotation {
return new Impl(this);
}
+ /**
+ * Sets the {@link Query#def} property on this annotation.
+ *
+ * @param value The new value for this property.
+ * @return This object.
+ */
+ public Builder def(String value) {
+ this.def = value;
+ return this;
+ }
+
/**
* Sets the {@link Query#name} property on this annotation.
*
@@ -228,7 +248,7 @@ public class QueryAnnotation {
private final Class<? extends HttpPartParser> parser;
private final Class<? extends HttpPartSerializer> serializer;
- private final String name, value;
+ private final String name, value, def;
private final Schema schema;
Impl(Builder b) {
@@ -238,6 +258,7 @@ public class QueryAnnotation {
this.schema = b.schema;
this.serializer = b.serializer;
this.value = b.value;
+ this.def = b.def;
postConstruct();
}
@@ -265,6 +286,11 @@ public class QueryAnnotation {
public String value() {
return value;
}
+
+ @Override /* Query */
+ public String def() {
+ return def;
+ }
}
//-----------------------------------------------------------------------------------------------------------------
diff --git a/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/arg/FormDataArg.java b/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/arg/FormDataArg.java
index 20b8f3bd8..29c1655c1 100644
--- a/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/arg/FormDataArg.java
+++ b/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/arg/FormDataArg.java
@@ -57,7 +57,7 @@ public class FormDataArg implements RestOpArg {
private final boolean multi;
private final HttpPartParser partParser;
private final HttpPartSchema schema;
- private final String name;
+ private final String name, def;
private final ClassInfo type;
/**
@@ -81,6 +81,7 @@ public class FormDataArg implements RestOpArg {
*/
protected FormDataArg(ParamInfo pi, AnnotationWorkList annotations) {
this.name = findName(pi).orElseThrow(()->new ArgException(pi, "@FormData used without name or value"));
+ this.def = findDef(pi).orElse(null);
this.type = pi.getParameterType();
this.schema = HttpPartSchema.create(FormData.class, pi);
Class<? extends HttpPartParser> pp = schema.getParser();
@@ -113,6 +114,6 @@ public class FormDataArg implements RestOpArg {
return req.getBeanSession().convertToType(m, cm);
}
- return rh.getLast(name).parser(ps).schema(schema).as(type.innerType()).orElse(null);
+ return rh.getLast(name).parser(ps).schema(schema).def(def).as(type.innerType()).orElse(null);
}
}
diff --git a/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/arg/HeaderArg.java b/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/arg/HeaderArg.java
index e7d0ad0d1..4a1f211ad 100644
--- a/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/arg/HeaderArg.java
+++ b/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/arg/HeaderArg.java
@@ -98,7 +98,7 @@ public class HeaderArg implements RestOpArg {
private final HttpPartParser partParser;
private final HttpPartSchema schema;
private final boolean multi;
- private final String name;
+ private final String name, def;
private final ClassInfo type;
/**
@@ -122,6 +122,7 @@ public class HeaderArg implements RestOpArg {
*/
protected HeaderArg(ParamInfo pi, AnnotationWorkList annotations) {
this.name = findName(pi).orElseThrow(() -> new ArgException(pi, "@Header used without name or value"));
+ this.def = findDef(pi).orElse(null);
this.type = pi.getParameterType();
this.schema = HttpPartSchema.create(Header.class, pi);
Class<? extends HttpPartParser> pp = schema.getParser();
@@ -154,6 +155,6 @@ public class HeaderArg implements RestOpArg {
return req.getBeanSession().convertToType(m, cm);
}
- return rh.getLast(name).parser(ps).schema(schema).as(type.innerType()).orElse(null);
+ return rh.getLast(name).parser(ps).schema(schema).def(def).as(type.innerType()).orElse(null);
}
}
diff --git a/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/arg/PathArg.java b/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/arg/PathArg.java
index 3433e9ebd..69b80d384 100644
--- a/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/arg/PathArg.java
+++ b/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/arg/PathArg.java
@@ -50,7 +50,7 @@ import org.apache.juneau.rest.util.*;
public class PathArg implements RestOpArg {
private final HttpPartParser partParser;
private final HttpPartSchema schema;
- private final String name;
+ private final String name, def;
private final Type type;
/**
@@ -76,6 +76,7 @@ public class PathArg implements RestOpArg {
*/
protected PathArg(ParamInfo paramInfo, AnnotationWorkList annotations, UrlPathMatcher pathMatcher) {
this.name = getName(paramInfo, pathMatcher);
+ this.def = findDef(paramInfo).orElse(null);
this.type = paramInfo.getParameterType().innerType();
this.schema = HttpPartSchema.create(Path.class, paramInfo);
Class<? extends HttpPartParser> pp = schema.getParser();
@@ -119,6 +120,6 @@ public class PathArg implements RestOpArg {
return req.getBeanSession().convertToType(m, type);
}
HttpPartParserSession ps = partParser == null ? req.getPartParserSession() : partParser.getPartSession();
- return req.getPathParams().get(name).parser(ps).schema(schema).as(type).orElse(null);
+ return req.getPathParams().get(name).parser(ps).schema(schema).def(def).as(type).orElse(null);
}
}
diff --git a/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/arg/QueryArg.java b/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/arg/QueryArg.java
index a8938ed2c..2e143726f 100644
--- a/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/arg/QueryArg.java
+++ b/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/arg/QueryArg.java
@@ -14,6 +14,7 @@ package org.apache.juneau.rest.arg;
import static org.apache.juneau.internal.CollectionUtils.*;
import static org.apache.juneau.internal.StringUtils.*;
+import static org.apache.juneau.http.annotation.QueryAnnotation.*;
import java.util.*;
@@ -56,7 +57,7 @@ public class QueryArg implements RestOpArg {
private final boolean multi;
private final HttpPartParser partParser;
private final HttpPartSchema schema;
- private final String name;
+ private final String name, def;
private final ClassInfo type;
/**
@@ -79,7 +80,8 @@ public class QueryArg implements RestOpArg {
* @param annotations The annotations to apply to any new part parsers.
*/
protected QueryArg(ParamInfo pi, AnnotationWorkList annotations) {
- this.name = QueryAnnotation.findName(pi).orElseThrow(() -> new ArgException(pi, "@Query used without name or value"));
+ this.name = findName(pi).orElseThrow(() -> new ArgException(pi, "@Query used without name or value"));
+ this.def = findDef(pi).orElse(null);
this.type = pi.getParameterType();
this.schema = HttpPartSchema.create(Query.class, pi);
Class<? extends HttpPartParser> pp = schema.getParser();
@@ -112,6 +114,6 @@ public class QueryArg implements RestOpArg {
return req.getBeanSession().convertToType(m, cm);
}
- return rh.getLast(name).parser(ps).schema(schema).as(type.innerType()).orElse(null);
+ return rh.getLast(name).parser(ps).schema(schema).def(def).as(type.innerType()).orElse(null);
}
}
diff --git a/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/httppart/RequestFormParam.java b/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/httppart/RequestFormParam.java
index 1e8b914ee..b790a71dc 100644
--- a/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/httppart/RequestFormParam.java
+++ b/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/httppart/RequestFormParam.java
@@ -135,6 +135,19 @@ public class RequestFormParam extends RequestHttpPart implements NameValuePair {
return value;
}
+
+ /**
+ * Sets a default value for this part.
+ *
+ * @param def The default value.
+ * @return This object.
+ */
+ public RequestFormParam def(String def) {
+ if (getValue() == null)
+ value = def;
+ return this;
+ }
+
//------------------------------------------------------------------------------------------------------------------
// Assertions
//------------------------------------------------------------------------------------------------------------------
diff --git a/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/httppart/RequestHeader.java b/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/httppart/RequestHeader.java
index 45459778e..ad147958c 100644
--- a/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/httppart/RequestHeader.java
+++ b/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/httppart/RequestHeader.java
@@ -95,7 +95,7 @@ import org.apache.juneau.rest.*;
*/
public class RequestHeader extends RequestHttpPart implements Header {
- private final String value;
+ private String value;
/**
* Constructor.
@@ -109,6 +109,18 @@ public class RequestHeader extends RequestHttpPart implements Header {
this.value = value;
}
+ /**
+ * Sets a default value for this part.
+ *
+ * @param def The default value.
+ * @return This object.
+ */
+ public RequestHeader def(String def) {
+ if (value == null)
+ value = def;
+ return this;
+ }
+
//------------------------------------------------------------------------------------------------------------------
// Retrievers
//------------------------------------------------------------------------------------------------------------------
diff --git a/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/httppart/RequestPathParam.java b/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/httppart/RequestPathParam.java
index 838e390a2..74289917c 100644
--- a/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/httppart/RequestPathParam.java
+++ b/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/httppart/RequestPathParam.java
@@ -90,7 +90,7 @@ import org.apache.juneau.rest.*;
*/
public class RequestPathParam extends RequestHttpPart implements NameValuePair {
- private final String value;
+ private String value;
/**
* Constructor.
@@ -104,6 +104,18 @@ public class RequestPathParam extends RequestHttpPart implements NameValuePair {
this.value = value;
}
+ /**
+ * Sets a default value for this part.
+ *
+ * @param def The default value.
+ * @return This object.
+ */
+ public RequestPathParam def(String def) {
+ if (value == null)
+ value = def;
+ return this;
+ }
+
//------------------------------------------------------------------------------------------------------------------
// Retrievers
//------------------------------------------------------------------------------------------------------------------
diff --git a/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/httppart/RequestQueryParam.java b/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/httppart/RequestQueryParam.java
index b094192d1..5c1b8e09c 100644
--- a/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/httppart/RequestQueryParam.java
+++ b/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/httppart/RequestQueryParam.java
@@ -90,7 +90,7 @@ import org.apache.juneau.rest.*;
*/
public class RequestQueryParam extends RequestHttpPart implements NameValuePair {
- private final String value;
+ private String value;
/**
* Constructor.
@@ -104,6 +104,18 @@ public class RequestQueryParam extends RequestHttpPart implements NameValuePair
this.value = value;
}
+ /**
+ * Sets a default value for this part.
+ *
+ * @param def The default value.
+ * @return This object.
+ */
+ public RequestQueryParam def(String def) {
+ if (value == null)
+ value = def;
+ return this;
+ }
+
//------------------------------------------------------------------------------------------------------------------
// Retrievers
//------------------------------------------------------------------------------------------------------------------
diff --git a/juneau-utest/src/test/java/org/apache/juneau/http/annotation/FormDataAnnotation_Test.java b/juneau-utest/src/test/java/org/apache/juneau/http/annotation/FormDataAnnotation_Test.java
index 8919f36e8..78c9ab788 100644
--- a/juneau-utest/src/test/java/org/apache/juneau/http/annotation/FormDataAnnotation_Test.java
+++ b/juneau-utest/src/test/java/org/apache/juneau/http/annotation/FormDataAnnotation_Test.java
@@ -32,6 +32,7 @@ public class FormDataAnnotation_Test {
//------------------------------------------------------------------------------------------------------------------
FormData a1 = FormDataAnnotation.create()
+ .def("def")
.name("name")
.on("on")
.onClass(X1.class)
@@ -41,6 +42,7 @@ public class FormDataAnnotation_Test {
.build();
FormData a2 = FormDataAnnotation.create()
+ .def("def")
.name("name")
.on("on")
.onClass(X1.class)
@@ -53,6 +55,7 @@ public class FormDataAnnotation_Test {
public void a01_basic() {
assertObject(a1).asJson().isMatches(""
+ "{"
+ + "def:'def',"
+ "name:'name',"
+ "on:['on'],"
+ "onClass:['org.apache.juneau.http.annotation.FormDataAnnotation_Test$X1'],"
@@ -112,6 +115,7 @@ public class FormDataAnnotation_Test {
//------------------------------------------------------------------------------------------------------------------
@FormData(
+ def="def",
name="name",
on="on",
onClass=X1.class,
@@ -123,6 +127,7 @@ public class FormDataAnnotation_Test {
FormData d1 = D1.class.getAnnotationsByType(FormData.class)[0];
@FormData(
+ def="def",
name="name",
on="on",
onClass=X1.class,
diff --git a/juneau-utest/src/test/java/org/apache/juneau/http/annotation/HeaderAnnotation_Test.java b/juneau-utest/src/test/java/org/apache/juneau/http/annotation/HeaderAnnotation_Test.java
index 09c779f21..371c436c0 100644
--- a/juneau-utest/src/test/java/org/apache/juneau/http/annotation/HeaderAnnotation_Test.java
+++ b/juneau-utest/src/test/java/org/apache/juneau/http/annotation/HeaderAnnotation_Test.java
@@ -32,6 +32,7 @@ public class HeaderAnnotation_Test {
//------------------------------------------------------------------------------------------------------------------
Header a1 = HeaderAnnotation.create()
+ .def("def")
.name("name")
.on("on")
.onClass(X1.class)
@@ -41,6 +42,7 @@ public class HeaderAnnotation_Test {
.build();
Header a2 = HeaderAnnotation.create()
+ .def("def")
.name("name")
.on("on")
.onClass(X1.class)
@@ -53,6 +55,7 @@ public class HeaderAnnotation_Test {
public void a01_basic() {
assertObject(a1).asJson().isMatches(""
+ "{"
+ + "def:'def',"
+ "name:'name',"
+ "on:['on'],"
+ "onClass:['"+CNAME+"$X1'],"
@@ -112,6 +115,7 @@ public class HeaderAnnotation_Test {
//------------------------------------------------------------------------------------------------------------------
@Header(
+ def="def",
name="name",
on="on",
onClass=X1.class,
@@ -123,6 +127,7 @@ public class HeaderAnnotation_Test {
Header d1 = D1.class.getAnnotationsByType(Header.class)[0];
@Header(
+ def="def",
name="name",
on="on",
onClass=X1.class,
diff --git a/juneau-utest/src/test/java/org/apache/juneau/http/annotation/PathAnnotation_Test.java b/juneau-utest/src/test/java/org/apache/juneau/http/annotation/PathAnnotation_Test.java
index 0f1506f38..797475461 100644
--- a/juneau-utest/src/test/java/org/apache/juneau/http/annotation/PathAnnotation_Test.java
+++ b/juneau-utest/src/test/java/org/apache/juneau/http/annotation/PathAnnotation_Test.java
@@ -32,6 +32,7 @@ public class PathAnnotation_Test {
//------------------------------------------------------------------------------------------------------------------
Path a1 = PathAnnotation.create()
+ .def("def")
.name("name")
.on("on")
.onClass(X1.class)
@@ -41,6 +42,7 @@ public class PathAnnotation_Test {
.build();
Path a2 = PathAnnotation.create()
+ .def("def")
.name("name")
.on("on")
.onClass(X1.class)
@@ -53,6 +55,7 @@ public class PathAnnotation_Test {
public void a01_basic() {
assertObject(a1).asJson().isMatches(""
+ "{"
+ + "def:'def',"
+ "name:'name',"
+ "on:['on'],"
+ "onClass:['"+CNAME+"$X1'],"
@@ -112,6 +115,7 @@ public class PathAnnotation_Test {
//------------------------------------------------------------------------------------------------------------------
@Path(
+ def="def",
name="name",
on="on",
onClass=X1.class,
@@ -123,6 +127,7 @@ public class PathAnnotation_Test {
Path d1 = D1.class.getAnnotationsByType(Path.class)[0];
@Path(
+ def="def",
name="name",
on="on",
onClass=X1.class,
diff --git a/juneau-utest/src/test/java/org/apache/juneau/http/annotation/QueryAnnotation_Test.java b/juneau-utest/src/test/java/org/apache/juneau/http/annotation/QueryAnnotation_Test.java
index 40afced92..7256e7cb4 100644
--- a/juneau-utest/src/test/java/org/apache/juneau/http/annotation/QueryAnnotation_Test.java
+++ b/juneau-utest/src/test/java/org/apache/juneau/http/annotation/QueryAnnotation_Test.java
@@ -32,6 +32,7 @@ public class QueryAnnotation_Test {
//------------------------------------------------------------------------------------------------------------------
Query a1 = QueryAnnotation.create()
+ .def("def")
.name("name")
.on("on")
.onClass(X1.class)
@@ -41,6 +42,7 @@ public class QueryAnnotation_Test {
.build();
Query a2 = QueryAnnotation.create()
+ .def("def")
.name("name")
.on("on")
.onClass(X1.class)
@@ -53,6 +55,7 @@ public class QueryAnnotation_Test {
public void a01_basic() {
assertObject(a1).asJson().isMatches(""
+ "{"
+ + "def:'def',"
+ "name:'name',"
+ "on:['on'],"
+ "onClass:['"+CNAME+"$X1'],"
@@ -112,6 +115,7 @@ public class QueryAnnotation_Test {
//------------------------------------------------------------------------------------------------------------------
@Query(
+ def="def",
name="name",
on="on",
onClass=X1.class,
@@ -123,6 +127,7 @@ public class QueryAnnotation_Test {
Query d1 = D1.class.getAnnotationsByType(Query.class)[0];
@Query(
+ def="def",
name="name",
on="on",
onClass=X1.class,
diff --git a/juneau-utest/src/test/java/org/apache/juneau/rest/annotation/FormData_Test.java b/juneau-utest/src/test/java/org/apache/juneau/rest/annotation/FormData_Test.java
index 80f614739..d5a572046 100644
--- a/juneau-utest/src/test/java/org/apache/juneau/rest/annotation/FormData_Test.java
+++ b/juneau-utest/src/test/java/org/apache/juneau/rest/annotation/FormData_Test.java
@@ -211,4 +211,112 @@ public class FormData_Test {
.assertCode().is(200)
.assertContent().is("null");
}
+
+ //------------------------------------------------------------------------------------------------------------------
+ // Default form data parameter.
+ //------------------------------------------------------------------------------------------------------------------
+
+ @Rest(serializers=SimpleJsonSerializer.class)
+ public static class F {
+ @RestPost
+ public Object a1(@FormData(name="f1",def="1") Integer f1) throws Exception {
+ assertNotNull(f1);
+ return f1;
+ }
+ @RestPost
+ public Object a2(@FormData(name="f1",def="1") Optional<Integer> f1) throws Exception {
+ assertNotNull(f1);
+ return f1;
+ }
+ @RestPost
+ public Object b1(@FormData(name="f1",def="a=2,b=bar") ABean f1) throws Exception {
+ assertNotNull(f1);
+ return f1;
+ }
+ @RestPost
+ public Object b2(@FormData(name="f1",def="a=2,b=bar") Optional<ABean> f1) throws Exception {
+ assertNotNull(f1);
+ return f1;
+ }
+ @RestPost
+ public Object c1(@FormData(name="f1",def="@((a=2,b=bar))") List<ABean> f1) throws Exception {
+ assertNotNull(f1);
+ return f1;
+ }
+ @RestPost
+ public Object c2(@FormData(name="f1",def="@((a=2,b=bar))") Optional<List<ABean>> f1) throws Exception {
+ assertNotNull(f1);
+ return f1;
+ }
+ @RestPost
+ public Object d(@FormData(name="f1",def="@((a=2,b=bar))") List<Optional<ABean>> f1) throws Exception {
+ return f1;
+ }
+ }
+
+ @Test
+ public void f01_defaultParams() throws Exception {
+ RestClient f = MockRestClient.create(F.class).accept("application/json").contentType("application/x-www-form-urlencoded").build();
+
+ f.post("/a1", "f1=123")
+ .run()
+ .assertCode().is(200)
+ .assertContent().is("123");
+ f.post("/a1", "")
+ .run()
+ .assertCode().is(200)
+ .assertContent().is("1");
+ f.post("/a2", "f1=123")
+ .run()
+ .assertCode().is(200)
+ .assertContent().is("123");
+ f.post("/a2", "")
+ .run()
+ .assertCode().is(200)
+ .assertContent().is("1");
+
+ f.post("/b1", "f1=a=1,b=foo")
+ .run()
+ .assertCode().is(200)
+ .assertContent().is("{a:1,b:'foo'}");
+ f.post("/b1", "")
+ .run()
+ .assertCode().is(200)
+ .assertContent().is("{a:2,b:'bar'}");
+ f.post("/b2", "f1=a=1,b=foo")
+ .run()
+ .assertCode().is(200)
+ .assertContent().is("{a:1,b:'foo'}");
+ f.post("/b2", "")
+ .run()
+ .assertCode().is(200)
+ .assertContent().is("{a:2,b:'bar'}");
+
+ f.post("/c1", "f1=@((a=1,b=foo))")
+ .run()
+ .assertCode().is(200)
+ .assertContent().is("[{a:1,b:'foo'}]");
+ f.post("/c1", "null")
+ .run()
+ .assertCode().is(200)
+ .assertContent().is("[{a:2,b:'bar'}]");
+ f.post("/c2", "f1=@((a=1,b=foo))")
+ .run()
+ .assertCode().is(200)
+ .assertContent().is("[{a:1,b:'foo'}]");
+ f.post("/c2", "null")
+ .run()
+ .assertCode().is(200)
+ .assertContent().is("[{a:2,b:'bar'}]");
+
+
+ f.post("/d", "f1=@((a=1,b=foo))")
+ .run()
+ .assertCode().is(200)
+ .assertContent().is("[{a:1,b:'foo'}]");
+ f.post("/d", "null")
+ .run()
+ .assertCode().is(200)
+ .assertContent().is("[{a:2,b:'bar'}]");
+ }
}
diff --git a/juneau-utest/src/test/java/org/apache/juneau/rest/annotation/Header_Test.java b/juneau-utest/src/test/java/org/apache/juneau/rest/annotation/Header_Test.java
index 9d589f3bb..082f789e6 100644
--- a/juneau-utest/src/test/java/org/apache/juneau/rest/annotation/Header_Test.java
+++ b/juneau-utest/src/test/java/org/apache/juneau/rest/annotation/Header_Test.java
@@ -210,4 +210,114 @@ public class Header_Test {
e.get("/a").header("H1",7).header("H2",8).header("H3",9).run().assertContent().is("{h1:'7',h2:'8',h3:'9'}");
e.get("/a").header("h1",7).header("h2",8).header("h3",9).run().assertContent().is("{h1:'7',h2:'8',h3:'9'}");
}
+
+ //------------------------------------------------------------------------------------------------------------------
+ // Default parameters
+ //------------------------------------------------------------------------------------------------------------------
+
+ @Rest(serializers=SimpleJsonSerializer.class)
+ public static class F {
+ @RestGet
+ public Object a1(@Header(name="f1", def="1") Integer f1) throws Exception {
+ assertNotNull(f1);
+ return f1;
+ }
+ @RestGet
+ public Object a2(@Header(name="f1", def="1") Optional<Integer> f1) throws Exception {
+ assertNotNull(f1);
+ return f1.get();
+ }
+ @RestGet
+ public Object b1(@Header(name="f1", def="a=1,b=foo") ABean f1) throws Exception {
+ assertNotNull(f1);
+ return f1;
+ }
+ @RestGet
+ public Object b2(@Header(name="f1", def="a=1,b=foo") Optional<ABean> f1) throws Exception {
+ assertNotNull(f1);
+ return f1.get();
+ }
+ @RestGet
+ public Object c1(@Header(name="f1", def="@((a=1,b=foo))") List<ABean> f1) throws Exception {
+ assertNotNull(f1);
+ return f1;
+ }
+ @RestGet
+ public Object c2(@Header(name="f1", def="@((a=1,b=foo))") Optional<List<ABean>> f1) throws Exception {
+ assertNotNull(f1);
+ return f1.get();
+ }
+ @RestGet
+ public Object d(@Header(name="f1", def="@((a=1,b=foo))") List<Optional<ABean>> f1) throws Exception {
+ return f1;
+ }
+ }
+
+ @Test
+ public void f01_defaultHeaders() throws Exception {
+ RestClient f = MockRestClient.buildJson(F.class);
+ f.get("/a1")
+ .header("f1","123")
+ .run()
+ .assertCode().is(200)
+ .assertContent().is("123");
+ f.get("/a1")
+ .run()
+ .assertCode().is(200)
+ .assertContent().is("1");
+ f.get("/a2")
+ .header("f1","123")
+ .run()
+ .assertCode().is(200)
+ .assertContent().is("123");
+ f.get("/a2")
+ .run()
+ .assertCode().is(200)
+ .assertContent().is("1");
+ f.get("/b1")
+ .header("f1","a=2,b=bar")
+ .run()
+ .assertCode().is(200)
+ .assertContent().is("{a:2,b:'bar'}");
+ f.get("/b1")
+ .run()
+ .assertCode().is(200)
+ .assertContent().is("{a:1,b:'foo'}");
+ f.get("/b2")
+ .header("f1","a=2,b=bar")
+ .run()
+ .assertCode().is(200)
+ .assertContent().is("{a:2,b:'bar'}");
+ f.get("/b2")
+ .run()
+ .assertCode().is(200)
+ .assertContent().is("{a:1,b:'foo'}");
+ f.get("/c1")
+ .header("f1","@((a=2,b=bar))")
+ .run()
+ .assertCode().is(200)
+ .assertContent().is("[{a:2,b:'bar'}]");
+ f.get("/c1")
+ .run()
+ .assertCode().is(200)
+ .assertContent().is("[{a:1,b:'foo'}]");
+ f.get("/c2")
+ .header("f1","@((a=2,b=bar))")
+ .run()
+ .assertCode().is(200)
+ .assertContent().is("[{a:2,b:'bar'}]");
+ f.get("/c2")
+ .run()
+ .assertCode().is(200)
+ .assertContent().is("[{a:1,b:'foo'}]");
+ f.get("/d")
+ .header("f1","@((a=2,b=bar))")
+ .run()
+ .assertCode().is(200)
+ .assertContent().is("[{a:2,b:'bar'}]");
+ f.get("/d")
+ .run()
+ .assertCode().is(200)
+ .assertContent().is("[{a:1,b:'foo'}]");
+ }
}
diff --git a/juneau-utest/src/test/java/org/apache/juneau/rest/annotation/Query_Test.java b/juneau-utest/src/test/java/org/apache/juneau/rest/annotation/Query_Test.java
index 82b5b9df6..170332cc2 100644
--- a/juneau-utest/src/test/java/org/apache/juneau/rest/annotation/Query_Test.java
+++ b/juneau-utest/src/test/java/org/apache/juneau/rest/annotation/Query_Test.java
@@ -288,4 +288,107 @@ public class Query_Test {
.assertCode().is(200)
.assertContent().is("null");
}
+
+ //------------------------------------------------------------------------------------------------------------------
+ // Default parameters
+ //------------------------------------------------------------------------------------------------------------------
+
+ @Rest(serializers=SimpleJsonSerializer.class)
+ public static class F {
+ @RestGet
+ public Object a1(@Query(name="f1", def="1") Integer f1) throws Exception {
+ assertNotNull(f1);
+ return f1;
+ }
+ @RestGet
+ public Object a2(@Query(name="f1", def="1") Optional<Integer> f1) throws Exception {
+ assertNotNull(f1);
+ return f1.get();
+ }
+ @RestGet
+ public Object b1(@Query(name="f1", def="a=1,b=foo") ABean f1) throws Exception {
+ assertNotNull(f1);
+ return f1;
+ }
+ @RestGet
+ public Object b2(@Query(name="f1", def="a=1,b=foo") Optional<ABean> f1) throws Exception {
+ assertNotNull(f1);
+ return f1.get();
+ }
+ @RestGet
+ public Object c1(@Query(name="f1", def="@((a=1,b=foo))") List<ABean> f1) throws Exception {
+ assertNotNull(f1);
+ return f1;
+ }
+ @RestGet
+ public Object c2(@Query(name="f1", def="@((a=1,b=foo))") Optional<List<ABean>> f1) throws Exception {
+ assertNotNull(f1);
+ return f1.get();
+ }
+ @RestGet
+ public Object d(@Query(name="f1", def="@((a=1,b=foo))") List<Optional<ABean>> f1) throws Exception {
+ return f1;
+ }
+ }
+
+ @Test
+ public void f01_defaultParams() throws Exception {
+ RestClient f = MockRestClient.buildJson(F.class);
+ f.get("/a1?f1=123")
+ .run()
+ .assertCode().is(200)
+ .assertContent().is("123");
+ f.get("/a1")
+ .run()
+ .assertCode().is(200)
+ .assertContent().is("1");
+ f.get("/a2?f1=123")
+ .run()
+ .assertCode().is(200)
+ .assertContent().is("123");
+ f.get("/a2")
+ .run()
+ .assertCode().is(200)
+ .assertContent().is("1");
+ f.get("/b1?f1=a=2,b=bar")
+ .run()
+ .assertCode().is(200)
+ .assertContent().is("{a:2,b:'bar'}");
+ f.get("/b1")
+ .run()
+ .assertCode().is(200)
+ .assertContent().is("{a:1,b:'foo'}");
+ f.get("/b2?f1=a=2,b=bar")
+ .run()
+ .assertCode().is(200)
+ .assertContent().is("{a:2,b:'bar'}");
+ f.get("/b2")
+ .run()
+ .assertCode().is(200)
+ .assertContent().is("{a:1,b:'foo'}");
+ f.get("/c1?f1=@((a=2,b=bar))")
+ .run()
+ .assertCode().is(200)
+ .assertContent().is("[{a:2,b:'bar'}]");
+ f.get("/c1")
+ .run()
+ .assertCode().is(200)
+ .assertContent().is("[{a:1,b:'foo'}]");
+ f.get("/c2?f1=@((a=2,b=bar))")
+ .run()
+ .assertCode().is(200)
+ .assertContent().is("[{a:2,b:'bar'}]");
+ f.get("/c2")
+ .run()
+ .assertCode().is(200)
+ .assertContent().is("[{a:1,b:'foo'}]");
+ f.get("/d?f1=@((a=2,b=bar))")
+ .run()
+ .assertCode().is(200)
+ .assertContent().is("[{a:2,b:'bar'}]");
+ f.get("/d")
+ .run()
+ .assertCode().is(200)
+ .assertContent().is("[{a:1,b:'foo'}]");
+ }
}