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 2018/05/23 00:32:19 UTC
[juneau] branch master updated: Simplify how serializers and
parsers are inherited from class to method.
This is an automated email from the ASF dual-hosted git repository.
jamesbognar pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/juneau.git
The following commit(s) were added to refs/heads/master by this push:
new 26bc383 Simplify how serializers and parsers are inherited from class to method.
26bc383 is described below
commit 26bc3837a48cf26ef924e05fd7e10b8ce28be8bb
Author: JamesBognar <ja...@apache.org>
AuthorDate: Tue May 22 20:32:03 2018 -0400
Simplify how serializers and parsers are inherited from class to method.
---
.../org/apache/juneau/internal/ArrayUtils.java | 18 +++
.../main/java/org/apache/juneau/parser/Parser.java | 9 +-
.../org/apache/juneau/serializer/Serializer.java | 32 ++++-
juneau-doc/src/main/javadoc/overview.html | 6 +
.../main/java/org/apache/juneau/rest/Inherit.java | 42 ++++++
.../src/main/java/org/apache/juneau/rest/None.java | 36 +++++
.../org/apache/juneau/rest/RestJavaMethod.java | 81 ++++++-----
.../juneau/rest/annotation/MethodSwagger.java | 155 ++++++++++++++++++---
.../apache/juneau/rest/annotation/RestMethod.java | 82 +++++------
.../rest/annotation/RestMethodInheritTest.java | 33 +----
.../rest/annotation/RestResourceParsersTest.java | 5 +-
.../annotation/RestResourceSerializersTest.java | 5 +-
.../org/apache/juneau/rest/headers/AcceptTest.java | 5 +-
.../juneau/rest/headers/ContentTypeTest.java | 5 +-
14 files changed, 368 insertions(+), 146 deletions(-)
diff --git a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/internal/ArrayUtils.java b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/internal/ArrayUtils.java
index dbcac53..d5b26b7 100644
--- a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/internal/ArrayUtils.java
+++ b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/internal/ArrayUtils.java
@@ -474,4 +474,22 @@ public final class ArrayUtils {
Array.set(a, --j, i.next());
return (T[])a;
}
+
+ /**
+ * Removes the specified element from the specified array.
+ *
+ * @param element The element to remove from the array.
+ * @param array The array to remove the element from.
+ * @return A new array with the element removed, or the original array if the array did not contain the element.
+ */
+ public static Object[] remove(Object element, Object[] array) {
+ if (! contains(element, array))
+ return array;
+ List<Object> l = new ArrayList<>(array.length);
+ for (Object o2 : array) {
+ if (! element.equals(o2))
+ l.add(o2);
+ }
+ return l.toArray(new Object[l.size()]);
+ }
}
diff --git a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/parser/Parser.java b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/parser/Parser.java
index dd915a5..349c10a 100644
--- a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/parser/Parser.java
+++ b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/parser/Parser.java
@@ -479,8 +479,13 @@ public abstract class Parser extends BeanContext {
/** General parser properties currently set on this parser. */
private final MediaType[] consumes;
- // Hidden constructor to force subclass from InputStreamParser or ReaderParser.
- Parser(PropertyStore ps, String...consumes) {
+ /**
+ * Constructor.
+ *
+ * @param ps The property store containing all the settings for this object.
+ * @param consumes The list of media types that this parser consumes (e.g. <js>"application/json"</js>).
+ */
+ protected Parser(PropertyStore ps, String...consumes) {
super(ps);
trimStrings = getBooleanProperty(PARSER_trimStrings, false);
diff --git a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/serializer/Serializer.java b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/serializer/Serializer.java
index 4567a68..16f1674 100644
--- a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/serializer/Serializer.java
+++ b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/serializer/Serializer.java
@@ -863,9 +863,35 @@ public abstract class Serializer extends BeanContext {
private final MediaTypeRange[] accept;
private final MediaType[] accepts;
private final MediaType produces;
-
- // Hidden constructors to force subclass from OuputStreamSerializer or WriterSerializer.
- Serializer(PropertyStore ps, String produces, String accept) {
+
+ /**
+ * Constructor
+ *
+ * @param ps
+ * The property store containing all the settings for this object.
+ * @param produces
+ * The media type that this serializer produces.
+ * @param accept
+ * The accept media types that the serializer can handle.
+ * <p>
+ * Can contain meta-characters per the <code>media-type</code> specification of
+ * <a class="doclink" href="http://www.w3.org/Protocols/rfc2616/rfc2616-sec14.html#sec14.1">RFC2616/14.1</a>
+ * <p>
+ * If empty, then assumes the only media type supported is <code>produces</code>.
+ * <p>
+ * For example, if this serializer produces <js>"application/json"</js> but should handle media types of
+ * <js>"application/json"</js> and <js>"text/json"</js>, then the arguments should be:
+ * <p class='bcode'>
+ * <jk>super</jk>(ps, <js>"application/json"</js>, <js>"application/json,text/json"</js>);
+ * </p>
+ * <br>...or...
+ * <p class='bcode'>
+ * <jk>super</jk>(ps, <js>"application/json"</js>, <js>"*​/json"</js>);
+ * </p>
+ * <p>
+ * The accept value can also contain q-values.
+ */
+ protected Serializer(PropertyStore ps, String produces, String accept) {
super(ps);
maxDepth = getIntegerProperty(SERIALIZER_maxDepth, 100);
diff --git a/juneau-doc/src/main/javadoc/overview.html b/juneau-doc/src/main/javadoc/overview.html
index b81e7a4..66cc6f1 100644
--- a/juneau-doc/src/main/javadoc/overview.html
+++ b/juneau-doc/src/main/javadoc/overview.html
@@ -21759,6 +21759,12 @@
<li>
New documentation:
<br>><a class="doclink" href="#juneau-rest-server.UnitTesting">Overview > juneau-rest-server > Server-less Unit Testing of REST Interfaces</a>
+ <li>
+ <code><ja>@RestMethod</ja>(inherit)</code> annotation has been removed and replaced with the following classes:
+ <ul>
+ <li class='jc'>{@link org.apache.juneau.rest.Inherit}
+ <li class='jc'>{@link org.apache.juneau.rest.None}
+ </ul>
</ul>
<h5 class='topic w800'>juneau-rest-client</h5>
diff --git a/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/Inherit.java b/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/Inherit.java
new file mode 100644
index 0000000..450f308
--- /dev/null
+++ b/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/Inherit.java
@@ -0,0 +1,42 @@
+// ***************************************************************************************************************************
+// * 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;
+
+/**
+ * Dummy class that indicates that serializers, parsers, or transforms should be inherited from parent-class-to-class or class-to-method.
+ *
+ * <h5 class='section'>Example:</h5>
+ * <p class='bcode'>
+ * <ja>@RestMethod</ja>(
+ *
+ * // Override the serializers for this method, but also inherit the serializers from the class.
+ * // Class-level serializers will be inserted in the location in the array.
+ * serializers={JsonSerializer.<jk>class</jk>, Inherit.<jk>class</jk>},
+ *
+ * // Override the parsers for this method, but also inherit the parsers from the class.
+ * // Class-level parsers will be inserted in the location in the array.
+ * parsers={JsonParser.<jk>class</jk>, Inherit.<jk>class</jk>},
+ *
+ * // Override the bean filters for this method, but also inherit the bean filters from the class.
+ * // Overridden bean filters only apply to NEW serializers and parsers defined on the method
+ * // (not those inherited from the class).
+ * beanFilters={MyFilter.<jk>class</jk>, Inherit.<jk>class</jk>},
+ *
+ * // Override the POJO swaps for this method, but also inherit the POJO swaps from the class.
+ * // Overridden POJO swaps only apply to NEW serializers and parsers defined on the method
+ * // (not those inherited from the class).
+ * pojoSwaps={MySwap.<jk>class</jk>, Inherit.<jk>class</jk>}
+ * )
+ * </p>
+ */
+public final class Inherit {}
diff --git a/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/None.java b/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/None.java
new file mode 100644
index 0000000..2eaa73f
--- /dev/null
+++ b/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/None.java
@@ -0,0 +1,36 @@
+// ***************************************************************************************************************************
+// * 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;
+
+/**
+ * Dummy class that indicates that serializers, parsers, or transforms for a Java class or method should not be inherited.
+ *
+ * <h5 class='section'>Example:</h5>
+ * <p class='bcode'>
+ * <ja>@RestMethod</ja>(
+ *
+ * // No serializers are defined method or inherited from the class.
+ * serializers=None.<jk>class</jk>,
+ *
+ * // No parsers are defined method or inherited from the class.
+ * parsers=None.<jk>class</jk>,
+ *
+ * // No bean filters are defined method or inherited from the class.
+ * beanFilters=None.<jk>class</jk>,
+ *
+ * // No POJO swaps are defined method or inherited from the class.
+ * pojoSwaps=None.<jk>class</jk>
+ * )
+ * </p>
+ */
+public final class None {}
diff --git a/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/RestJavaMethod.java b/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/RestJavaMethod.java
index 92fc1fe..ae7384f 100644
--- a/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/RestJavaMethod.java
+++ b/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/RestJavaMethod.java
@@ -39,7 +39,6 @@ import org.apache.juneau.rest.util.*;
import org.apache.juneau.rest.widget.*;
import org.apache.juneau.serializer.*;
import org.apache.juneau.svl.*;
-import org.apache.juneau.utils.*;
/**
* Represents a single Java servlet/resource method annotated with {@link RestMethod @RestMethod}.
@@ -167,16 +166,22 @@ public class RestJavaMethod implements Comparable<RestJavaMethod> {
hdb.style("INHERIT", "$W{"+w.getName()+".style}");
}
- ASet<String> inherit = new ASet<String>().appendAll(StringUtils.split(m.inherit()));
- if (inherit.contains("*"))
- inherit.appendAll("SERIALIZERS","PARSERS","TRANSFORMS","PROPERTIES","ENCODERS");
+// ASet<String> inherit = new ASet<String>().appendAll(StringUtils.split(m.inherit()));
+// if (inherit.contains("*"))
+// inherit.appendAll("SERIALIZERS","PARSERS","TRANSFORMS","PROPERTIES","ENCODERS");
SerializerGroupBuilder sgb = null;
ParserGroupBuilder pgb = null;
ParserBuilder uepb = null;
BeanContextBuilder bcb = null;
PropertyStore cps = context.getPropertyStore();
-
+
+
+ Object[] mSerializers = resolve(cps.getArrayProperty(REST_serializers, Object.class), m.serializers());
+ Object[] mParsers = resolve(cps.getArrayProperty(REST_parsers, Object.class), m.parsers());
+ Object[] mPojoSwaps = resolve(cps.getArrayProperty(BEAN_pojoSwaps, Object.class), m.pojoSwaps());
+ Object[] mBeanFilters = resolve(cps.getArrayProperty(BEAN_beanFilters, Object.class), m.beanFilters());
+
if (m.serializers().length > 0 || m.parsers().length > 0 || m.properties().length > 0 || m.flags().length > 0
|| m.beanFilters().length > 0 || m.pojoSwaps().length > 0 || m.bpi().length > 0
|| m.bpx().length > 0) {
@@ -184,12 +189,8 @@ public class RestJavaMethod implements Comparable<RestJavaMethod> {
pgb = ParserGroup.create();
uepb = Parser.create();
bcb = beanContext.builder();
-
- if (inherit.contains("SERIALIZERS") || m.serializers().length == 0)
- sgb.append(cps.getArrayProperty(REST_serializers, Object.class));
-
- if (inherit.contains("PARSERS") || m.parsers().length == 0)
- pgb.append(cps.getArrayProperty(REST_parsers, Object.class));
+ sgb.append(mSerializers);
+ pgb.append(mParsers);
}
httpMethod = m.name().toUpperCase(Locale.ENGLISH);
@@ -227,16 +228,10 @@ public class RestJavaMethod implements Comparable<RestJavaMethod> {
this.optionalMatchers = optionalMatchers.toArray(new RestMatcher[optionalMatchers.size()]);
PropertyStore ps = context.getPropertyStore();
- if (! inherit.contains("TRANSFORMS"))
- ps = ps.builder().set(BEAN_beanFilters, null).set(BEAN_pojoSwaps, null).build();
+ ps = ps.builder().set(BEAN_beanFilters, mBeanFilters).set(BEAN_pojoSwaps, mPojoSwaps).build();
if (sgb != null) {
- sgb.append(m.serializers());
-
- if (! inherit.contains("PROPERTIES"))
- sgb.beanFilters((Object[])ps.getClassArrayProperty(BEAN_beanFilters)).pojoSwaps(ps.getClassArrayProperty(BEAN_pojoSwaps));
- else
- sgb.apply(ps);
+ sgb.apply(ps);
for (Property p1 : m.properties())
sgb.set(p1.name(), p1.value());
for (String p1 : m.flags())
@@ -267,22 +262,18 @@ public class RestJavaMethod implements Comparable<RestJavaMethod> {
}
sgb.excludeProperties(bpxMap);
}
- sgb.beanFilters((Object[])m.beanFilters());
- sgb.pojoSwaps(m.pojoSwaps());
+ sgb.beanFilters(mBeanFilters);
+ sgb.pojoSwaps(mPojoSwaps);
}
if (pgb != null) {
- pgb.append(m.parsers());
- if (! inherit.contains("PROPERTIES"))
- pgb.beanFilters((Object[])ps.getClassArrayProperty(BEAN_beanFilters)).pojoSwaps(ps.getClassArrayProperty(BEAN_pojoSwaps));
- else
- pgb.apply(ps);
+ pgb.apply(ps);
for (Property p1 : m.properties())
pgb.set(p1.name(), p1.value());
for (String p1 : m.flags())
pgb.set(p1, true);
- pgb.beanFilters((Object[])m.beanFilters());
- pgb.pojoSwaps(m.pojoSwaps());
+ pgb.beanFilters(mBeanFilters);
+ pgb.pojoSwaps(mPojoSwaps);
}
if (uepb != null) {
@@ -291,8 +282,8 @@ public class RestJavaMethod implements Comparable<RestJavaMethod> {
uepb.set(p1.name(), p1.value());
for (String p1 : m.flags())
uepb.set(p1, true);
- uepb.beanFilters((Object[])m.beanFilters());
- uepb.pojoSwaps(m.pojoSwaps());
+ uepb.beanFilters(mBeanFilters);
+ uepb.pojoSwaps(mPojoSwaps);
}
if (bcb != null) {
@@ -301,8 +292,8 @@ public class RestJavaMethod implements Comparable<RestJavaMethod> {
bcb.set(p1.name(), p1.value());
for (String p1 : m.flags())
bcb.set(p1, true);
- bcb.beanFilters((Object[])m.beanFilters());
- bcb.pojoSwaps(m.pojoSwaps());
+ bcb.beanFilters(mBeanFilters);
+ bcb.pojoSwaps(mPojoSwaps);
}
if (m.properties().length > 0 || m.flags().length > 0) {
@@ -315,10 +306,7 @@ public class RestJavaMethod implements Comparable<RestJavaMethod> {
if (m.encoders().length > 0) {
EncoderGroupBuilder g = EncoderGroup.create().append(IdentityEncoder.INSTANCE);
- if (inherit.contains("ENCODERS"))
- g.append(encoders);
-
- for (Class<? extends Encoder> c : m.encoders()) {
+ for (Class<?> c : m.encoders()) {
try {
g.append(c);
} catch (Exception e) {
@@ -415,6 +403,27 @@ public class RestJavaMethod implements Comparable<RestJavaMethod> {
}
}
}
+
+ static Object[] resolve(Object[] fromClass, Object[] fromAnnotation) {
+
+ if (ArrayUtils.contains(None.class, fromAnnotation))
+ return ArrayUtils.remove(None.class, fromAnnotation);
+
+ if (fromAnnotation.length == 0)
+ return fromClass;
+
+ if (! ArrayUtils.contains(Inherit.class, fromAnnotation))
+ return fromAnnotation;
+
+ List<Object> l = new ArrayList<>(fromClass.length + fromAnnotation.length);
+ for (Object o : fromAnnotation) {
+ if (o == Inherit.class)
+ l.addAll(Arrays.asList(fromClass));
+ else
+ l.add(o);
+ }
+ return l.toArray(new Object[l.size()]);
+ }
/**
* Returns <jk>true</jk> if this Java method has any guards or matchers.
diff --git a/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/annotation/MethodSwagger.java b/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/annotation/MethodSwagger.java
index 48b98e3..4488ee2 100644
--- a/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/annotation/MethodSwagger.java
+++ b/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/annotation/MethodSwagger.java
@@ -23,38 +23,113 @@ package org.apache.juneau.rest.annotation;
public @interface MethodSwagger {
/**
- * Swagger JSON.
+ * Defines the swagger field <code>/paths/{path}/{method}</code>.
*
* <p>
- * Used for free-form Swagger documentation of a REST resource.
+ * Used for free-form Swagger documentation of a REST Java method.
+ *
+ * <h5 class='section'>Example:</h5>
+ * <p class='bcode'>
+ * <ja>@RestMethod</ja>(
+ * swagger=<ja>@MethodSwagger</ja>(
+ * <js>"tags:['pet'],"</js>,
+ * <js>"security:[ { petstore_auth:['write:pets','read:pets'] } ]"</js>
+ * )
+ * )
+ * </p>
+ *
+ * <h5 class='section'>Notes:</h5>
+ * <ul class='spaced-list'>
+ * <li>
+ * The format is a JSON object.
+ * <br>Multiple lines are concatenated with newlines.
+ * <br>Comments and whitespace are ignored.
+ * <br>The leading and trailing <js>'{'</js>/<js>'}'</js> characters are optional.
+ * <li>
+ * Supports <a class="doclink" href="../../../../../overview-summary.html#DefaultRestSvlVariables">initialization-time and request-time variables</a>
+ * (e.g. <js>"$L{my.localized.variable}"</js>).
+ * <li>
+ * Values defined on this annotation override values defined for the method in the class swagger.
+ * <li>
+ *
+ * </ul>
*/
String[] value() default {};
/**
- * {@link TODO}
+ * Defines the swagger field <code>/paths/{path}/{method}/summary</code>.
+ *
+ * <h5 class='section'>Notes:</h5>
+ * <ul class='spaced-list'>
+ * <li>
+ * The format is plain text.
+ * <br>Multiple lines are concatenated with newlines.
+ * <li>
+ * Supports <a class="doclink" href="../../../../../overview-summary.html#DefaultRestSvlVariables">initialization-time and request-time variables</a>
+ * (e.g. <js>"$L{my.localized.variable}"</js>).
+ * <li>
+ * Values defined on this annotation override values defined for the method in the class swagger.
+ * <li>
+ * If not specified, the value is pulled from {@link RestMethod#summary()}.
+ * </ul>
*/
String[] summary() default {};
/**
- * {@link TODO}
+ * Defines the swagger field <code>/paths/{path}/{method}/description</code>.
+ *
+ * <h5 class='section'>Notes:</h5>
+ * <ul class='spaced-list'>
+ * <li>
+ * The format is plain text.
+ * <br>Multiple lines are concatenated with newlines.
+ * <li>
+ * Supports <a class="doclink" href="../../../../../overview-summary.html#DefaultRestSvlVariables">initialization-time and request-time variables</a>
+ * (e.g. <js>"$L{my.localized.variable}"</js>).
+ * <li>
+ * Values defined on this annotation override values defined for the method in the class swagger.
+ * <li>
+ * If not specified, the value is pulled from {@link RestMethod#description()}.
+ * </ul>
*/
String[] description() default {};
/**
- * {@link TODO}
+ * Defines the swagger field <code>/paths/{path}/{method}/operationId</code>.
+ *
+ * <h5 class='section'>Notes:</h5>
+ * <ul class='spaced-list'>
+ * <li>
+ * The format is plain text.
+ * <li>
+ * Supports <a class="doclink" href="../../../../../overview-summary.html#DefaultRestSvlVariables">initialization-time and request-time variables</a>
+ * (e.g. <js>"$L{my.localized.variable}"</js>).
+ * <li>
+ * Values defined on this annotation override values defined for the method in the class swagger.
+ * <li>
+ * If not specified, the value used is the Java method name.
+ * </ul>
*/
String operationId() default "";
/**
- * {@link TODO}
+ * Defines the swagger field <code>/paths/{path}/{method}/schemes</code>.
+ *
+ * <h5 class='section'>Notes:</h5>
+ * <ul class='spaced-list'>
+ * <li>
+ * The format is either a comma-delimited list of simple strings or a JSON array.
+ * <li>
+ * Supports <a class="doclink" href="../../../../../overview-summary.html#DefaultRestSvlVariables">initialization-time and request-time variables</a>
+ * (e.g. <js>"$L{my.localized.variable}"</js>).
+ * <li>
+ * Values defined on this annotation override values defined for the method in the class swagger.
+ * </ul>
*/
String[] schemes() default {};
/**
- * Optional deprecated flag for the exposed API.
- *
- * <p>
- * Used to populate the Swagger deprecated field.
+ * Defines the swagger field <code>/paths/{path}/{method}/deprecated</code>.
*
* <h5 class='section'>Example:</h5>
* <p class='bcode'>
@@ -68,26 +143,58 @@ public @interface MethodSwagger {
* <h5 class='section'>Notes:</h5>
* <ul class='spaced-list'>
* <li>
- * Corresponds to the swagger field <code>/paths/{path}/{method}/deprecated</code>.
+ * The format is boolean.
+ * <li>
+ * Supports <a class="doclink" href="../../../../../overview-summary.html#DefaultRestSvlVariables">initialization-time and request-time variables</a>
+ * (e.g. <js>"$L{my.localized.variable}"</js>).
+ * <li>
+ * Values defined on this annotation override values defined for the method in the class swagger.
+ * <li>
+ * If not specified, set to <js>"true"</js> if the method is annotated with {@link Deprecated @Deprecated}
* </ul>
*/
String deprecated() default "";
/**
- * {@link TODO}
+ * Defines the swagger field <code>/paths/{path}/{method}/consumes</code>.
+ *
+ * <p>
+ * Use this value to override the supported <code>Content-Type</code> media types defined by the parsers defined via {@link RestMethod#parsers()}.
+ *
+ * <h5 class='section'>Notes:</h5>
+ * <ul class='spaced-list'>
+ * <li>
+ * The format is either a comma-delimited list of simple strings or a JSON array.
+ * <li>
+ * Supports <a class="doclink" href="../../../../../overview-summary.html#DefaultRestSvlVariables">initialization-time and request-time variables</a>
+ * (e.g. <js>"$L{my.localized.variable}"</js>).
+ * <li>
+ * Values defined on this annotation override values defined for the method in the class swagger.
+ * </ul>
*/
String[] consumes() default {};
/**
- * {@link TODO}
+ * Defines the swagger field <code>/paths/{path}/{method}/consumes</code>.
+ *
+ * <p>
+ * Use this value to override the supported <code>CAccept/code> media types defined by the serializers defined via {@link RestMethod#serializers()}.
+ *
+ * <h5 class='section'>Notes:</h5>
+ * <ul class='spaced-list'>
+ * <li>
+ * The format is either a comma-delimited list of simple strings or a JSON array.
+ * <li>
+ * Supports <a class="doclink" href="../../../../../overview-summary.html#DefaultRestSvlVariables">initialization-time and request-time variables</a>
+ * (e.g. <js>"$L{my.localized.variable}"</js>).
+ * <li>
+ * Values defined on this annotation override values defined for the method in the class swagger.
+ * </ul>
*/
String[] produces() default {};
/**
- * Optional external documentation information for the exposed API.
- *
- * <p>
- * Used to populate the Swagger external documentation field.
+ * Defines the swagger field <code>/paths/{path}/{method}/externalDocs</code>.
*
* <p>
* A simplified JSON string with the following fields:
@@ -110,16 +217,21 @@ public @interface MethodSwagger {
* <h5 class='section'>Notes:</h5>
* <ul class='spaced-list'>
* <li>
+ * The format is a JSON object.
+ * <br>Multiple lines are concatenated with newlines.
+ * <br>Comments and whitespace are ignored.
+ * <br>The leading and trailing <js>'{'</js>/<js>'}'</js> characters are optional.
+ * <li>
* Supports <a class="doclink" href="../../../../../overview-summary.html#DefaultRestSvlVariables">initialization-time and request-time variables</a>
* (e.g. <js>"$L{my.localized.variable}"</js>).
* <li>
- * Corresponds to the swagger field <code>/paths/{path}/{method}/externalDocs</code>.
+ * Values defined on this annotation override values defined for the method in the class swagger.
* </ul>
*/
String[] externalDocs() default {};
/**
- * Optional parameter descriptions.
+ * Defines the swagger field <code>/paths/{path}/{method}/parameters</code>.
*
* <p>
* This annotation is provided for documentation purposes and is used to populate the method <js>"parameters"</js>
@@ -147,13 +259,12 @@ public @interface MethodSwagger {
* Supports <a class="doclink" href="../../../../../overview-summary.html#DefaultRestSvlVariables">initialization-time and request-time variables</a>
* (e.g. <js>"$L{my.localized.variable}"</js>).
* <li>
- * Corresponds to the swagger field <code>/paths/{path}/{method}/parameters</code>.
* </ul>
*/
String[] parameters() default {};
/**
- * Optional output description.
+ * Defines the swagger field <code>/paths/{path}/{method}/responses</code>.
*
* <p>
* This annotation is provided for documentation purposes and is used to populate the method <js>"responses"</js>
@@ -183,8 +294,6 @@ public @interface MethodSwagger {
* <li>
* Supports <a class="doclink" href="../../../../../overview-summary.html#DefaultRestSvlVariables">initialization-time and request-time variables</a>
* (e.g. <js>"$L{my.localized.variable}"</js>).
- * <li>
- * Corresponds to the swagger field <code>/paths/{path}/{method}/responses</code>.
* </ul>
*/
String[] responses() default {};
diff --git a/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/annotation/RestMethod.java b/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/annotation/RestMethod.java
index cc0f1ed..8144782f 100644
--- a/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/annotation/RestMethod.java
+++ b/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/annotation/RestMethod.java
@@ -18,11 +18,8 @@ import static java.lang.annotation.RetentionPolicy.*;
import java.lang.annotation.*;
import org.apache.juneau.*;
-import org.apache.juneau.encoders.*;
-import org.apache.juneau.parser.*;
import org.apache.juneau.remoteable.*;
import org.apache.juneau.rest.*;
-import org.apache.juneau.serializer.*;
/**
* Identifies a REST Java method on a {@link RestServlet} implementation class.
@@ -39,7 +36,17 @@ import org.apache.juneau.serializer.*;
public @interface RestMethod {
/**
- * Appends the specified bean filters to all serializers and parsers used by this method.
+ * Sets the bean filters for the serializers and parsers defined on this method.
+ *
+ * <p>
+ * If no value is specified, the bean filters are inherited from the class.
+ * <br>Otherwise, this value overrides the bean filters defined on the class.
+ *
+ * <p>
+ * Use {@link Inherit} to inherit bean filters defined on the class.
+ *
+ * <p>
+ * Use {@link None} to suppress inheriting bean filters defined on the class.
*
* <h5 class='section'>See Also:</h5>
* <ul>
@@ -392,7 +399,7 @@ public @interface RestMethod {
* <li class='jf'>{@link RestContext#REST_encoders}
* </ul>
*/
- Class<? extends Encoder>[] encoders() default {};
+ Class<?>[] encoders() default {};
/**
* Shortcut for setting {@link #properties()} of simple boolean types.
@@ -429,32 +436,6 @@ public @interface RestMethod {
HtmlDoc htmldoc() default @HtmlDoc;
/**
- * Identifies what class-level properties are inherited by the serializers and parsers defined on the method.
- *
- * <p>
- * Possible values:
- * <ul>
- * <li><js>"SERIALIZERS"</js> - Inherit class-level serializers.
- * <li><js>"PARSERS"</js> - Inherit class-level parsers.
- * <li><js>"TRANSFORMS"</js> - Inherit class-level bean properties and pojo-swaps.
- * <li><js>"PROPERTIES"</js> - Inherit class-level properties (other than transforms).
- * <li><js>"ENCODERS"</js> - Inherit class-level encoders.
- * <li><js>"*"</js> - Inherit everything.
- * </ul>
- *
- * <p>
- * For example, to inherit all parsers, properties, and transforms from the servlet class:
- * <p class='bcode'>
- * <ja>@RestMethod</ja>(
- * path=<js>"/foo"</js>,
- * parsers=MySpecialParser.<jk>class</jk>,
- * inherit=<js>"PARSERS,PROPERTIES,TRANSFORMS"</js>
- * )
- * </p>
- */
- String inherit() default "";
-
- /**
* Method matchers.
*
* <p>
@@ -549,14 +530,14 @@ public @interface RestMethod {
* Parsers.
*
* <p>
- * Overrides the list of parsers assigned at the method level.
+ * If no value is specified, the parsers are inherited from the class.
+ * <br>Otherwise, this value overrides the parsers defined on the class.
*
* <p>
- * Use this annotation when the list of parsers assigned to a method differs from the list of parsers assigned at
- * the servlet level.
+ * Use {@link Inherit} to inherit parsers defined on the class.
*
* <p>
- * To append to the list of parsers assigned at the servlet level, use <code>inherit=<js>"PARSERS"</js></code>.
+ * Use {@link None} to suppress inheriting parsers defined on the class.
*
* <p class='bcode'>
* <jk>public class</jk> MyResource <jk>extends</jk> RestServlet {
@@ -564,8 +545,7 @@ public @interface RestMethod {
* <ja>@RestMethod</ja>(
* name=<jsf>PUT</jsf>,
* path=<js>"/foo"</js>,
- * parsers=MySpecialParser.<jk>class</jk>,
- * inherit=<js>"PARSERS"</js>
+ * parsers=MySpecialParser.<jk>class</jk>
* )
* <jk>public</jk> Object doGetWithSpecialAcceptType() {
* <jc>// Handle request for special Accept type</jc>
@@ -578,7 +558,7 @@ public @interface RestMethod {
* <li class='jf'>{@link RestContext#REST_parsers}
* </ul>
*/
- Class<? extends Parser>[] parsers() default {};
+ Class<?>[] parsers() default {};
/**
* Optional path pattern for the specified method.
@@ -606,7 +586,17 @@ public @interface RestMethod {
String path() default "/*";
/**
- * Appends the specified POJO swaps to all serializers and parsers used by this method.
+ * Sets the POJO swaps for the serializers and parsers defined on this method.
+ *
+ * <p>
+ * If no value is specified, the POJO swaps are inherited from the class.
+ * <br>Otherwise, this value overrides the POJO swaps defined on the class.
+ *
+ * <p>
+ * Use {@link Inherit} to inherit POJO swaps defined on the class.
+ *
+ * <p>
+ * Use {@link None} to suppress inheriting POJO swaps defined on the class.
*
* <h5 class='section'>See Also:</h5>
* <ul>
@@ -642,11 +632,14 @@ public @interface RestMethod {
* Overrides the list of serializers assigned at the method level.
*
* <p>
- * Use this annotation when the list of serializers assigned to a method differs from the list of serializers
- * assigned at the servlet level.
+ * If no value is specified, the serializers are inherited from the class.
+ * <br>Otherwise, this value overrides the serializers defined on the class.
+ *
+ * <p>
+ * Use {@link Inherit} to inherit serializers defined on the class.
*
* <p>
- * To append to the list of serializers assigned at the servlet level, use <code>inherit=<js>"SERIALIZERS"</js></code>.
+ * Use {@link None} to suppress inheriting serializers defined on the class.
*
* <h5 class='section'>Example:</h5>
* <p class='bcode'>
@@ -655,8 +648,7 @@ public @interface RestMethod {
* <ja>@RestMethod</ja>(
* name=<jsf>GET</jsf>,
* path=<js>"/foo"</js>,
- * serializers=MySpecialSerializer.<jk>class</jk>,
- * inherit=<js>"SERIALIZERS"</js>
+ * serializers=MySpecialSerializer.<jk>class</jk>
* )
* <jk>public</jk> Object doGetWithSpecialAcceptType() {
* <jc>// Handle request for special Accept type</jc>
@@ -669,7 +661,7 @@ public @interface RestMethod {
* <li class='jf'>{@link RestContext#REST_serializers}
* </ul>
*/
- Class<? extends Serializer>[] serializers() default {};
+ Class<?>[] serializers() default {};
/**
* Optional summary for the exposed API.
diff --git a/juneau-rest/juneau-rest-server/src/test/java/org/apache/juneau/rest/annotation/RestMethodInheritTest.java b/juneau-rest/juneau-rest-server/src/test/java/org/apache/juneau/rest/annotation/RestMethodInheritTest.java
index 2fafbe0..7666da6 100644
--- a/juneau-rest/juneau-rest-server/src/test/java/org/apache/juneau/rest/annotation/RestMethodInheritTest.java
+++ b/juneau-rest/juneau-rest-server/src/test/java/org/apache/juneau/rest/annotation/RestMethodInheritTest.java
@@ -146,7 +146,7 @@ public class RestMethodInheritTest {
// Should show ['text/s5']
return new ObjectList(res.getSupportedMediaTypes());
}
- @RestMethod(path="/onMethodInherit", serializers=S5.class, inherit="SERIALIZERS")
+ @RestMethod(path="/onMethodInherit", serializers={S5.class,Inherit.class})
public ObjectList a03(RestResponse res) {
// Should show ['text/s5','text/s3','text/s4','text/s1','text/s2']
return new ObjectList(res.getSupportedMediaTypes());
@@ -189,7 +189,7 @@ public class RestMethodInheritTest {
// Should show ['text/p5']
return new ObjectList(req.getConsumes());
}
- @RestMethod(path="/onMethodInherit", parsers=P5.class, inherit="PARSERS")
+ @RestMethod(path="/onMethodInherit", parsers={P5.class,Inherit.class})
public ObjectList bo3(RestRequest req) {
// Should show ['text/p5','text/p3','text/p4','text/p1','text/p2']
return new ObjectList(req.getConsumes());
@@ -211,31 +211,6 @@ public class RestMethodInheritTest {
}
//=================================================================================================================
- // Test encoder inheritance.
- //=================================================================================================================
-
- @RestResource(encoders={E1.class,E2.class})
- public static class C {}
-
- @RestResource(encoders={E3.class,E4.class})
- public static class C01 extends C {}
-
- @RestResource
- public static class C02 extends C01 {
- @RestMethod(name=GET, inherit="ENCODERS")
- public ObjectList test(RestResponse res) throws RestServletException {
- // Should show ['e3','e4','e1','e2','identity']
- return new ObjectList(res.getSupportedEncodings());
- }
- }
- static MockRest c = MockRest.create(C02.class);
-
- @Test
- public void c01_encoders() throws Exception {
- c.get("/").execute().assertBody("['e3','e4','e1','e2','identity']");
- }
-
- //=================================================================================================================
// Test filter inheritance.
//=================================================================================================================
@@ -252,7 +227,7 @@ public class RestMethodInheritTest {
// Should show ['F1','F2','Foo3']
return new Object[]{new Foo1(), new Foo2(), new Foo3()};
}
- @RestMethod(name=GET, path="/inheritTransforms", pojoSwaps=F3Swap.class, inherit="TRANSFORMS")
+ @RestMethod(name=GET, path="/inheritTransforms", pojoSwaps={F3Swap.class,Inherit.class})
public Object[] d02() {
// Should show ['F1','F2','F3']
return new Object[]{new Foo1(), new Foo2(), new Foo3()};
@@ -263,7 +238,7 @@ public class RestMethodInheritTest {
// Overriding serializer does not have parent filters applied.
return new Object[]{new Foo1(), new Foo2(), new Foo3()};
}
- @RestMethod(name=GET, path="/overrideSerializerInheritTransforms", serializers=JsonSerializer.Simple.class, pojoSwaps=F3Swap.class, inherit="TRANSFORMS")
+ @RestMethod(name=GET, path="/overrideSerializerInheritTransforms", serializers=JsonSerializer.Simple.class, pojoSwaps={F3Swap.class,Inherit.class})
public Object[] d04() {
// Should show ['F1','F2','F3']
return new Object[]{new Foo1(), new Foo2(), new Foo3()};
diff --git a/juneau-rest/juneau-rest-server/src/test/java/org/apache/juneau/rest/annotation/RestResourceParsersTest.java b/juneau-rest/juneau-rest-server/src/test/java/org/apache/juneau/rest/annotation/RestResourceParsersTest.java
index 0f2578a..ac9fc58 100644
--- a/juneau-rest/juneau-rest-server/src/test/java/org/apache/juneau/rest/annotation/RestResourceParsersTest.java
+++ b/juneau-rest/juneau-rest-server/src/test/java/org/apache/juneau/rest/annotation/RestResourceParsersTest.java
@@ -17,6 +17,7 @@ import static org.apache.juneau.internal.IOUtils.*;
import org.apache.juneau.*;
import org.apache.juneau.parser.*;
+import org.apache.juneau.rest.*;
import org.apache.juneau.rest.mock.*;
import org.junit.*;
import org.junit.runners.*;
@@ -110,11 +111,11 @@ public class RestResourceParsersTest {
public String a02(@Body String in) {
return in;
}
- @RestMethod(name=PUT, path="/parserOverriddenOnMethod", parsers={PB.class,PC.class}, inherit="PARSERS")
+ @RestMethod(name=PUT, path="/parserOverriddenOnMethod", parsers={Inherit.class, PB.class,PC.class})
public String a03(@Body String in) {
return in;
}
- @RestMethod(name=PUT, path="/parserWithDifferentMediaTypes", parsers={PD.class}, inherit="PARSERS")
+ @RestMethod(name=PUT, path="/parserWithDifferentMediaTypes", parsers={Inherit.class, PD.class})
public String a04(@Body String in) {
return in;
}
diff --git a/juneau-rest/juneau-rest-server/src/test/java/org/apache/juneau/rest/annotation/RestResourceSerializersTest.java b/juneau-rest/juneau-rest-server/src/test/java/org/apache/juneau/rest/annotation/RestResourceSerializersTest.java
index d1dfd9c..0112907 100644
--- a/juneau-rest/juneau-rest-server/src/test/java/org/apache/juneau/rest/annotation/RestResourceSerializersTest.java
+++ b/juneau-rest/juneau-rest-server/src/test/java/org/apache/juneau/rest/annotation/RestResourceSerializersTest.java
@@ -15,6 +15,7 @@ package org.apache.juneau.rest.annotation;
import static org.apache.juneau.http.HttpMethodName.*;
import org.apache.juneau.*;
+import org.apache.juneau.rest.*;
import org.apache.juneau.rest.mock.*;
import org.apache.juneau.serializer.*;
import org.junit.*;
@@ -106,11 +107,11 @@ public class RestResourceSerializersTest {
public String a02() {
return "test2";
}
- @RestMethod(name=GET, path="/serializerOverriddenOnMethod", serializers={SB.class,SC.class}, inherit="SERIALIZERS")
+ @RestMethod(name=GET, path="/serializerOverriddenOnMethod", serializers={SB.class,SC.class,Inherit.class})
public String a03() {
return "test3";
}
- @RestMethod(name=GET, path="/serializerWithDifferentMediaTypes", serializers={SD.class}, inherit="SERIALIZERS")
+ @RestMethod(name=GET, path="/serializerWithDifferentMediaTypes", serializers={SD.class,Inherit.class})
public String a04() {
return "test4";
}
diff --git a/juneau-rest/juneau-rest-server/src/test/java/org/apache/juneau/rest/headers/AcceptTest.java b/juneau-rest/juneau-rest-server/src/test/java/org/apache/juneau/rest/headers/AcceptTest.java
index bb7713c..41332e1 100644
--- a/juneau-rest/juneau-rest-server/src/test/java/org/apache/juneau/rest/headers/AcceptTest.java
+++ b/juneau-rest/juneau-rest-server/src/test/java/org/apache/juneau/rest/headers/AcceptTest.java
@@ -15,6 +15,7 @@ package org.apache.juneau.rest.headers;
import static org.apache.juneau.http.HttpMethodName.*;
import org.apache.juneau.*;
+import org.apache.juneau.rest.*;
import org.apache.juneau.rest.annotation.*;
import org.apache.juneau.rest.mock.*;
import org.apache.juneau.serializer.*;
@@ -123,7 +124,7 @@ public class AcceptTest {
serializers={S1.class,S2.class}
)
public static class C {
- @RestMethod(name=PUT, serializers=S3.class, inherit="SERIALIZERS")
+ @RestMethod(name=PUT, serializers={S3.class,Inherit.class})
public String c(@Body String in) {
return in;
}
@@ -233,7 +234,7 @@ public class AcceptTest {
serializers={S1.class,S2.class}
)
public static class F {
- @RestMethod(name=PUT, defaultRequestHeaders={"Accept: text/s3"}, serializers=S3.class, inherit="SERIALIZERS")
+ @RestMethod(name=PUT, defaultRequestHeaders={"Accept: text/s3"}, serializers={Inherit.class, S3.class})
public String f(@Body String in) {
return in;
}
diff --git a/juneau-rest/juneau-rest-server/src/test/java/org/apache/juneau/rest/headers/ContentTypeTest.java b/juneau-rest/juneau-rest-server/src/test/java/org/apache/juneau/rest/headers/ContentTypeTest.java
index 2837158..e522c49 100644
--- a/juneau-rest/juneau-rest-server/src/test/java/org/apache/juneau/rest/headers/ContentTypeTest.java
+++ b/juneau-rest/juneau-rest-server/src/test/java/org/apache/juneau/rest/headers/ContentTypeTest.java
@@ -16,6 +16,7 @@ import static org.apache.juneau.http.HttpMethodName.*;
import org.apache.juneau.*;
import org.apache.juneau.parser.*;
+import org.apache.juneau.rest.*;
import org.apache.juneau.rest.annotation.*;
import org.apache.juneau.rest.mock.*;
import org.junit.*;
@@ -137,7 +138,7 @@ public class ContentTypeTest {
parsers={P1.class,P2.class}
)
public static class C {
- @RestMethod(name=PUT, parsers=P3.class, inherit="PARSERS")
+ @RestMethod(name=PUT, parsers={P3.class,Inherit.class})
public String c(@Body String in) {
return in;
}
@@ -210,7 +211,7 @@ public class ContentTypeTest {
parsers={P1.class,P2.class}
)
public static class F {
- @RestMethod(name=PUT, defaultRequestHeaders={"Content-Type: text/p3"}, parsers=P3.class, inherit="PARSERS")
+ @RestMethod(name=PUT, defaultRequestHeaders={"Content-Type: text/p3"}, parsers={Inherit.class,P3.class})
public String f(@Body String in) {
return in;
}
--
To stop receiving notification emails like this one, please contact
jamesbognar@apache.org.