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 7c45992 Context API refactoring.
7c45992 is described below
commit 7c45992d7f334d91e8971c361a80c64d4650cf7e
Author: JamesBognar <[email protected]>
AuthorDate: Sun Aug 29 13:29:08 2021 -0400
Context API refactoring.
---
.../java/org/apache/juneau/rest/RestContext.java | 86 -----------------
.../org/apache/juneau/rest/RestContextBuilder.java | 36 -------
.../java/org/apache/juneau/rest/RestGuardList.java | 106 +++++++++++++++++++--
.../org/apache/juneau/rest/RestMatcherList.java | 80 ++++++++++++++--
.../apache/juneau/rest/RestMatcherListBuilder.java | 77 ---------------
.../java/org/apache/juneau/rest/RestOpContext.java | 30 +++---
.../apache/juneau/rest/RestOpContextBuilder.java | 90 ++++++++++++++++-
.../org/apache/juneau/rest/annotation/Rest.java | 2 +-
.../juneau/rest/annotation/RestAnnotation.java | 2 +-
.../apache/juneau/rest/annotation/RestDelete.java | 2 +-
.../rest/annotation/RestDeleteAnnotation.java | 2 +-
.../org/apache/juneau/rest/annotation/RestGet.java | 2 +-
.../juneau/rest/annotation/RestGetAnnotation.java | 2 +-
.../org/apache/juneau/rest/annotation/RestOp.java | 2 +-
.../juneau/rest/annotation/RestOpAnnotation.java | 2 +-
.../apache/juneau/rest/annotation/RestPost.java | 2 +-
.../juneau/rest/annotation/RestPostAnnotation.java | 2 +-
.../org/apache/juneau/rest/annotation/RestPut.java | 2 +-
.../juneau/rest/annotation/RestPutAnnotation.java | 2 +-
19 files changed, 281 insertions(+), 248 deletions(-)
diff --git
a/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/RestContext.java
b/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/RestContext.java
index 45c3396..078e4ba 100644
---
a/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/RestContext.java
+++
b/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/RestContext.java
@@ -907,92 +907,6 @@ public class RestContext extends BeanContext {
public static final String REST_fileFinderDefault = PREFIX +
".fileFinderDefault.o";
/**
- * Configuration property: Class-level guards.
- *
- * <h5 class='section'>Property:</h5>
- * <ul class='spaced-list'>
- * <li><b>ID:</b> {@link
org.apache.juneau.rest.RestContext#REST_guards REST_guards}
- * <li><b>Name:</b> <js>"RestContext.guards.lo"</js>
- * <li><b>Data type:</b> <c>List<{@link
org.apache.juneau.rest.RestGuard}|Class<{@link
org.apache.juneau.rest.RestGuard}>></c>
- * <li><b>Default:</b> empty list
- * <li><b>Session property:</b> <jk>false</jk>
- * <li><b>Annotations:</b>
- * <ul>
- * <li class='ja'>{@link
org.apache.juneau.rest.annotation.Rest#guards()}
- * <li class='ja'>{@link
org.apache.juneau.rest.annotation.RestOp#guards()}
- * </ul>
- * <li><b>Methods:</b>
- * <ul>
- * <li class='jm'>{@link
org.apache.juneau.rest.RestContextBuilder#guards(Class...)}
- * <li class='jm'>{@link
org.apache.juneau.rest.RestContextBuilder#guards(RestGuard...)}
- * </ul>
- * </ul>
- *
- * <h5 class='section'>Description:</h5>
- * <p>
- * Associates one or more {@link RestGuard RestGuards} with all REST
methods defined in this class.
- * <br>These guards get called immediately before execution of any REST
method in this class.
- *
- * <p>
- * If multiple guards are specified, <b>ALL</b> guards must pass.
- * <br>Note that this is different than matchers where only ONE matcher
needs to pass.
- *
- * <h5 class='section'>Example:</h5>
- * <p class='bcode w800'>
- * <jc>// Define a guard that only lets Billy make a request.</jc>
- * <jk>public</jk> BillyGuard <jk>extends</jk> RestGuard {
- * <ja>@Override</ja>
- * <jk>public boolean</jk> isRequestAllowed(RestRequest
<jv>req</jv>) {
- * <jk>return</jk>
<jv>req</jv>.getUserPrincipal().getName().equals(<js>"Billy"</js>);
- * }
- * }
- *
- * <jc>// Option #1 - Registered via annotation.</jc>
- * <ja>@Rest</ja>(guards={BillyGuard.<jk>class</jk>})
- * <jk>public class</jk> MyResource {
- *
- * <jc>// Option #2 - Registered via builder passed in
through resource constructor.</jc>
- * <jk>public</jk> MyResource(RestContextBuilder
<jv>builder</jv>) <jk>throws</jk> Exception {
- *
- * <jc>// Using method on builder.</jc>
- *
<jv>builder</jv>.guards(BillyGuard.<jk>class</jk>);
- *
- * <jc>// Same, but using property.</jc>
- * <jv>builder</jv>.addTo(<jsf>REST_guards</jsf>,
BillyGuard.<jk>class</jk>);
- * }
- *
- * <jc>// Option #3 - Registered via builder passed in
through init method.</jc>
- * <ja>@RestHook</ja>(<jsf>INIT</jsf>)
- * <jk>public void</jk> init(RestContextBuilder
<jv>builder</jv>) <jk>throws</jk> Exception {
- *
<jv>builder</jv>.guards(BillyGuard.<jk>class</jk>);
- * }
- *
- * <jc>// Override at the method level.</jc>
- *
<ja>@RestGet</ja>(guards={SomeOtherGuard.<jk>class</jk>})
- * <jk>public</jk> Object myMethod() {...}
- * }
- * </p>
- *
- * <ul class='notes'>
- * <li>
- * When defined as a class, the implementation must have
one of the following constructors:
- * <ul>
- * <li><code><jk>public</jk> T(RestContext)</code>
- * <li><code><jk>public</jk> T()</code>
- * <li><code><jk>public static</jk> T
<jsm>create</jsm>(RestContext)</code>
- * <li><code><jk>public static</jk> T
<jsm>create</jsm>()</code>
- * </ul>
- * <li>
- * Inner classes of the REST resource class are allowed.
- * </ul>
- *
- * <ul class='seealso'>
- * <li class='link'>{@doc RestGuards}
- * </ul>
- */
- public static final String REST_guards = PREFIX + ".guards.lo";
-
- /**
* Configuration property: Messages.
*
* <h5 class='section'>Property:</h5>
diff --git
a/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/RestContextBuilder.java
b/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/RestContextBuilder.java
index 5bb24b5..e1924ba 100644
---
a/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/RestContextBuilder.java
+++
b/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/RestContextBuilder.java
@@ -1523,42 +1523,6 @@ public class RestContextBuilder extends
BeanContextBuilder implements ServletCon
}
/**
- * <i><l>RestContext</l> configuration property: </i> Class-level
guards.
- *
- * <p>
- * Associates one or more {@link RestGuard RestGuards} with all REST
methods defined in this class.
- *
- * <ul class='seealso'>
- * <li class='jf'>{@link RestContext#REST_guards}
- * </ul>
- *
- * @param values The values to add to this setting.
- * @return This object (for method chaining).
- */
- @FluentSetter
- public RestContextBuilder guards(Class<?>...values) {
- return prependTo(REST_guards, values);
- }
-
- /**
- * <i><l>RestContext</l> configuration property: </i> Class-level
guards.
- *
- * <p>
- * Same as {@link #guards(Class...)} except input is pre-constructed
instances.
- *
- * <ul class='seealso'>
- * <li class='jf'>{@link RestContext#REST_guards}
- * </ul>
- *
- * @param values The values to add to this setting.
- * @return This object (for method chaining).
- */
- @FluentSetter
- public RestContextBuilder guards(RestGuard...values) {
- return prependTo(REST_guards, values);
- }
-
- /**
* The maximum allowed input size (in bytes) on HTTP requests.
*
* <p>
diff --git
a/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/RestGuardList.java
b/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/RestGuardList.java
index b3be73a..b62bf3d 100644
---
a/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/RestGuardList.java
+++
b/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/RestGuardList.java
@@ -12,31 +12,121 @@
//
***************************************************************************************************************************
package org.apache.juneau.rest;
+import static java.util.Collections.*;
+import static java.util.stream.Collectors.*;
+
+import java.util.*;
+
+import org.apache.juneau.*;
import org.apache.juneau.collections.*;
+import org.apache.juneau.cp.*;
/**
* A list of {@link RestGuard} objects.
*/
-public class RestGuardList extends AList<RestGuard> {
+public class RestGuardList {
- private static final long serialVersionUID = 1L;
+ private final List<RestGuard> entries;
/**
* Static creator.
*
* @return An empty list.
*/
- @SuppressWarnings("unchecked")
- public static RestGuardList create() {
- return new RestGuardList();
+ public static Builder create() {
+ return new Builder();
+ }
+
+ /**
+ * Constructor.
+ *
+ * @param builder The builder containing the contents for this list.
+ */
+ protected RestGuardList(Builder builder) {
+ entries = unmodifiableList(
+ builder
+ .entries
+ .stream()
+ .map(x -> instantiate(x, builder.beanStore))
+ .collect(toList())
+ );
+ }
+
+ /**
+ * Builder for {@link RestGuardList} objects.
+ */
+ public static class Builder {
+
+ AList<Object> entries;
+ BeanStore beanStore;
+
+ /**
+ * Create an empty builder.
+ */
+ protected Builder() {
+ this.entries = AList.create();
+ }
+
+ /**
+ * Creates a new {@link RestGuardList} object using a snapshot
of the settings defined in this builder.
+ *
+ * @return A new {@link RestGuardList} object.
+ */
+ public RestGuardList build() {
+ return new RestGuardList(this);
+ }
+
+ /**
+ * Appends the specified rest matcher classes to the list.
+ *
+ * @param values The values to add.
+ * @return This object (for method chaining).
+ */
+ @SuppressWarnings("unchecked")
+ public Builder append(Class<? extends RestGuard>...values) {
+ entries.append((Object[])values);
+ return this;
+ }
+
+ /**
+ * Appends the specified rest matcher classes to the list.
+ *
+ * @param values The values to add.
+ * @return This object (for method chaining).
+ */
+ public Builder append(RestGuard...values) {
+ entries.append((Object[])values);
+ return this;
+ }
+
+ /**
+ * Specifies the bean store to use for instantiating rest
matcher classes.
+ *
+ * @param value The bean store to use for instantiating rest
matcher classes.
+ * @return This object (for method chaining).
+ */
+ public Builder beanStore(BeanStore value) {
+ beanStore = value;
+ return this;
+ }
+ }
+
+ private static RestGuard instantiate(Object o, BeanStore bs) {
+ if (o instanceof RestGuard)
+ return (RestGuard)o;
+ try {
+ return (RestGuard)bs.createBean((Class<?>)o);
+ } catch (ExecutableException e) {
+ throw new ConfigException(e, "Could not instantiate
class {0}", o);
+ }
}
/**
- * Returns the contents of this list as a {@link RestGuard} array.
+ * Returns the entries in this list.
*
- * @return The contents of this list as a {@link RestGuard} array.
+ * @return The entries in this list.
*/
public RestGuard[] asArray() {
- return asArrayOf(RestGuard.class);
+ return entries.toArray(new RestGuard[entries.size()]);
}
}
diff --git
a/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/RestMatcherList.java
b/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/RestMatcherList.java
index c2e4898..508baf1 100644
---
a/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/RestMatcherList.java
+++
b/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/RestMatcherList.java
@@ -18,6 +18,7 @@ import static java.util.Collections.*;
import java.util.*;
import org.apache.juneau.*;
+import org.apache.juneau.collections.*;
import org.apache.juneau.cp.*;
/**
@@ -25,15 +26,15 @@ import org.apache.juneau.cp.*;
*/
public class RestMatcherList {
- private final List<RestMatcher> matchers;
+ private final List<RestMatcher> entries;
/**
* Static creator.
*
* @return An empty list.
*/
- public static RestMatcherListBuilder create() {
- return new RestMatcherListBuilder();
+ public static Builder create() {
+ return new Builder();
}
/**
@@ -41,16 +42,75 @@ public class RestMatcherList {
*
* @param builder The builder containing the contents for this list.
*/
- protected RestMatcherList(RestMatcherListBuilder builder) {
- matchers = unmodifiableList(
+ protected RestMatcherList(Builder builder) {
+ entries = unmodifiableList(
builder
- .matchers
+ .entries
.stream()
.map(x -> instantiate(x, builder.beanStore))
.collect(toList())
);
}
+ /**
+ * Builder for {@link RestMatcherList} objects.
+ */
+ public static class Builder {
+
+ AList<Object> entries;
+ BeanStore beanStore;
+
+ /**
+ * Create an empty builder.
+ */
+ protected Builder() {
+ this.entries = AList.create();
+ }
+
+ /**
+ * Creates a new {@link RestMatcherList} object using a
snapshot of the settings defined in this builder.
+ *
+ * @return A new {@link RestMatcherList} object.
+ */
+ public RestMatcherList build() {
+ return new RestMatcherList(this);
+ }
+
+ /**
+ * Appends the specified rest matcher classes to the list.
+ *
+ * @param values The values to add.
+ * @return This object (for method chaining).
+ */
+ @SuppressWarnings("unchecked")
+ public Builder append(Class<? extends RestMatcher>...values) {
+ entries.append((Object[])values);
+ return this;
+ }
+
+ /**
+ * Appends the specified rest matcher classes to the list.
+ *
+ * @param values The values to add.
+ * @return This object (for method chaining).
+ */
+ public Builder append(RestMatcher...values) {
+ entries.append((Object[])values);
+ return this;
+ }
+
+ /**
+ * Specifies the bean store to use for instantiating rest
matcher classes.
+ *
+ * @param value The bean store to use for instantiating rest
matcher classes.
+ * @return This object (for method chaining).
+ */
+ public Builder beanStore(BeanStore value) {
+ beanStore = value;
+ return this;
+ }
+ }
+
private static RestMatcher instantiate(Object o, BeanStore bs) {
if (o instanceof RestMatcher)
return (RestMatcher)o;
@@ -62,11 +122,11 @@ public class RestMatcherList {
}
/**
- * Returns the matchers in this list.
+ * Returns the entries in this list.
*
- * @return The matchers in this list. The list is unmodifiable.
+ * @return The entries in this list.
*/
- public List<RestMatcher> getMatchers() {
- return matchers;
+ public List<RestMatcher> getEntries() {
+ return entries;
}
}
diff --git
a/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/RestMatcherListBuilder.java
b/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/RestMatcherListBuilder.java
deleted file mode 100644
index bad3a10..0000000
---
a/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/RestMatcherListBuilder.java
+++ /dev/null
@@ -1,77 +0,0 @@
-//
***************************************************************************************************************************
-// * Licensed to the Apache Software Foundation (ASF) under one or more
contributor license agreements. See the NOTICE file *
-// * distributed with this work for additional information regarding copyright
ownership. The ASF licenses this file *
-// * to you under the Apache License, Version 2.0 (the "License"); you may not
use this file except in compliance *
-// * with the License. You may obtain a copy of the License at
*
-// *
*
-// * http://www.apache.org/licenses/LICENSE-2.0
*
-// *
*
-// * Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an *
-// * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
express or implied. See the License for the *
-// * specific language governing permissions and limitations under the
License. *
-//
***************************************************************************************************************************
-package org.apache.juneau.rest;
-
-import org.apache.juneau.collections.*;
-import org.apache.juneau.cp.*;
-import org.apache.juneau.internal.*;
-
-/**
- * Builder for {@link RestMatcherList} objects.
- */
-@FluentSetters
-public class RestMatcherListBuilder {
-
- AList<Object> matchers;
- BeanStore beanStore;
-
- /**
- * Create an empty builder.
- */
- protected RestMatcherListBuilder() {
- this.matchers = AList.create();
- }
-
- /**
- * Creates a new {@link RestMatcherList} object using a snapshot of the
settings defined in this builder.
- *
- * @return A new {@link RestMatcherList} object.
- */
- public RestMatcherList build() {
- return new RestMatcherList(this);
- }
-
- /**
- * Appends the specified rest matcher classes to the list.
- *
- * @param values The values to add.
- * @return This object (for method chaining).
- */
- @SuppressWarnings("unchecked")
- public RestMatcherListBuilder append(Class<? extends
RestMatcher>...values) {
- matchers.append((Object[])values);
- return this;
- }
-
- /**
- * Appends the specified rest matcher classes to the list.
- *
- * @param values The values to add.
- * @return This object (for method chaining).
- */
- public RestMatcherListBuilder append(RestMatcher...values) {
- matchers.append((Object[])values);
- return this;
- }
-
- /**
- * Specifies the bean store to use for instantiating rest matcher
classes.
- *
- * @param value The bean store to use for instantiating rest matcher
classes.
- * @return This object (for method chaining).
- */
- public RestMatcherListBuilder beanStore(BeanStore value) {
- beanStore = value;
- return this;
- }
-}
diff --git
a/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/RestOpContext.java
b/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/RestOpContext.java
index a52b716..393f66a 100644
---
a/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/RestOpContext.java
+++
b/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/RestOpContext.java
@@ -169,8 +169,8 @@ public class RestOpContext extends BeanContext implements
Comparable<RestOpConte
bs.addBean(RestGuard[].class, guards);
RestMatcherList matchers = createMatchers(r, builder,
bs);
- requiredMatchers =
matchers.getMatchers().stream().filter(x ->
x.required()).toArray(RestMatcher[]::new);
- optionalMatchers =
matchers.getMatchers().stream().filter(x -> !
x.required()).toArray(RestMatcher[]::new);
+ requiredMatchers =
matchers.getEntries().stream().filter(x ->
x.required()).toArray(RestMatcher[]::new);
+ optionalMatchers =
matchers.getEntries().stream().filter(x -> !
x.required()).toArray(RestMatcher[]::new);
pathMatchers = createPathMatchers(r, cp, builder,
bs).asArray();
bs.addBean(UrlPathMatcher[].class, pathMatchers);
@@ -279,9 +279,9 @@ public class RestOpContext extends BeanContext implements
Comparable<RestOpConte
* <p>
* Instantiates based on the following logic:
* <ul>
- * <li>Looks for {@link RestContext#REST_guards} value set via any
of the following:
+ * <li>Looks for guards set via any of the following:
* <ul>
- * <li>{@link
RestContextBuilder#guards(Class...)}/{@link
RestContextBuilder#guards(RestGuard...)}
+ * <li>{@link
RestOpContextBuilder#guards(Class...)}/{@link
RestOpContextBuilder#guards(RestGuard...)}
* <li>{@link RestOp#guards()}.
* <li>{@link Rest#guards()}.
* </ul>
@@ -302,23 +302,17 @@ public class RestOpContext extends BeanContext implements
Comparable<RestOpConte
* @param beanStore The bean store to use for retrieving and creating
beans.
* @return The guards for this REST resource method.
* @throws Exception If guards could not be instantiated.
- * @see RestContext#REST_guards
*/
protected RestGuardList createGuards(Object resource,
RestOpContextBuilder builder, BeanStore beanStore) throws Exception {
- RestGuardList x = RestGuardList.create();
-
-
x.append(builder.getContextProperties().getInstanceArray(REST_guards,
RestGuard.class, beanStore).orElse(new RestGuard[0]));
-
- if (x.isEmpty())
- x = beanStore.getBean(RestGuardList.class).orElse(x);
+ RestGuardList.Builder x = builder.guards.beanStore(beanStore);
Set<String> rolesDeclared = builder.rolesDeclared;
Set<String> roleGuard =
ofNullable(builder.roleGuard).orElseGet(()->new LinkedHashSet<>());
for (String rg : roleGuard) {
try {
- x.add(new RoleBasedRestGuard(rolesDeclared,
rg));
+ x.append(new RoleBasedRestGuard(rolesDeclared,
rg));
} catch (java.text.ParseException e1) {
throw new ServletException(e1);
}
@@ -326,14 +320,14 @@ public class RestOpContext extends BeanContext implements
Comparable<RestOpConte
x = BeanStore
.of(beanStore, resource)
- .addBean(RestGuardList.class, x)
- .beanCreateMethodFinder(RestGuardList.class, resource)
+ .addBean(RestGuardList.Builder.class, x)
+ .beanCreateMethodFinder(RestGuardList.Builder.class,
resource)
.find("createGuards", Method.class)
.thenFind("createGuards")
.withDefault(x)
.run();
- return x;
+ return x.build();
}
/**
@@ -366,7 +360,7 @@ public class RestOpContext extends BeanContext implements
Comparable<RestOpConte
*/
protected RestMatcherList createMatchers(Object resource,
RestOpContextBuilder builder, BeanStore beanStore) throws Exception {
- RestMatcherListBuilder x =
builder.restMatchers.beanStore(beanStore);
+ RestMatcherList.Builder x =
builder.restMatchers.beanStore(beanStore);
String clientVersion = builder.clientVersion;
if (clientVersion != null)
@@ -374,8 +368,8 @@ public class RestOpContext extends BeanContext implements
Comparable<RestOpConte
x = BeanStore
.of(beanStore, resource)
- .addBean(RestMatcherListBuilder.class, x)
- .beanCreateMethodFinder(RestMatcherListBuilder.class,
resource)
+ .addBean(RestMatcherList.Builder.class, x)
+ .beanCreateMethodFinder(RestMatcherList.Builder.class,
resource)
.find("createMatchers", Method.class)
.withDefault(x)
.run();
diff --git
a/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/RestOpContextBuilder.java
b/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/RestOpContextBuilder.java
index c30f999..c5e70a2 100644
---
a/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/RestOpContextBuilder.java
+++
b/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/RestOpContextBuilder.java
@@ -45,9 +45,10 @@ public class RestOpContextBuilder extends BeanContextBuilder
{
PartListBuilder defaultFormData, defaultQueryData;
NamedAttributeList defaultRequestAttributes;
HeaderListBuilder defaultRequestHeaders, defaultResponseHeaders;
- RestMatcherListBuilder restMatchers;
+ RestMatcherList.Builder restMatchers;
List<MediaType> produces, consumes;
Set<String> roleGuard, rolesDeclared;
+ RestGuardList.Builder guards = RestGuardList.create();
Charset defaultCharset;
Long maxInput;
@@ -416,6 +417,93 @@ public class RestOpContextBuilder extends
BeanContextBuilder {
}
/**
+ * Guards.
+ *
+ * <p>
+ * Associates one or more {@link RestGuard RestGuards} with this method.
+ *
+ * <p>
+ * If multiple guards are specified, <b>ALL</b> guards must pass.
+ * <br>Note that this is different than matchers where only ONE matcher
needs to pass.
+ *
+ * <h5 class='section'>Example:</h5>
+ * <p class='bcode w800'>
+ * <jc>// Define a guard that only lets Billy make a request.</jc>
+ * <jk>public</jk> BillyGuard <jk>extends</jk> RestGuard {
+ * <ja>@Override</ja>
+ * <jk>public boolean</jk> isRequestAllowed(RestRequest
<jv>req</jv>) {
+ * <jk>return</jk>
<jv>req</jv>.getUserPrincipal().getName().equals(<js>"Billy"</js>);
+ * }
+ * }
+ *
+ * <jc>// Option #1 - Registered via annotation.</jc>
+ * <ja>@Rest</ja>(guards={BillyGuard.<jk>class</jk>})
+ * <jk>public class</jk> MyResource {
+ *
+ * <jc>// Option #2 - Registered via builder passed in
through resource constructor.</jc>
+ * <jk>public</jk> MyResource(RestContextBuilder
<jv>builder</jv>) <jk>throws</jk> Exception {
+ *
+ * <jc>// Using method on builder.</jc>
+ *
<jv>builder</jv>.guards(BillyGuard.<jk>class</jk>);
+ * }
+ *
+ * <jc>// Option #3 - Registered via builder passed in
through init method.</jc>
+ * <ja>@RestHook</ja>(<jsf>INIT</jsf>)
+ * <jk>public void</jk> init(RestContextBuilder
<jv>builder</jv>) <jk>throws</jk> Exception {
+ *
<jv>builder</jv>.guards(BillyGuard.<jk>class</jk>);
+ * }
+ *
+ * <jc>// Override at the method level.</jc>
+ *
<ja>@RestGet</ja>(guards={SomeOtherGuard.<jk>class</jk>})
+ * <jk>public</jk> Object myMethod() {...}
+ * }
+ * </p>
+ *
+ * <ul class='notes'>
+ * <li>
+ * When defined as a class, the implementation must have
one of the following constructors:
+ * <ul>
+ * <li><code><jk>public</jk> T(RestContext)</code>
+ * <li><code><jk>public</jk> T()</code>
+ * <li><code><jk>public static</jk> T
<jsm>create</jsm>(RestContext)</code>
+ * <li><code><jk>public static</jk> T
<jsm>create</jsm>()</code>
+ * </ul>
+ * <li>
+ * Inner classes of the REST resource class are allowed.
+ * </ul>
+ *
+ * <ul class='seealso'>
+ * <li class='link'>{@doc RestGuards}
+ * <li class='ja'>{@link Rest#guards()}
+ * <li class='ja'>{@link RestOp#guards()}
+ * </ul>
+ *
+ * @param values The values to add to this setting.
+ * @return This object (for method chaining).
+ */
+ @SuppressWarnings("unchecked")
+ @FluentSetter
+ public RestOpContextBuilder guards(Class<? extends RestGuard>...values)
{
+ guards.append(values);
+ return this;
+ }
+
+ /**
+ * Guards.
+ *
+ * <p>
+ * Same as {@link #guards(Class...)} except input is pre-constructed
instances.
+ *
+ * @param values The values to add to this setting.
+ * @return This object (for method chaining).
+ */
+ @FluentSetter
+ public RestOpContextBuilder guards(RestGuard...values) {
+ guards.append(values);
+ return this;
+ }
+
+ /**
* HTTP method name.
*
* <p>
diff --git
a/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/annotation/Rest.java
b/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/annotation/Rest.java
index a426707..4ee871e 100644
---
a/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/annotation/Rest.java
+++
b/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/annotation/Rest.java
@@ -628,7 +628,7 @@ public @interface Rest {
* Associates one or more {@link RestGuard RestGuards} with all REST
methods defined in this class.
*
* <ul class='seealso'>
- * <li class='jf'>{@link RestContext#REST_guards}
+ * <li class='jm'>{@link RestOpContextBuilder#guards(Class...)}
* </ul>
*/
Class<? extends RestGuard>[] guards() default {};
diff --git
a/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/annotation/RestAnnotation.java
b/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/annotation/RestAnnotation.java
index d2d5a44..435d647 100644
---
a/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/annotation/RestAnnotation.java
+++
b/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/annotation/RestAnnotation.java
@@ -1106,7 +1106,7 @@ public class RestAnnotation {
stringStream(a.produces()).map(MediaType::of).forEach(x
-> b.produces(x));
stringStream(a.consumes()).map(MediaType::of).forEach(x
-> b.consumes(x));
b.prependTo(REST_converters, a.converters());
- b.prependTo(REST_guards, reverse(a.guards()));
+ b.guards(a.guards());
value(a.defaultCharset()).map(Charset::forName).ifPresent(x ->
b.defaultCharset(x));
value(a.maxInput()).ifPresent(x -> b.maxInput(x));
cdStream(a.rolesDeclared()).forEach(x ->
b.rolesDeclared(x));
diff --git
a/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/annotation/RestDelete.java
b/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/annotation/RestDelete.java
index 33156e8..a2781e2 100644
---
a/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/annotation/RestDelete.java
+++
b/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/annotation/RestDelete.java
@@ -327,7 +327,7 @@ public @interface RestDelete {
* Associates one or more {@link RestGuard RestGuards} with this method.
*
* <ul class='seealso'>
- * <li class='jf'>{@link RestContext#REST_guards}
+ * <li class='jm'>{@link RestOpContextBuilder#guards(Class...)}
* </ul>
*/
Class<? extends RestGuard>[] guards() default {};
diff --git
a/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/annotation/RestDeleteAnnotation.java
b/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/annotation/RestDeleteAnnotation.java
index b01d6ee..6ef318f 100644
---
a/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/annotation/RestDeleteAnnotation.java
+++
b/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/annotation/RestDeleteAnnotation.java
@@ -463,7 +463,7 @@ public class RestDeleteAnnotation {
stringStream(a.defaultRequestAttributes()).map(x ->
BasicNamedAttribute.ofPair(x)).forEach(x -> b.defaultRequestAttributes(x));
stringStream(a.defaultQueryData()).map(x ->
basicPart(x)).forEach(x -> b.defaultQueryData(x));
b.appendToIfNotEmpty(REST_defaultRequestHeaders,
accept(string(a.defaultAccept())));
- b.prependTo(REST_guards, reverse(a.guards()));
+ b.guards(a.guards());
b.matchers(a.matchers());
value(a.clientVersion()).ifPresent(x ->
b.clientVersion(x));
value(a.defaultCharset()).map(Charset::forName).ifPresent(x ->
b.defaultCharset(x));
diff --git
a/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/annotation/RestGet.java
b/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/annotation/RestGet.java
index a3cfb9d..5fcb202 100644
---
a/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/annotation/RestGet.java
+++
b/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/annotation/RestGet.java
@@ -342,7 +342,7 @@ public @interface RestGet {
* Associates one or more {@link RestGuard RestGuards} with this method.
*
* <ul class='seealso'>
- * <li class='jf'>{@link RestContext#REST_guards}
+ * <li class='jm'>{@link RestOpContextBuilder#guards(Class...)}
* </ul>
*/
Class<? extends RestGuard>[] guards() default {};
diff --git
a/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/annotation/RestGetAnnotation.java
b/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/annotation/RestGetAnnotation.java
index 5e162ed..8db30b5 100644
---
a/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/annotation/RestGetAnnotation.java
+++
b/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/annotation/RestGetAnnotation.java
@@ -520,7 +520,7 @@ public class RestGetAnnotation {
stringStream(a.defaultQueryData()).map(x ->
basicPart(x)).forEach(x -> b.defaultQueryData(x));
b.appendToIfNotEmpty(REST_defaultRequestHeaders,
accept(string(a.defaultAccept())));
b.prependTo(REST_converters, a.converters());
- b.prependTo(REST_guards, reverse(a.guards()));
+ b.guards(a.guards());
b.matchers(a.matchers());
value(a.clientVersion()).ifPresent(x ->
b.clientVersion(x));
value(a.defaultCharset()).map(Charset::forName).ifPresent(x ->
b.defaultCharset(x));
diff --git
a/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/annotation/RestOp.java
b/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/annotation/RestOp.java
index 7b1dc97..f952c35 100644
---
a/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/annotation/RestOp.java
+++
b/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/annotation/RestOp.java
@@ -397,7 +397,7 @@ public @interface RestOp {
* Associates one or more {@link RestGuard RestGuards} with this method.
*
* <ul class='seealso'>
- * <li class='jf'>{@link RestContext#REST_guards}
+ * <li class='jm'>{@link RestOpContextBuilder#guards(Class...)}
* </ul>
*/
Class<? extends RestGuard>[] guards() default {};
diff --git
a/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/annotation/RestOpAnnotation.java
b/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/annotation/RestOpAnnotation.java
index 6fffef0..a709fde 100644
---
a/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/annotation/RestOpAnnotation.java
+++
b/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/annotation/RestOpAnnotation.java
@@ -624,7 +624,7 @@ public class RestOpAnnotation {
b.appendToIfNotEmpty(REST_defaultRequestHeaders,
accept(string(a.defaultAccept())));
b.appendToIfNotEmpty(REST_defaultRequestHeaders,
contentType(string(a.defaultContentType())));
b.prependTo(REST_converters, a.converters());
- b.prependTo(REST_guards, reverse(a.guards()));
+ b.guards(a.guards());
b.matchers(a.matchers());
value(a.clientVersion()).ifPresent(x ->
b.clientVersion(x));
value(a.defaultCharset()).map(Charset::forName).ifPresent(x ->
b.defaultCharset(x));
diff --git
a/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/annotation/RestPost.java
b/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/annotation/RestPost.java
index 6e10b81..3e3e1ac 100644
---
a/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/annotation/RestPost.java
+++
b/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/annotation/RestPost.java
@@ -399,7 +399,7 @@ public @interface RestPost {
* Associates one or more {@link RestGuard RestGuards} with this method.
*
* <ul class='seealso'>
- * <li class='jf'>{@link RestContext#REST_guards}
+ * <li class='jm'>{@link RestOpContextBuilder#guards(Class...)}
* </ul>
*/
Class<? extends RestGuard>[] guards() default {};
diff --git
a/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/annotation/RestPostAnnotation.java
b/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/annotation/RestPostAnnotation.java
index ce348f9..cb9d910 100644
---
a/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/annotation/RestPostAnnotation.java
+++
b/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/annotation/RestPostAnnotation.java
@@ -609,7 +609,7 @@ public class RestPostAnnotation {
b.appendToIfNotEmpty(REST_defaultRequestHeaders,
accept(string(a.defaultAccept())));
b.appendToIfNotEmpty(REST_defaultRequestHeaders,
contentType(string(a.defaultContentType())));
b.prependTo(REST_converters, a.converters());
- b.prependTo(REST_guards, reverse(a.guards()));
+ b.guards(a.guards());
b.matchers(a.matchers());
value(a.clientVersion()).ifPresent(x ->
b.clientVersion(x));
value(a.defaultCharset()).map(Charset::forName).ifPresent(x ->
b.defaultCharset(x));
diff --git
a/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/annotation/RestPut.java
b/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/annotation/RestPut.java
index cb675c7..5fa3084 100644
---
a/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/annotation/RestPut.java
+++
b/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/annotation/RestPut.java
@@ -399,7 +399,7 @@ public @interface RestPut {
* Associates one or more {@link RestGuard RestGuards} with this method.
*
* <ul class='seealso'>
- * <li class='jf'>{@link RestContext#REST_guards}
+ * <li class='jm'>{@link RestOpContextBuilder#guards(Class...)}
* </ul>
*/
Class<? extends RestGuard>[] guards() default {};
diff --git
a/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/annotation/RestPutAnnotation.java
b/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/annotation/RestPutAnnotation.java
index bb5975b..8459b51 100644
---
a/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/annotation/RestPutAnnotation.java
+++
b/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/annotation/RestPutAnnotation.java
@@ -609,7 +609,7 @@ public class RestPutAnnotation {
b.appendToIfNotEmpty(REST_defaultRequestHeaders,
accept(string(a.defaultAccept())));
b.appendToIfNotEmpty(REST_defaultRequestHeaders,
contentType(string(a.defaultContentType())));
b.prependTo(REST_converters, a.converters());
- b.prependTo(REST_guards, reverse(a.guards()));
+ b.guards(a.guards());
b.matchers(a.matchers());
value(a.clientVersion()).ifPresent(x ->
b.clientVersion(x));
value(a.defaultCharset()).map(Charset::forName).ifPresent(x ->
b.defaultCharset(x));