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/08/06 17:28:51 UTC
[juneau] branch jbFixRestNpe updated: Replace @RestHook with @RestInit/etc...
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
The following commit(s) were added to refs/heads/jbFixRestNpe by this push:
new 3b21d86b3 Replace @RestHook with @RestInit/etc...
3b21d86b3 is described below
commit 3b21d86b325d8611e97b8a655570323a445792c3
Author: JamesBognar <ja...@salesforce.com>
AuthorDate: Sat Aug 6 13:23:17 2022 -0400
Replace @RestHook with @RestInit/etc...
---
.../java/org/apache/juneau/reflect/FieldInfo.java | 2 +
juneau-doc/docs/ReleaseNotes/6.4.0.html | 2 +-
.../05.jrs.LifecycleHooks.html | 41 +-
.../02.jrs.JavaMethodParameters.html | 2 +-
.../08.juneau-rest-server/05.jrs.Marshalling.html | 2 +-
.../08.juneau-rest-server/12.jrs.SvlVariables.html | 2 +-
.../08.juneau-rest-server/13.jrs.StaticFiles.html | 3 +-
.../16.jrs.ExecutionStatistics.html | 2 +-
.../18.jrs.LoggingAndDebugging.html | 3 +-
.../08.juneau-rest-server/22.jrs.RestContext.html | 6 +-
.../23.jrs.RestOpContext.html | 4 +-
juneau-doc/src/main/javadoc/overview.html | 67 +--
.../microservice/resources/LogsResource.java | 3 +-
.../rest/test/client/ThirdPartyProxyResource.java | 8 +-
.../java/org/apache/juneau/rest/RestChildren.java | 6 +-
.../java/org/apache/juneau/rest/RestContext.java | 200 ++++---
.../java/org/apache/juneau/rest/RestOpContext.java | 4 +-
.../java/org/apache/juneau/rest/RestSession.java | 4 +-
.../apache/juneau/rest/annotation/HookEvent.java | 481 ----------------
.../apache/juneau/rest/annotation/RestDestroy.java | 100 ++++
...kAnnotation.java => RestDestroyAnnotation.java} | 41 +-
.../apache/juneau/rest/annotation/RestEndCall.java | 114 ++++
...kAnnotation.java => RestEndCallAnnotation.java} | 41 +-
.../apache/juneau/rest/annotation/RestHook.java | 125 -----
.../apache/juneau/rest/annotation/RestInit.java | 105 ++++
...HookAnnotation.java => RestInitAnnotation.java} | 41 +-
.../juneau/rest/annotation/RestPostCall.java | 175 ++++++
...Annotation.java => RestPostCallAnnotation.java} | 41 +-
.../juneau/rest/annotation/RestPostInit.java | 95 ++++
...Annotation.java => RestPostInitAnnotation.java} | 37 +-
.../apache/juneau/rest/annotation/RestPreCall.java | 182 +++++++
...kAnnotation.java => RestPreCallAnnotation.java} | 41 +-
.../juneau/rest/annotation/RestStartCall.java | 106 ++++
...nnotation.java => RestStartCallAnnotation.java} | 41 +-
.../org/apache/juneau/rest/arg/DefaultArg.java | 1 -
.../org/apache/juneau/rest/servlet/RestObject.java | 67 ++-
.../apache/juneau/rest/servlet/RestServlet.java | 61 +--
...n_Test.java => RestDestroyAnnotation_Test.java} | 29 +-
...n_Test.java => RestEndCallAnnotation_Test.java} | 29 +-
.../juneau/rest/annotation/RestHook_Test.java | 603 ---------------------
...tion_Test.java => RestInitAnnotation_Test.java} | 29 +-
.../{Rest_Context_Test.java => RestInit_Test.java} | 135 +++--
..._Test.java => RestPostCallAnnotation_Test.java} | 29 +-
...st_Context_Test.java => RestPostCall_Test.java} | 117 ++--
..._Test.java => RestPostInitAnnotation_Test.java} | 34 +-
.../juneau/rest/annotation/RestPostInit_Test.java | 209 +++++++
...n_Test.java => RestPreCallAnnotation_Test.java} | 29 +-
...est_Context_Test.java => RestPreCall_Test.java} | 118 ++--
...Test.java => RestStartCallAnnotation_Test.java} | 29 +-
...t_Context_Test.java => RestStartCall_Test.java} | 117 ++--
.../juneau/rest/annotation/Rest_Context_Test.java | 8 +-
.../Rest_DefaultRequestAttributes_Test.java | 184 +++++++
.../juneau/rest/annotation/Rest_Messages_Test.java | 8 +-
53 files changed, 1899 insertions(+), 2064 deletions(-)
diff --git a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/reflect/FieldInfo.java b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/reflect/FieldInfo.java
index 2abdfaa95..06be5cbf1 100644
--- a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/reflect/FieldInfo.java
+++ b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/reflect/FieldInfo.java
@@ -486,6 +486,7 @@ public final class FieldInfo implements Comparable<FieldInfo> {
* Returns the field value on the specified object.
*
* @param o The object containing the field.
+ * @param <T> The object type to retrieve.
* @return The field value.
* @throws BeanRuntimeException Field was not accessible or field does not belong to object.
*/
@@ -503,6 +504,7 @@ public final class FieldInfo implements Comparable<FieldInfo> {
* Same as {@link #get(Object)} but wraps the results in an {@link Optional}.
*
* @param o The object containing the field.
+ * @param <T> The object type to retrieve.
* @return The field value.
* @throws BeanRuntimeException Field was not accessible or field does not belong to object.
*/
diff --git a/juneau-doc/docs/ReleaseNotes/6.4.0.html b/juneau-doc/docs/ReleaseNotes/6.4.0.html
index 6418a73ef..c0caf253e 100644
--- a/juneau-doc/docs/ReleaseNotes/6.4.0.html
+++ b/juneau-doc/docs/ReleaseNotes/6.4.0.html
@@ -381,7 +381,7 @@
<ul class='spaced-list'>
<li>
Revamped and simplified servlet and REST-call lifecycle handling through new
- {@link oajr.annotation.RestHook @RestHook} annotation.
+ {@del @RestHook} annotation.
<ul>
<li>The {@del oajr.RestServlet#init(ServletConfig)} method is now final and can
no longer be extended.
diff --git a/juneau-doc/docs/Topics/08.juneau-rest-server/02.jrs.AnnotatedClasses/05.jrs.LifecycleHooks.html b/juneau-doc/docs/Topics/08.juneau-rest-server/02.jrs.AnnotatedClasses/05.jrs.LifecycleHooks.html
index c1341c94c..beaf8c43f 100644
--- a/juneau-doc/docs/Topics/08.juneau-rest-server/02.jrs.AnnotatedClasses/05.jrs.LifecycleHooks.html
+++ b/juneau-doc/docs/Topics/08.juneau-rest-server/02.jrs.AnnotatedClasses/05.jrs.LifecycleHooks.html
@@ -29,7 +29,7 @@
| <jc>// Our database.</jc>
| <jk>private</jk> Map<Integer,Object> <jf>myDatabase</jf>;
|
- | <ja>@RestHook</ja>(<jsf>INIT</jsf>)
+ | <ja>@RestInit</ja>
| <jk>public void</jk> initMyDatabase(RestContext.Builder <jv>builder</jv>) <jk>throws</jk> Exception {
| <jf>myDatabase</jf> = <jk>new</jk> LinkedHashMap<>();
| }
@@ -43,39 +43,30 @@
| <jk>public class</jk> MyResource <jk>extends</jk> BasicRestObject <jk>implements</jk> BasicUniversalConfig {
|
| <jc>// Add a request attribute to all incoming requests.</jc>
- | <ja>@RestHook</ja>(<jsf>PRE_CALL</jsf>)
+ | <ja>@RestPreCall</ja>
| <jk>public void</jk> onPreCall(RestRequest <jv>req</jv>) {
| <jv>req</jv>.setAttribute(<js>"foo"</js>, <js>"bar"</js>);
| }
| }
</p>
<p>
- The hook events can be broken down into two categories:
+ The following lifecycle annotations are provided.
</p>
<ul class='javatree'>
- <li class='je'>{@link oajr.annotation.HookEvent}
- <ul class='spaced-list'>
- <li>Resource lifecycle events:
- <ul class='javatree'>
- <li class='jf'>{@link oajr.annotation.HookEvent#INIT INIT} - Right before initialization.
- <li class='jf'>{@link oajr.annotation.HookEvent#POST_INIT POST_INIT} - Right after initialization.
- <li class='jf'>{@link oajr.annotation.HookEvent#POST_INIT_CHILD_FIRST POST_INIT_CHILD_FIRST} - Right after initialization but run child methods first.
- <li class='jf'>{@link oajr.annotation.HookEvent#DESTROY DESTROY} - Right before servlet destroy.
- </ul>
- </li>
- <li>REST call lifecycle events:
- <ul class='javatree'>
- <li class='jf'>{@link oajr.annotation.HookEvent#START_CALL START_CALL} - At the beginning of a REST call.
- <li class='jf'>{@link oajr.annotation.HookEvent#PRE_CALL PRE_CALL} - Right before the <ja>@RestOp</ja> method is invoked.
- <li class='jf'>{@link oajr.annotation.HookEvent#POST_CALL POST_CALL} - Right after the <ja>@RestOp</ja> method is invoked.
- <li class='jf'>{@link oajr.annotation.HookEvent#END_CALL END_CALL} - At the end of the REST call after the response has been flushed.
- </ul>
- </li>
+ <li>Resource lifecycle events:
+ <ul class='javatree'>
+ <li class='ja'>{@link oajr.annotation.RestInit} - Right before initialization.
+ <li class='ja'>{@link oajr.annotation.RestPostInit} - Right after initialization.
+ <li class='ja'>{@link oajr.annotation.RestDestroy} - Right before servlet destroy.
+ </ul>
+ </li>
+ <li>REST call lifecycle events:
+ <ul class='javatree'>
+ <li class='ja'>{@link oajr.annotation.RestStartCall} - At the beginning of a REST call.
+ <li class='ja'>{@link oajr.annotation.RestPreCall} - Right before the <ja>@RestOp</ja> method is invoked.
+ <li class='ja'>{@link oajr.annotation.RestPostCall} - Right after the <ja>@RestOp</ja> method is invoked.
+ <li class='ja'>{@link oajr.annotation.RestEndCall} - At the end of the REST call after the response has been flushed.
</ul>
</li>
- </ul>
-
- <ul class='seealso'>
- <li class='ja'>{@link oajr.annotation.RestHook}
</ul>
</div>
\ No newline at end of file
diff --git a/juneau-doc/docs/Topics/08.juneau-rest-server/03.jrs.RestOpAnnotatedMethods/02.jrs.JavaMethodParameters.html b/juneau-doc/docs/Topics/08.juneau-rest-server/03.jrs.RestOpAnnotatedMethods/02.jrs.JavaMethodParameters.html
index 1edd7a2a1..148258bf3 100644
--- a/juneau-doc/docs/Topics/08.juneau-rest-server/03.jrs.RestOpAnnotatedMethods/02.jrs.JavaMethodParameters.html
+++ b/juneau-doc/docs/Topics/08.juneau-rest-server/03.jrs.RestOpAnnotatedMethods/02.jrs.JavaMethodParameters.html
@@ -183,6 +183,6 @@
</p>
<p>
Additional parameter types can be defined by overriding {@link oajr.RestContext.Builder#createRestOpArgs(BeanStore,Supplier)} or
- by adding them to the bean store using {@link oajr.RestContext.Builder#createBeanStore(Class,Supplier)}.
+ by adding them to the bean store using {@link oajr.RestContext.Builder#createBeanStore(Supplier)}.
</p>
</div>
\ No newline at end of file
diff --git a/juneau-doc/docs/Topics/08.juneau-rest-server/05.jrs.Marshalling.html b/juneau-doc/docs/Topics/08.juneau-rest-server/05.jrs.Marshalling.html
index f3751eaa5..9001c3427 100644
--- a/juneau-doc/docs/Topics/08.juneau-rest-server/05.jrs.Marshalling.html
+++ b/juneau-doc/docs/Topics/08.juneau-rest-server/05.jrs.Marshalling.html
@@ -91,7 +91,7 @@
| <ja>@Rest</ja>
| <jk>public class</jk> MyResource {
|
- | <ja>@RestHook</ja>(<jsf>INIT</jsf>)
+ | <ja>@RestInit</ja>
| <jk>public void</jk> init(RestContext.Builder <jv>builder</jv>) {
| <jv>builder</jv>.serializers().add(JsonSerializer.<jk>class</jk>, HtmlSerializer.<jk>class</jk>);
| <jv>builder</jv>.parsers().add(JsonParser.<jk>class</jk>, HtmlParser.<jk>class</jk>);
diff --git a/juneau-doc/docs/Topics/08.juneau-rest-server/12.jrs.SvlVariables.html b/juneau-doc/docs/Topics/08.juneau-rest-server/12.jrs.SvlVariables.html
index 5f2f333e4..e02eb9e4b 100644
--- a/juneau-doc/docs/Topics/08.juneau-rest-server/12.jrs.SvlVariables.html
+++ b/juneau-doc/docs/Topics/08.juneau-rest-server/12.jrs.SvlVariables.html
@@ -251,7 +251,7 @@
<ul class='javatree'>
<li class='jc'>{@link oajr.RestContext.Builder}
<ul class='javatreec'>
- <li class='jmp'>{@link oajr.RestContext.Builder#createVarResolver(BeanStore,Class) createVarResolver(BeanStore,Class)}
+ <li class='jmp'>{@link oajr.RestContext.Builder#createVarResolver(BeanStore,Supplier,Class) createVarResolver(BeanStore,Supplier,Class)}
<li class='jm'>{@link oajr.RestContext.Builder#varResolver() varResolver()}
<li class='jm'>{@link oajr.RestContext.Builder#varResolver(Consumer) varResolver(Consumer)}
</ul>
diff --git a/juneau-doc/docs/Topics/08.juneau-rest-server/13.jrs.StaticFiles.html b/juneau-doc/docs/Topics/08.juneau-rest-server/13.jrs.StaticFiles.html
index 4df5d8bc4..3d5d1ac40 100644
--- a/juneau-doc/docs/Topics/08.juneau-rest-server/13.jrs.StaticFiles.html
+++ b/juneau-doc/docs/Topics/08.juneau-rest-server/13.jrs.StaticFiles.html
@@ -63,9 +63,8 @@
<ul class='javatree'>
<li class='jc'>{@link oajr.RestContext.Builder}
<ul class='javatreec'>
- <li class='jmp'>{@link oajr.RestContext.Builder#createStaticFiles(BeanStore,Supplier) createStaticFiles(BeanStore,Supplier)}
+ <li class='jmp'>{@link oajr.RestContext.Builder#createStaticFiles() createStaticFiles(BeanStore,Supplier)}
<li class='jm'>{@link oajr.RestContext.Builder#staticFiles() staticFiles()}
- <li class='jm'>{@link oajr.RestContext.Builder#staticFiles(Consumer) staticFiles(Consumer)}
</ul>
</li>
</ul>
diff --git a/juneau-doc/docs/Topics/08.juneau-rest-server/16.jrs.ExecutionStatistics.html b/juneau-doc/docs/Topics/08.juneau-rest-server/16.jrs.ExecutionStatistics.html
index bf525042c..f5d923a8e 100644
--- a/juneau-doc/docs/Topics/08.juneau-rest-server/16.jrs.ExecutionStatistics.html
+++ b/juneau-doc/docs/Topics/08.juneau-rest-server/16.jrs.ExecutionStatistics.html
@@ -18,7 +18,7 @@
<div class='topic'>
<p>
{@link oajr.annotation.Rest}-annotated classes get automated timing and error statistic information for all <ja>@RestOp</ja>
- and <ja>@RestHook</ja> annotated methods on the class.
+ and lifecycle-event annotated methods on the class.
</p>
<p>
If you extend from {@link oajr.servlet.BasicRestServlet} or {@link oajr.servlet.BasicRestObject}, then
diff --git a/juneau-doc/docs/Topics/08.juneau-rest-server/18.jrs.LoggingAndDebugging.html b/juneau-doc/docs/Topics/08.juneau-rest-server/18.jrs.LoggingAndDebugging.html
index 8274c7a43..23dc4cc74 100644
--- a/juneau-doc/docs/Topics/08.juneau-rest-server/18.jrs.LoggingAndDebugging.html
+++ b/juneau-doc/docs/Topics/08.juneau-rest-server/18.jrs.LoggingAndDebugging.html
@@ -93,7 +93,6 @@
<ul class='javatreec'>
<li class='jmp'>{@link oajr.RestContext.Builder#createDebugEnablement(BeanStore,Supplier) createDebugEnablement(BeanStore,Supplier)}
<li class='jm'>{@link oajr.RestContext.Builder#debugEnablement() debugEnablement()}
- <li class='jm'>{@link oajr.RestContext.Builder#debugEnablement(Consumer) debugEnablement(Consumer)}
</ul>
</li>
</ul>
@@ -169,7 +168,7 @@
</li>
<li class='jc'>{@link oajr.RestContext.Builder}
<ul class='javatreec'>
- <li class='jmp'>{@link oajr.RestContext.Builder#createCallLogger() createCallLogger()}
+ <li class='jmp'>{@link oajr.RestContext.Builder#createCallLogger(BeanStore,Supplier) createCallLogger(BeanStore,Supplier)}
<li class='jm'>{@link oajr.RestContext.Builder#callLogger() callLogger()}
</ul>
</li>
diff --git a/juneau-doc/docs/Topics/08.juneau-rest-server/22.jrs.RestContext.html b/juneau-doc/docs/Topics/08.juneau-rest-server/22.jrs.RestContext.html
index e8f0d4cb8..3f09c6b48 100644
--- a/juneau-doc/docs/Topics/08.juneau-rest-server/22.jrs.RestContext.html
+++ b/juneau-doc/docs/Topics/08.juneau-rest-server/22.jrs.RestContext.html
@@ -41,8 +41,8 @@
| .debugEnablement(<jsf>CONDITIONAL</jsf>);
| }
|
- | <jc>// Option #2 - Use an INIT hook.</jc>
- | <ja>@RestHook</ja>(<jsf>INIT</jsf>)
+ | <jc>// Option #2 - Use an init hook.</jc>
+ | <ja>@RestInit</ja>
| <jk>public void</jk> init(RestContext.Builder <jv>builder</jv>) <jk>throws</jk> Exception {
| <jv>builder</jv>
| .beanContext(<jv>x</jv> -> <jv>x</jv>.swaps(TemporalCalendarSwap.Rfc1123DateTime.<jk>class</jk>))
@@ -68,9 +68,7 @@
<li class='jm'>{@link oaj.rest.RestContext.Builder#children(Object...) children}
<li class='jm'>{@link oaj.rest.RestContext.Builder#config(Config) config}
<li class='jm'>{@link oaj.rest.RestContext.Builder#consumes(MediaType...) consumes}
- <li class='jm'>{@link oaj.rest.RestContext.Builder#debug(Enablement) debug}
<li class='jm'>{@link oaj.rest.RestContext.Builder#debugDefault(Enablement) debugDefault}
- <li class='jm'>{@link oaj.rest.RestContext.Builder#debugOn(String) debugOn}
<li class='jm'>{@link oaj.rest.RestContext.Builder#defaultAccept(String) defaultAccept}
<li class='jm'>{@link oaj.rest.RestContext.Builder#defaultCharset(Charset) defaultCharset}
<li class='jm'>{@link oaj.rest.RestContext.Builder#defaultClasses(Class...) defaultClasses}
diff --git a/juneau-doc/docs/Topics/08.juneau-rest-server/23.jrs.RestOpContext.html b/juneau-doc/docs/Topics/08.juneau-rest-server/23.jrs.RestOpContext.html
index 09dcad3aa..23de568f8 100644
--- a/juneau-doc/docs/Topics/08.juneau-rest-server/23.jrs.RestOpContext.html
+++ b/juneau-doc/docs/Topics/08.juneau-rest-server/23.jrs.RestOpContext.html
@@ -28,8 +28,8 @@
To access the builder for these objects, simply implement the following init method that will be called for each {@link oajr.annotation.RestOp}-annotated method.
</p>
<p class='bjava'>
- | <jc>// Use an INIT hook with RestOpContext.Builder as a parameter.</jc>
- | <ja>@RestHook</ja>(<jsf>INIT</jsf>)
+ | <jc>// Use an init hook with RestOpContext.Builder as a parameter.</jc>
+ | <ja>@RestInit</ja>
| <jk>public void</jk> init(RestOpContext.Builder <jv>builder</jv>) <jk>throws</jk> Exception {
| <jv>builder</jv>
| .beanContext(<jv>x</jv> -> <jv>x</jv>.swaps(TemporalCalendarSwap.Rfc1123DateTime.<jk>class</jk>))
diff --git a/juneau-doc/src/main/javadoc/overview.html b/juneau-doc/src/main/javadoc/overview.html
index 5c8477295..200c92365 100644
--- a/juneau-doc/src/main/javadoc/overview.html
+++ b/juneau-doc/src/main/javadoc/overview.html
@@ -16803,7 +16803,7 @@
<jc>// Our database.</jc>
<jk>private</jk> Map<Integer,Object> <jf>myDatabase</jf>;
- <ja>@RestHook</ja>(<jsf>INIT</jsf>)
+ <ja>@RestInit</ja>
<jk>public void</jk> initMyDatabase(RestContext.Builder <jv>builder</jv>) <jk>throws</jk> Exception {
<jf>myDatabase</jf> = <jk>new</jk> LinkedHashMap<>();
}
@@ -16817,40 +16817,31 @@
<jk>public class</jk> MyResource <jk>extends</jk> BasicRestObject <jk>implements</jk> BasicUniversalConfig {
<jc>// Add a request attribute to all incoming requests.</jc>
- <ja>@RestHook</ja>(<jsf>PRE_CALL</jsf>)
+ <ja>@RestPreCall</ja>
<jk>public void</jk> onPreCall(RestRequest <jv>req</jv>) {
<jv>req</jv>.setAttribute(<js>"foo"</js>, <js>"bar"</js>);
}
}
</p>
<p>
- The hook events can be broken down into two categories:
+ The following lifecycle annotations are provided.
</p>
<ul class='javatree'>
- <li class='je'>{@link org.apache.juneau.rest.annotation.HookEvent}
- <ul class='spaced-list'>
- <li>Resource lifecycle events:
- <ul class='javatree'>
- <li class='jf'>{@link org.apache.juneau.rest.annotation.HookEvent#INIT INIT} - Right before initialization.
- <li class='jf'>{@link org.apache.juneau.rest.annotation.HookEvent#POST_INIT POST_INIT} - Right after initialization.
- <li class='jf'>{@link org.apache.juneau.rest.annotation.HookEvent#POST_INIT_CHILD_FIRST POST_INIT_CHILD_FIRST} - Right after initialization but run child methods first.
- <li class='jf'>{@link org.apache.juneau.rest.annotation.HookEvent#DESTROY DESTROY} - Right before servlet destroy.
- </ul>
- </li>
- <li>REST call lifecycle events:
- <ul class='javatree'>
- <li class='jf'>{@link org.apache.juneau.rest.annotation.HookEvent#START_CALL START_CALL} - At the beginning of a REST call.
- <li class='jf'>{@link org.apache.juneau.rest.annotation.HookEvent#PRE_CALL PRE_CALL} - Right before the <ja>@RestOp</ja> method is invoked.
- <li class='jf'>{@link org.apache.juneau.rest.annotation.HookEvent#POST_CALL POST_CALL} - Right after the <ja>@RestOp</ja> method is invoked.
- <li class='jf'>{@link org.apache.juneau.rest.annotation.HookEvent#END_CALL END_CALL} - At the end of the REST call after the response has been flushed.
- </ul>
- </li>
+ <li>Resource lifecycle events:
+ <ul class='javatree'>
+ <li class='ja'>{@link org.apache.juneau.rest.annotation.RestInit} - Right before initialization.
+ <li class='ja'>{@link org.apache.juneau.rest.annotation.RestPostInit} - Right after initialization.
+ <li class='ja'>{@link org.apache.juneau.rest.annotation.RestDestroy} - Right before servlet destroy.
+ </ul>
+ </li>
+ <li>REST call lifecycle events:
+ <ul class='javatree'>
+ <li class='ja'>{@link org.apache.juneau.rest.annotation.RestStartCall} - At the beginning of a REST call.
+ <li class='ja'>{@link org.apache.juneau.rest.annotation.RestPreCall} - Right before the <ja>@RestOp</ja> method is invoked.
+ <li class='ja'>{@link org.apache.juneau.rest.annotation.RestPostCall} - Right after the <ja>@RestOp</ja> method is invoked.
+ <li class='ja'>{@link org.apache.juneau.rest.annotation.RestEndCall} - At the end of the REST call after the response has been flushed.
</ul>
</li>
- </ul>
-
- <ul class='seealso'>
- <li class='ja'>{@link org.apache.juneau.rest.annotation.RestHook}
</ul>
</div>
</div><!-- END: 8.2.5 - juneau-rest-server.jrs.AnnotatedClasses.jrs.LifecycleHooks -->
@@ -17166,7 +17157,7 @@
</p>
<p>
Additional parameter types can be defined by overriding {@link org.apache.juneau.rest.RestContext.Builder#createRestOpArgs(BeanStore,Supplier)} or
- by adding them to the bean store using {@link org.apache.juneau.rest.RestContext.Builder#createBeanStore(Class,Supplier)}.
+ by adding them to the bean store using {@link org.apache.juneau.rest.RestContext.Builder#createBeanStore(Supplier)}.
</p>
</div>
</div><!-- END: 8.3.2 - juneau-rest-server.jrs.RestOpAnnotatedMethods.jrs.JavaMethodParameters -->
@@ -18664,7 +18655,7 @@
<ja>@Rest</ja>
<jk>public class</jk> MyResource {
- <ja>@RestHook</ja>(<jsf>INIT</jsf>)
+ <ja>@RestInit</ja>
<jk>public void</jk> init(RestContext.Builder <jv>builder</jv>) {
<jv>builder</jv>.serializers().add(JsonSerializer.<jk>class</jk>, HtmlSerializer.<jk>class</jk>);
<jv>builder</jv>.parsers().add(JsonParser.<jk>class</jk>, HtmlParser.<jk>class</jk>);
@@ -19629,7 +19620,7 @@
<ul class='javatree'>
<li class='jc'>{@link org.apache.juneau.rest.RestContext.Builder}
<ul class='javatreec'>
- <li class='jmp'>{@link org.apache.juneau.rest.RestContext.Builder#createVarResolver(BeanStore,Class) createVarResolver(BeanStore,Class)}
+ <li class='jmp'>{@link org.apache.juneau.rest.RestContext.Builder#createVarResolver(BeanStore,Supplier,Class) createVarResolver(BeanStore,Supplier,Class)}
<li class='jm'>{@link org.apache.juneau.rest.RestContext.Builder#varResolver() varResolver()}
<li class='jm'>{@link org.apache.juneau.rest.RestContext.Builder#varResolver(Consumer) varResolver(Consumer)}
</ul>
@@ -19730,9 +19721,8 @@
<ul class='javatree'>
<li class='jc'>{@link org.apache.juneau.rest.RestContext.Builder}
<ul class='javatreec'>
- <li class='jmp'>{@link org.apache.juneau.rest.RestContext.Builder#createStaticFiles(BeanStore,Supplier) createStaticFiles(BeanStore,Supplier)}
+ <li class='jmp'>{@link org.apache.juneau.rest.RestContext.Builder#createStaticFiles() createStaticFiles(BeanStore,Supplier)}
<li class='jm'>{@link org.apache.juneau.rest.RestContext.Builder#staticFiles() staticFiles()}
- <li class='jm'>{@link org.apache.juneau.rest.RestContext.Builder#staticFiles(Consumer) staticFiles(Consumer)}
</ul>
</li>
</ul>
@@ -20491,7 +20481,7 @@
<div class='topic'>
<p>
{@link org.apache.juneau.rest.annotation.Rest}-annotated classes get automated timing and error statistic information for all <ja>@RestOp</ja>
- and <ja>@RestHook</ja> annotated methods on the class.
+ and lifecycle-event annotated methods on the class.
</p>
<p>
If you extend from {@link org.apache.juneau.rest.servlet.BasicRestServlet} or {@link org.apache.juneau.rest.servlet.BasicRestObject}, then
@@ -21365,7 +21355,6 @@
<ul class='javatreec'>
<li class='jmp'>{@link org.apache.juneau.rest.RestContext.Builder#createDebugEnablement(BeanStore,Supplier) createDebugEnablement(BeanStore,Supplier)}
<li class='jm'>{@link org.apache.juneau.rest.RestContext.Builder#debugEnablement() debugEnablement()}
- <li class='jm'>{@link org.apache.juneau.rest.RestContext.Builder#debugEnablement(Consumer) debugEnablement(Consumer)}
</ul>
</li>
</ul>
@@ -21441,7 +21430,7 @@
</li>
<li class='jc'>{@link org.apache.juneau.rest.RestContext.Builder}
<ul class='javatreec'>
- <li class='jmp'>{@link org.apache.juneau.rest.RestContext.Builder#createCallLogger() createCallLogger()}
+ <li class='jmp'>{@link org.apache.juneau.rest.RestContext.Builder#createCallLogger(BeanStore,Supplier) createCallLogger(BeanStore,Supplier)}
<li class='jm'>{@link org.apache.juneau.rest.RestContext.Builder#callLogger() callLogger()}
</ul>
</li>
@@ -21741,8 +21730,8 @@
.debugEnablement(<jsf>CONDITIONAL</jsf>);
}
- <jc>// Option #2 - Use an INIT hook.</jc>
- <ja>@RestHook</ja>(<jsf>INIT</jsf>)
+ <jc>// Option #2 - Use an init hook.</jc>
+ <ja>@RestInit</ja>
<jk>public void</jk> init(RestContext.Builder <jv>builder</jv>) <jk>throws</jk> Exception {
<jv>builder</jv>
.beanContext(<jv>x</jv> -> <jv>x</jv>.swaps(TemporalCalendarSwap.Rfc1123DateTime.<jk>class</jk>))
@@ -21768,9 +21757,7 @@
<li class='jm'>{@link org.apache.juneau.rest.RestContext.Builder#children(Object...) children}
<li class='jm'>{@link org.apache.juneau.rest.RestContext.Builder#config(Config) config}
<li class='jm'>{@link org.apache.juneau.rest.RestContext.Builder#consumes(MediaType...) consumes}
- <li class='jm'>{@link org.apache.juneau.rest.RestContext.Builder#debug(Enablement) debug}
<li class='jm'>{@link org.apache.juneau.rest.RestContext.Builder#debugDefault(Enablement) debugDefault}
- <li class='jm'>{@link org.apache.juneau.rest.RestContext.Builder#debugOn(String) debugOn}
<li class='jm'>{@link org.apache.juneau.rest.RestContext.Builder#defaultAccept(String) defaultAccept}
<li class='jm'>{@link org.apache.juneau.rest.RestContext.Builder#defaultCharset(Charset) defaultCharset}
<li class='jm'>{@link org.apache.juneau.rest.RestContext.Builder#defaultClasses(Class...) defaultClasses}
@@ -21876,8 +21863,8 @@
To access the builder for these objects, simply implement the following init method that will be called for each {@link org.apache.juneau.rest.annotation.RestOp}-annotated method.
</p>
<p class='bjava'>
- <jc>// Use an INIT hook with RestOpContext.Builder as a parameter.</jc>
- <ja>@RestHook</ja>(<jsf>INIT</jsf>)
+ <jc>// Use an init hook with RestOpContext.Builder as a parameter.</jc>
+ <ja>@RestInit</ja>
<jk>public void</jk> init(RestOpContext.Builder <jv>builder</jv>) <jk>throws</jk> Exception {
<jv>builder</jv>
.beanContext(<jv>x</jv> -> <jv>x</jv>.swaps(TemporalCalendarSwap.Rfc1123DateTime.<jk>class</jk>))
@@ -33963,7 +33950,7 @@
<ul class='spaced-list'>
<li>
Revamped and simplified servlet and REST-call lifecycle handling through new
- {@link org.apache.juneau.rest.annotation.RestHook @RestHook} annotation.
+ {@del @RestHook} annotation.
<ul>
<li>The {@del org.apache.juneau.rest.RestServlet#init(ServletConfig)} method is now final and can
no longer be extended.
diff --git a/juneau-microservice/juneau-microservice-core/src/main/java/org/apache/juneau/microservice/resources/LogsResource.java b/juneau-microservice/juneau-microservice-core/src/main/java/org/apache/juneau/microservice/resources/LogsResource.java
index 07bd4f8bc..720e32ecc 100644
--- a/juneau-microservice/juneau-microservice-core/src/main/java/org/apache/juneau/microservice/resources/LogsResource.java
+++ b/juneau-microservice/juneau-microservice-core/src/main/java/org/apache/juneau/microservice/resources/LogsResource.java
@@ -12,7 +12,6 @@
// ***************************************************************************************************************************
package org.apache.juneau.microservice.resources;
-import static org.apache.juneau.rest.annotation.HookEvent.*;
import static org.apache.juneau.internal.StringUtils.*;
import java.io.*;
@@ -56,7 +55,7 @@ public class LogsResource extends BasicRestServlet implements BasicUniversalConf
private LogEntryFormatter leFormatter;
boolean allowDeletes;
- @RestHook(INIT)
+ @RestInit
public void init(Config config) throws Exception {
logDir = new File(config.get("Logging/logDir").asString().orElse("logs"));
allowDeletes = config.get("Logging/allowDeletes").asBoolean().orElse(true);
diff --git a/juneau-microservice/juneau-microservice-ftest/src/test/java/org/apache/juneau/rest/test/client/ThirdPartyProxyResource.java b/juneau-microservice/juneau-microservice-ftest/src/test/java/org/apache/juneau/rest/test/client/ThirdPartyProxyResource.java
index 9c1b66ffb..7fc2a57c8 100644
--- a/juneau-microservice/juneau-microservice-ftest/src/test/java/org/apache/juneau/rest/test/client/ThirdPartyProxyResource.java
+++ b/juneau-microservice/juneau-microservice-ftest/src/test/java/org/apache/juneau/rest/test/client/ThirdPartyProxyResource.java
@@ -53,7 +53,7 @@ public class ThirdPartyProxyResource extends BasicRestServlet implements BasicUn
}
}
- @RestHook(HookEvent.START_CALL)
+ @RestStartCall
public static void startCall(HttpServletRequest req) {
try {
logFile.append("START["+new Date()+"]-").append(req.getQueryString()).append("\n");
@@ -63,7 +63,7 @@ public class ThirdPartyProxyResource extends BasicRestServlet implements BasicUn
}
}
- @RestHook(HookEvent.PRE_CALL)
+ @RestPreCall
public static void preCall(HttpServletRequest req) {
try {
logFile.append("PRE["+new Date()+"]-").append(req.getQueryString()).append("\n");
@@ -73,7 +73,7 @@ public class ThirdPartyProxyResource extends BasicRestServlet implements BasicUn
}
}
- @RestHook(HookEvent.POST_CALL)
+ @RestPostCall
public static void postCall(HttpServletRequest req) {
try {
logFile.append("POST["+new Date()+"]-").append(req.getQueryString()).append("\n");
@@ -83,7 +83,7 @@ public class ThirdPartyProxyResource extends BasicRestServlet implements BasicUn
}
}
- @RestHook(HookEvent.END_CALL)
+ @RestEndCall
public static void endCall(HttpServletRequest req) {
try {
Throwable e = (Throwable)req.getAttribute("Exception");
diff --git a/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/RestChildren.java b/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/RestChildren.java
index 5a31b7d06..2650ed6db 100644
--- a/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/RestChildren.java
+++ b/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/RestChildren.java
@@ -171,7 +171,7 @@ public class RestChildren {
//-----------------------------------------------------------------------------------------------------------------
/**
- * Called during servlet initialization on all children to invoke all {@link HookEvent#POST_INIT} methods.
+ * Called during servlet initialization on all children to invoke all {@link RestPostInit} child-last methods.
*
* @throws ServletException Error occurred.
*/
@@ -181,7 +181,7 @@ public class RestChildren {
}
/**
- * Called during servlet initialization on all children to invoke all {@link HookEvent#POST_INIT_CHILD_FIRST} methods.
+ * Called during servlet initialization on all children to invoke all {@link RestPostInit} child-first methods.
*
* @throws ServletException Error occurred.
*/
@@ -191,7 +191,7 @@ public class RestChildren {
}
/**
- * Called during servlet destruction on all children to invoke all {@link HookEvent#DESTROY} and {@link Servlet#destroy()} methods.
+ * Called during servlet destruction on all children to invoke all {@link RestDestroy} and {@link Servlet#destroy()} methods.
*/
public void destroy() {
for (RestContext r : children.values()) {
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 f9a428e37..791e08a33 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
@@ -101,8 +101,8 @@ import org.apache.juneau.utils.*;
* .swaps(TemporalCalendarSwap.IsoLocalDateTime.<jk>class</jk>);
* }
*
- * <jc>// Option #2 - Use an INIT hook.</jc>
- * <ja>@RestHook</ja>(<jsf>INIT</jsf>)
+ * <jc>// Option #2 - Use an init hook.</jc>
+ * <ja>@RestInit</ja>
* <jk>public void</jk> init(RestContext.Builder <jv>builder</jv>) <jk>throws</jk> Exception {
* <jv>builder</jv>
* .swaps(TemporalCalendarSwap.IsoLocalDateTime.<jk>class</jk>);
@@ -389,7 +389,7 @@ public class RestContext extends Context {
Supplier<?> r = this.resource;
Class<?> rc = resourceClass;
- beanStore = createBeanStore()
+ beanStore = createBeanStore(resource)
.build()
.addBean(Builder.class, this)
.addBean(ResourceSupplier.class, this.resource)
@@ -403,9 +403,9 @@ public class RestContext extends Context {
BeanStore bs = beanStore;
beanStore.add(BeanStore.class, bs);
- varResolver = createVarResolver(bs, rc);
+ varResolver = createVarResolver(bs, r, rc);
beanStore.add(VarResolver.class, varResolver.build());
- config = beanStore.add(Config.class, createConfig(bs, rc));
+ config = beanStore.add(Config.class, createConfig(bs, r, rc));
beanStore.add(VarResolver.class, varResolver.bean(Config.class, config).build());
ClassInfo rci = ClassInfo.of(resourceClass);
@@ -465,7 +465,7 @@ public class RestContext extends Context {
Map<String,MethodInfo> map = map();
ClassInfo.ofProxy(r).forEachAllMethodParentFirst(
- y -> y.hasAnnotation(RestHook.class) && y.getAnnotation(RestHook.class).value() == HookEvent.INIT && ! y.hasArg(RestOpContext.Builder.class),
+ y -> y.hasAnnotation(RestInit.class) && ! y.hasArg(RestOpContext.Builder.class),
y -> {
String sig = y.getSignature();
if (! map.containsKey(sig))
@@ -475,11 +475,11 @@ public class RestContext extends Context {
for (MethodInfo m : map.values()) {
if (! beanStore.hasAllParams(m))
- throw servletException("Could not call @RestHook(INIT) method {0}.{1}. Could not find prerequisites: {2}.", m.getDeclaringClass().getSimpleName(), m.getSignature(), beanStore.getMissingParams(m));
+ throw servletException("Could not call @RestInit method {0}.{1}. Could not find prerequisites: {2}.", m.getDeclaringClass().getSimpleName(), m.getSignature(), beanStore.getMissingParams(m));
try {
m.invoke(r, beanStore.getParams(m));
} catch (Exception e) {
- throw servletException(e, "Exception thrown from @RestHook(INIT) method {0}.{1}.", m.getDeclaringClass().getSimpleName(), m.getSignature());
+ throw servletException(e, "Exception thrown from @RestInit method {0}.{1}.", m.getDeclaringClass().getSimpleName(), m.getSignature());
}
}
}
@@ -602,7 +602,7 @@ public class RestContext extends Context {
* Can be used to add more beans to the bean store.
*
* <p>
- * The bean store is created by the constructor using the {@link #createBeanStore()} method and is initialized with the following beans:
+ * The bean store is created by the constructor using the {@link #createBeanStore(Supplier)} method and is initialized with the following beans:
* <ul>
* <li>{@link RestContext.Builder}
* <li>{@link ServletConfig}
@@ -667,9 +667,11 @@ public class RestContext extends Context {
* <br>Args can be any injectable bean including {@link org.apache.juneau.cp.BeanStore.Builder}, the default builder.
* </ul>
*
+ * @param resource
+ * The REST servlet/bean instance that this context is defined against.
* @return A new bean store builder.
*/
- protected BeanStore.Builder createBeanStore() {
+ protected BeanStore.Builder createBeanStore(Supplier<?> resource) {
// Default value.
Value<BeanStore.Builder> v = Value.of(
@@ -710,7 +712,7 @@ public class RestContext extends Context {
* used to resolve string variables of the form <js>"$X{...}"</js> in various places such as annotations on the REST class and methods.
*
* <p>
- * The var resolver is created by the constructor using the {@link #createVarResolver(BeanStore,Class)} method and is initialized with the following beans:
+ * The var resolver is created by the constructor using the {@link #createVarResolver(BeanStore,Supplier,Class)} method and is initialized with the following beans:
* <ul>
* <li>{@link ConfigVar}
* <li>{@link FileVar}
@@ -779,22 +781,25 @@ public class RestContext extends Context {
* <li>
* Looks for bean of type {@link org.apache.juneau.svl.VarResolver.Builder} in bean store and returns a copy of it.
* <li>
- * Creates a default builder with default variables pulled from {@link #createVars(BeanStore,Class)}.
+ * Creates a default builder with default variables pulled from {@link #createVars(BeanStore,Supplier,Class)}.
* </ol>
*
- * @param beanStore The bean store containing injected beans.
+ * @param beanStore
+ * The factory used for creating beans and retrieving injected beans.
+ * @param resource
+ * The REST servlet/bean instance that this context is defined against.
* @param resourceClass
* The REST servlet/bean type that this context is defined against.
* @return A new variable resolver sub-builder.
*/
- protected VarResolver.Builder createVarResolver(BeanStore beanStore, Class<?> resourceClass) {
+ protected VarResolver.Builder createVarResolver(BeanStore beanStore, Supplier<?> resource, Class<?> resourceClass) {
// Default value.
Value<VarResolver.Builder> v = Value.of(
VarResolver
.create()
.defaultVars()
- .vars(createVars(beanStore, resourceClass))
+ .vars(createVars(beanStore, resource, resourceClass))
.vars(FileVar.class)
.bean(FileFinder.class, FileFinder.create(beanStore).cp(resourceClass,null,true).build())
);
@@ -835,12 +840,15 @@ public class RestContext extends Context {
* Creates a default builder with default variables.
* </ol>
*
- * @param beanStore The bean store containing injected beans.
+ * @param beanStore
+ * The factory used for creating beans and retrieving injected beans.
+ * @param resource
+ * The REST servlet/bean instance that this context is defined against.
* @param resourceClass
* The REST servlet/bean type that this context is defined against.
* @return A new var resolver variable list.
*/
- protected VarList createVars(BeanStore beanStore, Class<?> resourceClass) {
+ protected VarList createVars(BeanStore beanStore, Supplier<?> resource, Class<?> resourceClass) {
// Default value.
Value<VarList> v = Value.of(
@@ -949,12 +957,15 @@ public class RestContext extends Context {
/**
* Creates the config for this builder.
*
- * @param beanStore The bean store to use for creating the config.
+ * @param beanStore
+ * The factory used for creating beans and retrieving injected beans.
+ * @param resource
+ * The REST servlet/bean instance that this context is defined against.
* @param resourceClass
* The REST servlet/bean type that this context is defined against.
* @return A new config.
*/
- protected Config createConfig(BeanStore beanStore, Class<?> resourceClass) {
+ protected Config createConfig(BeanStore beanStore, Supplier<?> resource, Class<?> resourceClass) {
Value<Config> v = Value.empty();
@@ -1003,7 +1014,7 @@ public class RestContext extends Context {
*/
public Logger logger() {
if (logger == null)
- logger = createLogger(beanStore(), resourceClass);
+ logger = createLogger(beanStore(), resource, resourceClass);
return logger;
}
@@ -1033,7 +1044,7 @@ public class RestContext extends Context {
* Sets the logger for this resource.
*
* <p>
- * If not specified, the logger used is created by {@link #createLogger(BeanStore, Class)}.
+ * If not specified, the logger used is created by {@link #createLogger(BeanStore, Supplier, Class)}.
*
* @param value The logger to use for the REST resource.
* @return This object.
@@ -1060,14 +1071,15 @@ public class RestContext extends Context {
* <li>Instantiates via <c>Logger.<jsm>getLogger</jsm>(<jv>resource</jv>.getClass().getName())</c>.
* </ul>
*
- * @param resourceClass
- * The REST servlet/bean class that this context is defined against.
* @param beanStore
* The factory used for creating beans and retrieving injected beans.
- * <br>Created by {@link RestContext.Builder#beanStore()}.
+ * @param resource
+ * The REST servlet/bean instance that this context is defined against.
+ * @param resourceClass
+ * The REST servlet/bean class that this context is defined against.
* @return A new logger.
*/
- protected Logger createLogger(BeanStore beanStore, Class<?> resourceClass) {
+ protected Logger createLogger(BeanStore beanStore, Supplier<?> resource, Class<?> resourceClass) {
// Default value.
Value<Logger> v = Value.of(
@@ -1746,7 +1758,7 @@ public class RestContext extends Context {
* }
*
* <jc>// Option #3 - Defined via builder passed in through init method.</jc>
- * <ja>@RestHook</ja>(<jsf>INIT</jsf>)
+ * <ja>@RestInit</ja>
* <jk>public void</jk> init(RestContext.Builder <jv>builder</jv>) <jk>throws</jk> Exception {
* <jv>builder</jv>.responseProcessors(MyResponseProcessors.<jk>class</jk>);
* }
@@ -1910,7 +1922,7 @@ public class RestContext extends Context {
* }
*
* <jc>// Option #3 - Registered via builder passed in through init method.</jc>
- * <ja>@RestHook</ja>(<jsf>INIT</jsf>)
+ * <ja>@RestInit</ja>
* <jk>public void</jk> init(RestContext.Builder <jv>builder</jv>) <jk>throws</jk> Exception {
* <jv>builder</jv>.callLogger(MyLogger.<jk>class</jk>);
* }
@@ -1942,7 +1954,7 @@ public class RestContext extends Context {
*/
public BeanCreator<CallLogger> callLogger() {
if (callLogger == null)
- callLogger = createCallLogger();
+ callLogger = createCallLogger(beanStore, resource);
return callLogger;
}
@@ -1982,6 +1994,7 @@ public class RestContext extends Context {
* </ul>
* <li>Looks for a static or non-static <c>createCallLogger()</c> method that returns {@link CallLogger} on the
* resource class with any of the following arguments:
+ * <ul class='javatreec'>
* <li>{@link RestContext}
* <li>{@link RestContext.Builder}
* <li>{@link BeanContext}
@@ -2000,9 +2013,13 @@ public class RestContext extends Context {
* <li class='jm'>{@link RestContext.Builder#callLogger()}
* </ul>
*
+ * @param beanStore
+ * The factory used for creating beans and retrieving injected beans.
+ * @param resource
+ * The REST servlet/bean instance that this context is defined against.
* @return A new call logger sub-builder.
*/
- protected BeanCreator<CallLogger> createCallLogger() {
+ protected BeanCreator<CallLogger> createCallLogger(BeanStore beanStore, Supplier<?> resource) {
BeanCreator<CallLogger> creator = beanStore.createBean(CallLogger.class).type(BasicCallLogger.class);
@@ -2448,7 +2465,7 @@ public class RestContext extends Context {
*/
public BeanCreator<FileFinder> fileFinder() {
if (fileFinder == null)
- fileFinder = createFileFinder();
+ fileFinder = createFileFinder(beanStore, resource);
return fileFinder;
}
@@ -2494,7 +2511,7 @@ public class RestContext extends Context {
* </ul>
*
* <p>
- * The file finder is instantiated via the {@link RestContext.Builder#createFileFinder()} method which in turn instantiates
+ * The file finder is instantiated via the {@link RestContext.Builder#createFileFinder(BeanStore,Supplier)} method which in turn instantiates
* based on the following logic:
* <ul>
* <li>Returns the resource class itself if it's an instance of {@link FileFinder}.
@@ -2546,7 +2563,7 @@ public class RestContext extends Context {
* }
*
* <jc>// Option #4 - Registered via builder passed in through init method.</jc>
- * <ja>@RestHook</ja>(<jsf>INIT</jsf>)
+ * <ja>@RestInit</ja>
* <jk>public void</jk> init(RestContext.Builder <jv>builder</jv>) <jk>throws</jk> Exception {
* <jv>builder</jv>.fileFinder(MyFileFinder.<jk>class</jk>);
* }
@@ -2594,9 +2611,14 @@ public class RestContext extends Context {
* <li>{@link BeanStore} - The bean store of this REST context.
* <li>Any {@doc juneau-rest-server-springboot injected bean} types. Use {@link Optional} arguments for beans that may not exist.
* </ul>
+ *
+ * @param beanStore
+ * The factory used for creating beans and retrieving injected beans.
+ * @param resource
+ * The REST servlet/bean instance that this context is defined against.
* @return A new file finder bean creator.
*/
- protected BeanCreator<FileFinder> createFileFinder() {
+ protected BeanCreator<FileFinder> createFileFinder(BeanStore beanStore, Supplier<?> resource) {
BeanCreator<FileFinder> creator = beanStore.createBean(FileFinder.class).type(BasicRestFileFinder.class);
@@ -2629,7 +2651,7 @@ public class RestContext extends Context {
*/
public BeanCreator<StaticFiles> staticFiles() {
if (staticFiles == null)
- staticFiles = createStaticFiles();
+ staticFiles = createStaticFiles(beanStore, resource);
return staticFiles;
}
@@ -2674,7 +2696,7 @@ public class RestContext extends Context {
* </ul>
*
* <p>
- * The static file finder is instantiated via the {@link RestContext.Builder#createStaticFiles()} method which in turn instantiates
+ * The static file finder is instantiated via the {@link RestContext.Builder#createStaticFiles(BeanStore,Supplier)} method which in turn instantiates
* based on the following logic:
*
* <ol class='spaced-list'>
@@ -2747,9 +2769,13 @@ public class RestContext extends Context {
* <jk>public class</jk> MyResource {...}
* </p>
*
+ * @param beanStore
+ * The factory used for creating beans and retrieving injected beans.
+ * @param resource
+ * The REST servlet/bean instance that this context is defined against.
* @return A new static files sub-builder.
*/
- protected BeanCreator<StaticFiles> createStaticFiles() {
+ protected BeanCreator<StaticFiles> createStaticFiles(BeanStore beanStore, Supplier<?> resource) {
BeanCreator<StaticFiles> creator = beanStore.createBean(StaticFiles.class).type(BasicStaticFiles.class);
@@ -2840,7 +2866,7 @@ public class RestContext extends Context {
* }
*
* <jc>// Option #3 - Defined via builder passed in through init method.</jc>
- * <ja>@RestHook</ja>(<jsf>INIT</jsf>)
+ * <ja>@RestInit</ja>
* <jk>public void</jk> init(RestContext.Builder <jv>builder</jv>) <jk>throws</jk> Exception {
* <jv>builder</jv>.defaultRequestHeaders(Accept.<jsm>of</jsm>(<js>"application/json"</js>));
* }
@@ -3006,7 +3032,7 @@ public class RestContext extends Context {
* }
*
* <jc>// Option #3 - Defined via builder passed in through init method.</jc>
- * <ja>@RestHook</ja>(<jsf>INIT</jsf>)
+ * <ja>@RestInit</ja>
* <jk>public void</jk> init(RestContext.Builder <jv>builder</jv>) <jk>throws</jk> Exception {
* <jv>builder</jv>.defaultResponseHeaders(ContentType.<jsm>of</jsm>(<js>"text/plain"</js>));
* }
@@ -3136,7 +3162,7 @@ public class RestContext extends Context {
* }
*
* <jc>// Option #3 - Defined via builder passed in through init method.</jc>
- * <ja>@RestHook</ja>(<jsf>INIT</jsf>)
+ * <ja>@RestInit</ja>
* <jk>public void</jk> init(RestContext.Builder <jv>builder</jv>) <jk>throws</jk> Exception {
* <jv>builder</jv>.defaultRequestAttribute(<js>"Foo"</js>, <js>"bar"</js>);
* }
@@ -3279,7 +3305,7 @@ public class RestContext extends Context {
* }
*
* <jc>// Option #3 - Registered via builder passed in through init method.</jc>
- * <ja>@RestHook</ja>(<jsf>INIT</jsf>)
+ * <ja>@RestInit</ja>
* <jk>public void</jk> init(RestContext.Builder <jv>builder</jv>) <jk>throws</jk> Exception {
* <jv>builder</jv>.restOpArgs(MyRestParam.<jk>class</jk>);
* }
@@ -3409,7 +3435,7 @@ public class RestContext extends Context {
*/
public BeanCreator<DebugEnablement> debugEnablement() {
if (debugEnablement == null)
- debugEnablement = createDebugEnablement();
+ debugEnablement = createDebugEnablement(beanStore, resource);
return debugEnablement;
}
@@ -3453,9 +3479,13 @@ public class RestContext extends Context {
/**
* Instantiates the debug enablement bean creator.
*
+ * @param beanStore
+ * The factory used for creating beans and retrieving injected beans.
+ * @param resource
+ * The REST servlet/bean instance that this context is defined against.
* @return A new debug enablement bean creator.
*/
- protected BeanCreator<DebugEnablement> createDebugEnablement() {
+ protected BeanCreator<DebugEnablement> createDebugEnablement(BeanStore beanStore, Supplier<?> resource) {
BeanCreator<DebugEnablement> creator = beanStore.createBean(DebugEnablement.class).type(BasicDebugEnablement.class);
@@ -3527,7 +3557,7 @@ public class RestContext extends Context {
// Default value.
Value<MethodList> v = Value.of(
- getHookMethods(resource, HookEvent.START_CALL)
+ getAnnotatedMethods(resource, RestStartCall.class, x -> true)
);
// Replace with bean from: @RestBean(name="startCallMethods") public [static] MethodList xxx(<args>)
@@ -3590,7 +3620,7 @@ public class RestContext extends Context {
// Default value.
Value<MethodList> v = Value.of(
- getHookMethods(resource, HookEvent.END_CALL)
+ getAnnotatedMethods(resource, RestEndCall.class, x -> true)
);
// Replace with bean from: @RestBean(name="endCallMethods") public [static] MethodList xxx(<args>)
@@ -3653,7 +3683,7 @@ public class RestContext extends Context {
// Default value.
Value<MethodList> v = Value.of(
- getHookMethods(resource, HookEvent.POST_INIT)
+ getAnnotatedMethods(resource, RestPostInit.class, x -> ! x.childFirst())
);
// Replace with bean from: @RestBean(name="postInitMethods") public [static] MethodList xxx(<args>)
@@ -3716,7 +3746,7 @@ public class RestContext extends Context {
// Default value.
Value<MethodList> v = Value.of(
- getHookMethods(resource, HookEvent.POST_INIT_CHILD_FIRST)
+ getAnnotatedMethods(resource, RestPostInit.class, x -> x.childFirst())
);
// Replace with bean from: @RestBean(name="postInitChildFirstMethods") public [static] MethodList xxx(<args>)
@@ -3779,7 +3809,7 @@ public class RestContext extends Context {
// Default value.
Value<MethodList> v = Value.of(
- getHookMethods(resource, HookEvent.DESTROY)
+ getAnnotatedMethods(resource, RestDestroy.class, x -> true)
);
// Replace with bean from: @RestBean(name="destroyMethods") public [static] MethodList xxx(<args>)
@@ -3845,7 +3875,7 @@ public class RestContext extends Context {
// Default value.
Value<MethodList> v = Value.of(
- getHookMethods(resource, HookEvent.PRE_CALL)
+ getAnnotatedMethods(resource, RestPreCall.class, x -> true)
);
// Replace with bean from: @RestBean(name="preCallMethods") public [static] MethodList xxx(<args>)
@@ -3911,7 +3941,7 @@ public class RestContext extends Context {
// Default value.
Value<MethodList> v = Value.of(
- getHookMethods(resource, HookEvent.POST_CALL)
+ getAnnotatedMethods(resource, RestPostCall.class, x -> true)
);
// Replace with bean from: @RestBean(name="postCallMethods") public [static] MethodList xxx(<args>)
@@ -3966,7 +3996,7 @@ public class RestContext extends Context {
Map<String,MethodInfo> initMap = map();
ClassInfo.ofProxy(resource.get()).forEachAllMethodParentFirst(
- y -> y.hasAnnotation(RestHook.class) && y.getAnnotation(RestHook.class).value() == HookEvent.INIT && y.hasArg(RestOpContext.Builder.class),
+ y -> y.hasAnnotation(RestInit.class) && y.hasArg(RestOpContext.Builder.class),
y -> {
String sig = y.getSignature();
if (! initMap.containsKey(sig))
@@ -3996,12 +4026,12 @@ public class RestContext extends Context {
beanStore = BeanStore.of(beanStore, resource.get()).addBean(RestOpContext.Builder.class, rocb);
for (MethodInfo m : initMap.values()) {
if (! beanStore.hasAllParams(m)) {
- throw servletException("Could not call @RestHook(INIT) method {0}.{1}. Could not find prerequisites: {2}.", m.getDeclaringClass().getSimpleName(), m.getSignature(), beanStore.getMissingParams(m));
+ throw servletException("Could not call @RestInit method {0}.{1}. Could not find prerequisites: {2}.", m.getDeclaringClass().getSimpleName(), m.getSignature(), beanStore.getMissingParams(m));
}
try {
m.invoke(resource.get(), beanStore.getParams(m));
} catch (Exception e) {
- throw servletException(e, "Exception thrown from @RestHook(INIT) method {0}.{1}.", m.getDeclaringClass().getSimpleName(), m.getSignature());
+ throw servletException(e, "Exception thrown from @RestInit method {0}.{1}.", m.getDeclaringClass().getSimpleName(), m.getSignature());
}
}
@@ -4161,7 +4191,7 @@ public class RestContext extends Context {
*/
public BeanCreator<SwaggerProvider> swaggerProvider() {
if (swaggerProvider == null)
- swaggerProvider = createSwaggerProvider();
+ swaggerProvider = createSwaggerProvider(beanStore, resource);
return swaggerProvider;
}
@@ -4215,9 +4245,13 @@ public class RestContext extends Context {
* <li class='jm'>{@link RestContext.Builder#swaggerProvider(SwaggerProvider)}
* </ul>
*
+ * @param beanStore
+ * The factory used for creating beans and retrieving injected beans.
+ * @param resource
+ * The REST servlet/bean instance that this context is defined against.
* @return A new swagger provider sub-builder.
*/
- protected BeanCreator<SwaggerProvider> createSwaggerProvider() {
+ protected BeanCreator<SwaggerProvider> createSwaggerProvider(BeanStore beanStore, Supplier<?> resource) {
BeanCreator<SwaggerProvider> creator = beanStore.createBean(SwaggerProvider.class).type(BasicSwaggerProvider.class);
@@ -4314,7 +4348,7 @@ public class RestContext extends Context {
* }
*
* <jc>// Option #3 - Defined via builder passed in through init method.</jc>
- * <ja>@RestHook</ja>(<jsf>INIT</jsf>)
+ * <ja>@RestInit</ja>
* <jk>public void</jk> init(RestContext.Builder <jv>builder</jv>) <jk>throws</jk> Exception {
* <jv>builder</jv>.allowedMethodHeaders(<js>"PATCH"</js>);
* }
@@ -4385,7 +4419,7 @@ public class RestContext extends Context {
* }
*
* <jc>// Option #3 - Defined via builder passed in through init method.</jc>
- * <ja>@RestHook</ja>(<jsf>INIT</jsf>)
+ * <ja>@RestInit</ja>
* <jk>public void</jk> init(RestContext.Builder builder) <jk>throws</jk> Exception {
* <jv>builder</jv>.allowedMethodParams(<js>"HEAD,OPTIONS,PUT"</js>);
* }
@@ -4447,7 +4481,7 @@ public class RestContext extends Context {
* }
*
* <jc>// Option #3 - Defined via builder passed in through init method.</jc>
- * <ja>@RestHook</ja>(<jsf>INIT</jsf>)
+ * <ja>@RestInit</ja>
* <jk>public void</jk> init(RestContext.Builder <jv>builder</jv>) <jk>throws</jk> Exception {
* <jv>builder</jv>.clientVersionHeader(<js>"Client-Version"</js>);
* }
@@ -4515,7 +4549,7 @@ public class RestContext extends Context {
* }
*
* <jc>// Option #3 - Defined via builder passed in through init method.</jc>
- * <ja>@RestHook</ja>(<jsf>INIT</jsf>)
+ * <ja>@RestInit</ja>
* <jk>public void</jk> init(RestContext.Builder <jv>builder</jv>) <jk>throws</jk> Exception {
* <jv>builder</jv>.defaultCharset(<js>"US-ASCII"</js>);
* }
@@ -4573,7 +4607,7 @@ public class RestContext extends Context {
* }
*
* <jc>// Option #3 - Defined via builder passed in through init method.</jc>
- * <ja>@RestHook</ja>(<jsf>INIT</jsf>)
+ * <ja>@RestInit</ja>
* <jk>public void</jk> init(RestContext.Builder <jv>builder</jv>) <jk>throws</jk> Exception {
* <jv>builder</jv>.disableContentParam();
* }
@@ -4630,7 +4664,7 @@ public class RestContext extends Context {
* }
*
* <jc>// Option #3 - Defined via builder passed in through init method.</jc>
- * <ja>@RestHook</ja>(<jsf>INIT</jsf>)
+ * <ja>@RestInit</ja>
* <jk>public void</jk> init(RestContext.Builder <jv>builder</jv>) <jk>throws</jk> Exception {
* <jv>builder</jv>.maxInput(<js>"10M"</js>);
* }
@@ -4749,7 +4783,7 @@ public class RestContext extends Context {
* }
*
* <jc>// Option #3 - Defined via builder passed in through init method.</jc>
- * <ja>@RestHook</ja>(<jsf>INIT</jsf>)
+ * <ja>@RestInit</ja>
* <jk>public void</jk> init(RestContext.Builder <jv>builder</jv>) <jk>throws</jk> Exception {
* <jv>builder</jv>.uriAuthority(<js>"http://localhost:10000"</js>);
* }
@@ -4810,7 +4844,7 @@ public class RestContext extends Context {
* }
*
* <jc>// Option #3 - Defined via builder passed in through init method.</jc>
- * <ja>@RestHook</ja>(<jsf>INIT</jsf>)
+ * <ja>@RestInit</ja>
* <jk>public void</jk> init(RestContext.Builder <jv>builder</jv>) <jk>throws</jk> Exception {
* <jv>builder</jv>.uriContext(<js>"/foo"</js>);
* }
@@ -4869,7 +4903,7 @@ public class RestContext extends Context {
* }
*
* <jc>// Option #3 - Defined via builder passed in through init method.</jc>
- * <ja>@RestHook</ja>(<jsf>INIT</jsf>)
+ * <ja>@RestInit</ja>
* <jk>public void</jk> init(RestContext.Builder <jv>builder</jv>) <jk>throws</jk> Exception {
* <jv>builder</jv>.uriRelativity(<jsf>PATH_INFO</jsf>);
* }
@@ -4928,7 +4962,7 @@ public class RestContext extends Context {
* }
*
* <jc>// Option #3 - Defined via builder passed in through init method.</jc>
- * <ja>@RestHook</ja>(<jsf>INIT</jsf>)
+ * <ja>@RestInit</ja>
* <jk>public void</jk> init(RestContext.Builder <jv>builder</jv>) <jk>throws</jk> Exception {
* <jv>builder</jv>.uriResolution(<jsf>ABSOLUTE</jsf>);
* }
@@ -5101,7 +5135,7 @@ public class RestContext extends Context {
* }
*
* <jc>// Option #3 - Registered via builder passed in through init method.</jc>
- * <ja>@RestHook</ja>(<jsf>INIT</jsf>)
+ * <ja>@RestInit</ja>
* <jk>public void</jk> init(RestContext.Builder <jv>builder</jv>) <jk>throws</jk> Exception {
* <jv>builder</jv>.children(MyChildResource.<jk>class</jk>);
* }
@@ -5201,7 +5235,7 @@ public class RestContext extends Context {
* }
*
* <jc>// Option #3 - Defined via builder passed in through init method.</jc>
- * <ja>@RestHook</ja>(<jsf>INIT</jsf>)
+ * <ja>@RestInit</ja>
* <jk>public void</jk> init(RestContext.Builder <jv>builder</jv>) <jk>throws</jk> Exception {
* <jv>builder</jv>.path(<js>"/myResource"</js>);
* }
@@ -5283,7 +5317,7 @@ public class RestContext extends Context {
* ...
*
* <jc>// Option #2 - Defined via builder passed in through init method.</jc>
- * <ja>@RestHook</ja>(<jsf>INIT</jsf>)
+ * <ja>@RestInit</ja>
* <jk>public void</jk> init(RestContext.Builder <jv>builder</jv>) <jk>throws</jk> Exception {
* <jv>builder</jv>.restChildrenClass(MyRestChildren.<jk>class</jk>);
* }
@@ -5343,7 +5377,7 @@ public class RestContext extends Context {
* ...
*
* <jc>// Option #2 - Defined via builder passed in through init method.</jc>
- * <ja>@RestHook</ja>(<jsf>INIT</jsf>)
+ * <ja>@RestInit</ja>
* <jk>public void</jk> init(RestContext.Builder <jv>builder</jv>) <jk>throws</jk> Exception {
* <jv>builder</jv>.methodContextClass(MyRestOperationContext.<jk>class</jk>);
* }
@@ -5405,7 +5439,7 @@ public class RestContext extends Context {
* ...
*
* <jc>// Option #2 - Defined via builder passed in through init method.</jc>
- * <ja>@RestHook</ja>(<jsf>INIT</jsf>)
+ * <ja>@RestInit</ja>
* <jk>public void</jk> init(RestContext.Builder <jv>builder</jv>) <jk>throws</jk> Exception {
* <jv>builder</jv>.restMethodsClass(MyRestOperations.<jk>class</jk>);
* }
@@ -5463,7 +5497,7 @@ public class RestContext extends Context {
* }
*
* <jc>// Option #3 - Defined via builder passed in through init method.</jc>
- * <ja>@RestHook</ja>(<jsf>INIT</jsf>)
+ * <ja>@RestInit</ja>
* <jk>public void</jk> init(RestContext.Builder <jv>builder</jv>) <jk>throws</jk> Exception {
* <jv>builder</jv>.produces(<jk>false</jk>, <js>"application/json"</js>);
* }
@@ -5525,7 +5559,7 @@ public class RestContext extends Context {
* }
*
* <jc>// Option #3 - Defined via builder passed in through init method.</jc>
- * <ja>@RestHook</ja>(<jsf>INIT</jsf>)
+ * <ja>@RestInit</ja>
* <jk>public void</jk> init(RestContext.Builder <jv>builder</jv>) <jk>throws</jk> Exception {
* <jv>builder</jv>.consumes(<jk>false</jk>, <js>"application/json"</js>);
* }
@@ -5625,13 +5659,13 @@ public class RestContext extends Context {
// Helper methods
//----------------------------------------------------------------------------------------------------
- private static MethodList getHookMethods(Supplier<?> resource, HookEvent event) {
+ private static <T extends Annotation> MethodList getAnnotatedMethods(Supplier<?> resource, Class<T> annotation, Predicate<T> predicate) {
Map<String,Method> x = map();
Object r = resource.get();
ClassInfo.ofProxy(r).forEachAllMethodParentFirst(
- y -> y.hasAnnotation(RestHook.class),
- y -> y.forEachAnnotation(RestHook.class, z -> z.value() == event, z -> x.put(y.getSignature(), y.accessible().inner()))
+ y -> y.hasAnnotation(annotation),
+ y -> y.forEachAnnotation(annotation, predicate, z -> x.put(y.getSignature(), y.accessible().inner()))
);
MethodList x2 = MethodList.of(x.values());
@@ -6666,7 +6700,7 @@ public class RestContext extends Context {
} finally {
try {
s.finish();
- finishCall(s);
+ endCall(s);
} finally {
localSession.remove();
}
@@ -6886,7 +6920,7 @@ public class RestContext extends Context {
}
/**
- * Called at the start of a request to invoke all {@link HookEvent#START_CALL} methods.
+ * Called at the start of a request to invoke all {@link RestStartCall} methods.
*
* @param session The current request.
* @throws BasicHttpException If thrown from call methods.
@@ -6904,7 +6938,7 @@ public class RestContext extends Context {
}
/**
- * Called during a request to invoke all {@link HookEvent#PRE_CALL} methods.
+ * Called during a request to invoke all {@link RestPreCall} methods.
*
* @param session The current request.
* @throws Throwable If thrown from call methods.
@@ -6915,7 +6949,7 @@ public class RestContext extends Context {
}
/**
- * Called during a request to invoke all {@link HookEvent#POST_CALL} methods.
+ * Called during a request to invoke all {@link RestPostCall} methods.
*
* @param session The current request.
* @throws Throwable If thrown from call methods.
@@ -6926,14 +6960,14 @@ public class RestContext extends Context {
}
/**
- * Called at the end of a request to invoke all {@link HookEvent#END_CALL} methods.
+ * Called at the end of a request to invoke all {@link RestEndCall} methods.
*
* <p>
* This is the very last method called in {@link #execute(Object, HttpServletRequest, HttpServletResponse)}.
*
* @param session The current request.
*/
- protected void finishCall(RestSession session) {
+ protected void endCall(RestSession session) {
for (MethodInvoker x : endCallMethods) {
try {
x.invoke(session.getBeanStore(), session.getResource());
@@ -6944,7 +6978,7 @@ public class RestContext extends Context {
}
/**
- * Called during servlet initialization to invoke all {@link HookEvent#POST_INIT} methods.
+ * Called during servlet initialization to invoke all {@link RestPostInit} child-last methods.
*
* @return This object.
* @throws ServletException Error occurred.
@@ -6976,7 +7010,7 @@ public class RestContext extends Context {
}
/**
- * Called during servlet initialization to invoke all {@link HookEvent#POST_INIT_CHILD_FIRST} methods.
+ * Called during servlet initialization to invoke all {@link RestPostInit} child-first methods.
*
* @return This object.
* @throws ServletException Error occurred.
@@ -6997,7 +7031,7 @@ public class RestContext extends Context {
}
/**
- * Called during servlet destruction to invoke all {@link HookEvent#DESTROY} methods.
+ * Called during servlet destruction to invoke all {@link RestDestroy} methods.
*/
public void destroy() {
for (MethodInvoker x : destroyMethods) {
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 e6861794f..fee7195a6 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
@@ -862,7 +862,7 @@ public class RestOpContext extends Context implements Comparable<RestOpContext>
* }
*
* <jc>// Option #3 - Registered via builder passed in through init method.</jc>
- * <ja>@RestHook</ja>(<jsf>INIT</jsf>)
+ * <ja>@RestInit</ja>
* <jk>public void</jk> init(RestContext.Builder <jv>builder</jv>) <jk>throws</jk> Exception {
* <jv>builder</jv>.converters(MyConverter.<jk>class</jk>);
* }
@@ -1891,7 +1891,7 @@ public class RestOpContext extends Context implements Comparable<RestOpContext>
* }
*
* <jc>// Option #3 - Defined via builder passed in through init method.</jc>
- * <ja>@RestHook</ja>(<jsf>INIT</jsf>)
+ * <ja>@RestInit</ja>
* <jk>public void</jk> init(RestContext.Builder <jv>builder</jv>) <jk>throws</jk> Exception {
* <jv>builder</jv>.maxInput(<js>"10M"</js>);
* }
diff --git a/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/RestSession.java b/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/RestSession.java
index 9fa1876ae..dbdf3ce7b 100644
--- a/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/RestSession.java
+++ b/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/RestSession.java
@@ -544,9 +544,9 @@ public class RestSession extends ContextSession {
* Does the following:
* <ol>
* <li>Finds the Java method to invoke and creates a {@link RestOpSession} for it.
- * <li>Invokes {@link HookEvent#PRE_CALL} methods by calling {@link RestContext#preCall(RestOpSession)}.
+ * <li>Invokes {@link RestPreCall} methods by calling {@link RestContext#preCall(RestOpSession)}.
* <li>Invokes Java method by calling {@link RestOpSession#run()}.
- * <li>Invokes {@link HookEvent#POST_CALL} methods by calling {@link RestContext#postCall(RestOpSession)}.
+ * <li>Invokes {@link RestPostCall} methods by calling {@link RestContext#postCall(RestOpSession)}.
* <li>If the Java method produced output, finds the response processor for it and runs it by calling {@link RestContext#processResponse(RestOpSession)}.
* <li>If no Java method matched, generates a 404/405/412 by calling {@link RestContext#handleNotFound(RestSession)}.
* </ol>
diff --git a/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/annotation/HookEvent.java b/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/annotation/HookEvent.java
deleted file mode 100644
index 32de1ef37..000000000
--- a/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/annotation/HookEvent.java
+++ /dev/null
@@ -1,481 +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.annotation;
-
-import java.io.*;
-import java.util.*;
-import java.util.logging.*;
-
-import javax.servlet.*;
-import javax.servlet.http.*;
-
-import org.apache.juneau.*;
-import org.apache.juneau.config.*;
-import org.apache.juneau.cp.Messages;
-import org.apache.juneau.http.header.*;
-import org.apache.juneau.http.response.*;
-import org.apache.juneau.rest.*;
-import org.apache.juneau.rest.converter.*;
-import org.apache.juneau.rest.guard.*;
-import org.apache.juneau.rest.httppart.*;
-import org.apache.juneau.rest.matcher.*;
-
-/**
- * Identifies servlet and REST call lifecycle events which cause {@link RestHook @RestHook}-annotated Java methods
- * to be called.
- *
- * <ul class='seealso'>
- * <li class='link'>{@doc jrs.LifecycleHooks}
- * <li class='extlink'>{@source}
- * </ul>
- */
-public enum HookEvent {
-
- /**
- * Identifies a method that is called immediately after the <c>HttpServlet.service(HttpServletRequest, HttpServletResponse)</c>
- * method is called.
- *
- * <p>
- * Note that you only have access to the raw request and response objects at this point.
- *
- * <p>
- * The list of valid parameter types are as follows:
- * <ul>
- * <li>Servlet request/response objects:
- * <ul>
- * <li>{@link HttpServletRequest}
- * <li>{@link HttpServletResponse}
- * </ul>
- * </ul>
- *
- * <h5 class='figure'>Example:</h5>
- * <p class='bjava'>
- * <ja>@Rest</ja>(...)
- * <jk>public class</jk> MyResource <jk>extends</jk> BasicRestServlet <jk>implements</jk> BasicUniversalConfig {
- *
- * <jc>// Add a request attribute to all incoming requests.</jc>
- * <ja>@RestHook</ja>(<jsf>START_CALL</jsf>)
- * <jk>public void</jk> onStartCall(HttpServletRequest <jv>req</jv>) {
- * <jv>req</jv>.setAttribute(<js>"foobar"</js>, <jk>new</jk> FooBar());
- * }
- * }
- * </p>
- *
- * <ul class='notes'>
- * <li class='note'>
- * The method should return <jk>void</jk> although if it does return any value, the value will be ignored.
- * <li class='note'>
- * The method should be <jk>public</jk> although other visibilities are valid if the security manager allows it.
- * <li class='note'>
- * Static methods can be used.
- * <li class='note'>
- * Multiple START_CALL methods can be defined on a class.
- * <br>START_CALL methods on parent classes are invoked before START_CALL methods on child classes.
- * <br>The order of START_CALL method invocations within a class is alphabetical, then by parameter count, then by parameter types.
- * <li class='note'>
- * The method can throw any exception.
- * <br>{@link BasicHttpException BasicHttpExceptions} can be thrown to cause a particular HTTP error status code.
- * <br>All other exceptions cause an HTTP 500 error status code.
- * <li class='note'>
- * Note that if you override a parent method, you probably need to call <code><jk>super</jk>.parentMethod(...)</code>.
- * <br>The method is still considered part of the parent class for ordering purposes even though it's
- * overridden by the child class.
- * </ul>
- */
- START_CALL,
-
- /**
- * Identifies a method that gets called immediately before the <ja>@RestOp</ja> annotated method gets called.
- *
- * <p>
- * At this point, the {@link RestRequest} object has been fully initialized, and all {@link RestGuard} and
- * {@link RestMatcher} objects have been called.
- *
- * <p>
- * The list of valid parameter types are as follows:
- * <ul>
- * <li>Servlet request/response objects:
- * <ul>
- * <li>{@link HttpServletRequest}
- * <li>{@link HttpServletResponse}
- * </ul>
- * <li>Extended request/response objects:
- * <ul>
- * <li>{@link RestRequest}
- * <li>{@link RestResponse}
- * </ul>
- * <li>Header objects:
- * <ul>
- * <li>{@link Accept}
- * <li>{@link AcceptCharset}
- * <li>{@link AcceptEncoding}
- * <li>{@link AcceptLanguage}
- * <li>{@link Authorization}
- * <li>{@link CacheControl}
- * <li>{@link Connection}
- * <li>{@link ContentLength}
- * <li>{@link ContentType}
- * <li>{@link org.apache.juneau.http.header.Date}
- * <li>{@link Expect}
- * <li>{@link From}
- * <li>{@link Host}
- * <li>{@link IfMatch}
- * <li>{@link IfModifiedSince}
- * <li>{@link IfNoneMatch}
- * <li>{@link IfRange}
- * <li>{@link IfUnmodifiedSince}
- * <li>{@link MaxForwards}
- * <li>{@link Pragma}
- * <li>{@link ProxyAuthorization}
- * <li>{@link Range}
- * <li>{@link Referer}
- * <li>{@link TE}
- * <li>{@link UserAgent}
- * <li>{@link Upgrade}
- * <li>{@link Via}
- * <li>{@link Warning}
- * <li>{@link TimeZone}
- * </ul>
- * <li>Other objects:
- * <ul>
- * <li>{@link ResourceBundle}
- * <li>{@link Messages}
- * <li>{@link InputStream}
- * <li>{@link ServletInputStream}
- * <li>{@link Reader}
- * <li>{@link OutputStream}
- * <li>{@link ServletOutputStream}
- * <li>{@link Writer}
- * <li>{@link RequestHeaders}
- * <li>{@link RequestQueryParams}
- * <li>{@link RequestFormParams}
- * <li>{@link RequestPathParams}
- * <li>{@link Logger}
- * <li>{@link RestContext}
- * <li>{@link org.apache.juneau.parser.Parser}
- * <li>{@link Locale}
- * <li>{@link Swagger}
- * <li>{@link RequestContent}
- * <li>{@link Config}
- * <li>{@link UriContext}
- * <li>{@link UriResolver}
- * </ul>
- * </ul>
- *
- * <h5 class='figure'>Example:</h5>
- * <p class='bjava'>
- * <ja>@Rest</ja>(...)
- * <jk>public class</jk> MyResource <jk>extends</jk> BasicRestServlet <jk>implements</jk> BasicUniversalConfig {
- *
- * <jc>// Log the incoming request.</jc>
- * <ja>@RestHook</ja>(<jsf>PRE_CALL</jsf>)
- * <jk>public void</jk> onPreCall(Accept <jv>accept</jv>, Logger <jv>logger</jv>) {
- * <jv>logger</jv>.fine(<js>"Accept {0} header found."</js>, <jv>accept</jv>);
- * }
- * }
- * </p>
- *
- * <ul class='notes'>
- * <li class='note'>
- * The method should return <jk>void</jk> although if it does return any value, the value will be ignored.
- * <li class='note'>
- * The method should be <jk>public</jk> although other visibilities are valid if the security manager allows it.
- * <li class='note'>
- * Static methods can be used.
- * <li class='note'>
- * Multiple PRE_CALL methods can be defined on a class.
- * <br>PRE_CALL methods on parent classes are invoked before PRE_CALL methods on child classes.
- * <br>The order of PRE_CALL method invocations within a class is alphabetical, then by parameter count, then by parameter types.
- * <li class='note'>
- * The method can throw any exception.
- * <br>{@link BasicHttpException BasicHttpExceptions} can be thrown to cause a particular HTTP error status code.
- * <br>All other exceptions cause an HTTP 500 error status code.
- * <li class='note'>
- * Note that if you override a parent method, you probably need to call <code><jk>super</jk>.parentMethod(...)</code>.
- * <br>The method is still considered part of the parent class for ordering purposes even though it's
- * overridden by the child class.
- * <li class='note'>
- * It's advisable not to mess around with the HTTP content itself since you may end up consuming the content
- * before the actual REST method has a chance to use it.
- * </ul>
- */
- PRE_CALL,
-
- /**
- * Identifies a method that gets called immediately after the <ja>@RestOp</ja> annotated method gets called.
- *
- * <p>
- * At this point, the output object returned by the method call has been set on the response, but
- * {@link RestConverter RestConverters} have not yet been executed and the response has not yet been written.
- *
- * <p>
- * The list of valid parameter types are the same as {@link #PRE_CALL}.
- *
- * <h5 class='figure'>Example:</h5>
- * <p class='bjava'>
- * <ja>@Rest</ja>(...)
- * <jk>public class</jk> MyResource <jk>extends</jk> BasicRestServlet <jk>implements</jk> BasicUniversalConfig {
- *
- * <jc>// Log the result of the request.</jc>
- * <ja>@RestHook</ja>(<jsf>POST_CALL</jsf>)
- * <jk>public void</jk> onPostCall(RestResponse <jv>res</jv>, Logger <jv>logger</jv>) {
- * <jv>logger</jv>.fine(<js>Output {0} was set on the response."</js>, <jv>res</jv>.getOutput());
- * }
- * }
- * </p>
- *
- * <ul class='notes'>
- * <li class='note'>
- * The method should return <jk>void</jk> although if it does return any value, the value will be ignored.
- * <li class='note'>
- * The method should be <jk>public</jk> although other visibilities are valid if the security manager allows it.
- * <li class='note'>
- * Static methods can be used.
- * <li class='note'>
- * Multiple POST_CALL methods can be defined on a class.
- * <br>POST_CALL methods on parent classes are invoked before POST_CALL methods on child classes.
- * <br>The order of POST_CALL method invocations within a class is alphabetical, then by parameter count, then by parameter types.
- * <li class='note'>
- * The method can throw any exception, although at this point it is too late to set an HTTP error status code.
- * <li class='note'>
- * Note that if you override a parent method, you probably need to call <code><jk>super</jk>.parentMethod(...)</code>.
- * <br>The method is still considered part of the parent class for ordering purposes even though it's
- * overridden by the child class.
- * </ul>
- */
- POST_CALL,
-
- /**
- * Identifies a method that gets called right before we exit the servlet service method.
- *
- * <p>
- * At this point, the output has been written and flushed.
- *
- * <p>
- * The list of valid parameter types are as follows:
- * <ul>
- * <li>Servlet request/response objects:
- * <ul>
- * <li>{@link HttpServletRequest}
- * <li>{@link HttpServletResponse}
- * </ul>
- * </ul>
- *
- * <p>
- * The following attributes are set on the {@link HttpServletRequest} object that can be useful for logging purposes:
- * <ul>
- * <li><js>"Exception"</js> - Any exceptions thrown during the request.
- * <li><js>"ExecTime"</js> - Execution time of the request.
- * </ul>
- *
- * <h5 class='figure'>Example:</h5>
- * <p class='bjava'>
- * <ja>@Rest</ja>(...)
- * <jk>public class</jk> MyResource <jk>extends</jk> BasicRestServlet <jk>implements</jk> BasicUniversalConfig {
- *
- * <jc>// Log the time it took to execute the request.</jc>
- * <ja>@RestHook</ja>(<jsf>END_CALL</jsf>)
- * <jk>public void</jk> onEndCall(HttpServletRequest <jv>req</jv>, Logger <jv>logger</jv>) {
- * Exception <jv>exception</jv> = (Exception)<jv>req</jv>.getAttribute(<js>"Exception"</js>);
- * Long <jv>execTime</jv> = (Long)<jv>req</jv>.getAttribute(<js>"ExecTime"</js>);
- * <jk>if</jk> (<jv>exception</jv> != <jk>null</jk>)
- * <jv>logger</jv>.warn(<jv>exception</jv>, <js>"Request failed in {0}ms."</js>, <jv>execTime</jv>);
- * <jk>else</jk>
- * <jv>logger</jv>.fine(<js>"Request finished in {0}ms."</js>, <jv>execTime</jv>);
- * }
- * }
- * </p>
- *
- * <ul class='notes'>
- * <li class='note'>
- * The method should return <jk>void</jk> although if it does return any value, the value will be ignored.
- * <li class='note'>
- * The method should be <jk>public</jk> although other visibilities are valid if the security manager allows it.
- * <li class='note'>
- * Static methods can be used.
- * <li class='note'>
- * Multiple END_CALL methods can be defined on a class.
- * <br>END_CALL methods on parent classes are invoked before END_CALL methods on child classes.
- * <br>The order of END_CALL method invocations within a class is alphabetical, then by parameter count, then by parameter types.
- * <li class='note'>
- * The method can throw any exception, although at this point it is too late to set an HTTP error status code.
- * <li class='note'>
- * Note that if you override a parent method, you probably need to call <code><jk>super</jk>.parentMethod(...)</code>.
- * <br>The method is still considered part of the parent class for ordering purposes even though it's
- * overridden by the child class.
- * </ul>
- */
- END_CALL,
-
- /**
- * Identifies a method that gets called during servlet initialization.
- *
- * <p>
- * This method is called from within the {@link Servlet#init(ServletConfig)} method after the {@link org.apache.juneau.rest.RestContext.Builder}
- * object has been created and initialized with the annotations defined on the class, but before the
- * {@link RestContext} object has been created.
- *
- * <p>
- * The only valid parameter type for this method is {@link org.apache.juneau.rest.RestContext.Builder} which can be used to configure the servlet.
- *
- * <p>
- * An example of this is the <c>PetStoreResource</c> class that uses an init method to perform initialization
- * of an internal data structure.
- *
- * <h5 class='figure'>Example:</h5>
- * <p class='bjava'>
- * <ja>@Rest</ja>(...)
- * <jk>public class</jk> PetStoreResource <jk>extends</jk> BasicRestServlet <jk>implements</jk> BasicUniversalJenaConfig {
- *
- * <jc>// Our database.</jc>
- * <jk>private</jk> Map<Integer,Pet> <jf>petDB</jf>;
- *
- * <ja>@RestHook</ja>(<jsf>INIT</jsf>)
- * <jk>public void</jk> onInit(RestContext.Builder <jv>builder</jv>) <jk>throws</jk> Exception {
- * <jc>// Load our database from a local JSON file.</jc>
- * <jf>petDB</jf> = JsonParser.<jsf>DEFAULT</jsf>.parse(getClass().getResourceAsStream(<js>"PetStore.json"</js>), LinkedHashMap.<jk>class</jk>, Integer.<jk>class</jk>, Pet.<jk>class</jk>);
- * }
- * }
- * </p>
- *
- * <ul class='notes'>
- * <li class='note'>
- * The method should return <jk>void</jk> although if it does return any value, the value will be ignored.
- * <li class='note'>
- * The method should be <jk>public</jk> although other visibilities are valid if the security manager allows it.
- * <li class='note'>
- * Static methods can be used.
- * <li class='note'>
- * Multiple INIT methods can be defined on a class.
- * <br>INIT methods on parent classes are invoked before INIT methods on child classes.
- * <br>The order of INIT method invocations within a class is alphabetical, then by parameter count, then by parameter types.
- * <li class='note'>
- * The method can throw any exception causing initialization of the servlet to fail.
- * <li class='note'>
- * Note that if you override a parent method, you probably need to call <code><jk>super</jk>.parentMethod(...)</code>.
- * <br>The method is still considered part of the parent class for ordering purposes even though it's
- * overridden by the child class.
- * </ul>
- */
- INIT,
-
- /**
- * Identifies a method that gets called immediately after servlet initialization.
- *
- * <p>
- * This method is called from within the {@link Servlet#init(ServletConfig)} method after the {@link RestContext}
- * object has been created.
- *
- * <p>
- * The only valid parameter type for this method is {@link RestContext} which can be used to retrieve information
- * about the servlet.
- *
- * <ul class='notes'>
- * <li class='note'>
- * The method should return <jk>void</jk> although if it does return any value, the value will be ignored.
- * <li class='note'>
- * The method should be <jk>public</jk> although other visibilities are valid if the security manager allows it.
- * <li class='note'>
- * Static methods can be used.
- * <li class='note'>
- * Multiple POST_INIT methods can be defined on a class.
- * <br>POST_INIT methods on parent classes are invoked before POST_INIT methods on child classes.
- * <br>The order of POST_INIT method invocations within a class is alphabetical, then by parameter count, then by parameter types.
- * <li class='note'>
- * The method can throw any exception causing initialization of the servlet to fail.
- * <li class='note'>
- * Note that if you override a parent method, you probably need to call <code><jk>super</jk>.parentMethod(...)</code>.
- * <br>The method is still considered part of the parent class for ordering purposes even though it's
- * overridden by the child class.
- * </ul>
- */
- POST_INIT,
-
- /**
- * Identical to {@link #POST_INIT} except the order of execution is child-resources first.
- *
- * <p>
- * Use this annotation if you need to perform any kind of initialization on child resources before the parent resource.
- *
- * <p>
- * This method is called from within the {@link Servlet#init(ServletConfig)} method after the {@link RestContext}
- * object has been created and after the {@link #POST_INIT} methods have been called.
- *
- * <p>
- * The only valid parameter type for this method is {@link RestContext} which can be used to retrieve information
- * about the servlet.
- *
- * <ul class='notes'>
- * <li class='note'>
- * The method should return <jk>void</jk> although if it does return any value, the value will be ignored.
- * <li class='note'>
- * The method should be <jk>public</jk> although other visibilities are valid if the security manager allows it.
- * <li class='note'>
- * Static methods can be used.
- * <li class='note'>
- * Multiple POST_INIT_CHILD_FIRST methods can be defined on a class.
- * <br>POST_INIT_CHILD_FIRST methods on parent classes are invoked before POST_INIT_CHILD_FIRST methods on child classes.
- * <br>The order of POST_INIT_CHILD_FIRST method invocations within a class is alphabetical, then by parameter count, then by parameter types.
- * <li class='note'>
- * The method can throw any exception causing initialization of the servlet to fail.
- * </ul>
- */
- POST_INIT_CHILD_FIRST,
-
- /**
- * Identifies a method that gets called during servlet destroy.
- *
- * <p>
- * This method is called from within the {@link Servlet#destroy()}.
- *
- * <p>
- * The only valid parameter type for this method is {@link RestContext}, although typically no arguments will
- * be specified.
- *
- * <h5 class='figure'>Example:</h5>
- * <p class='bjava'>
- * <ja>@Rest</ja>(...)
- * <jk>public class</jk> PetStoreResource <jk>extends</jk> BasicRestServlet <jk>implements</jk> BasicUniversalJenaConfig {
- *
- * <jc>// Our database.</jc>
- * <jk>private</jk> Map<Integer,Pet> <jf>petDB</jf>;
- *
- * <ja>@RestHook</ja>(<jsf>DESTROY</jsf>)
- * <jk>public void</jk> onDestroy() {
- * <jf>petDB</jf> = <jk>null</jk>;
- * }
- * }
- * </p>
- *
- * <ul class='notes'>
- * <li class='note'>
- * The method should return <jk>void</jk> although if it does return any value, the value will be ignored.
- * <li class='note'>
- * The method should be <jk>public</jk> although other visibilities are valid if the security manager allows it.
- * <li class='note'>
- * Static methods can be used.
- * <li class='note'>
- * Multiple DESTROY methods can be defined on a class.
- * <br>DESTROY methods on child classes are invoked before DESTROY methods on parent classes.
- * <br>The order of DESTROY method invocations within a class is alphabetical, then by parameter count, then by parameter types.
- * <li class='note'>
- * In general, destroy methods should not throw any exceptions, although if any are thrown, the stack trace will be
- * printed to <c>System.err</c>.
- * <li class='note'>
- * Note that if you override a parent method, you probably need to call <code><jk>super</jk>.parentMethod(...)</code>.
- * <br>The method is still considered part of the parent class for ordering purposes even though it's
- * overridden by the child class.
- * </ul>
- */
- DESTROY
-}
diff --git a/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/annotation/RestDestroy.java b/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/annotation/RestDestroy.java
new file mode 100644
index 000000000..4f1c9cc3f
--- /dev/null
+++ b/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/annotation/RestDestroy.java
@@ -0,0 +1,100 @@
+// ***************************************************************************************************************************
+// * 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.annotation;
+
+import static java.lang.annotation.ElementType.*;
+import static java.lang.annotation.RetentionPolicy.*;
+
+import java.lang.annotation.*;
+
+import javax.servlet.*;
+
+import org.apache.juneau.rest.*;
+import org.apache.juneau.rest.servlet.*;
+
+/**
+ * Identifies a method that gets called during servlet destroy.
+ *
+ * <p>
+ * This method is called from within the {@link Servlet#destroy()}.
+ *
+ * <p>
+ * The only valid parameter type for this method is {@link RestContext}, although typically no arguments will
+ * be specified.
+ *
+ * <h5 class='figure'>Example:</h5>
+ * <p class='bjava'>
+ * <ja>@Rest</ja>(...)
+ * <jk>public class</jk> PetStoreResource <jk>extends</jk> BasicRestServlet <jk>implements</jk> BasicUniversalJenaConfig {
+ *
+ * <jc>// Our database.</jc>
+ * <jk>private</jk> Map<Integer,Pet> <jf>petDB</jf>;
+ *
+ * <ja>@RestDestroy</ja>
+ * <jk>public void</jk> onDestroy() {
+ * <jf>petDB</jf> = <jk>null</jk>;
+ * }
+ * }
+ * </p>
+ *
+ * <ul class='notes'>
+ * <li class='note'>
+ * The method should return <jk>void</jk> although if it does return any value, the value will be ignored.
+ * <li class='note'>
+ * The method should be <jk>public</jk> although other visibilities are valid if the security manager allows it.
+ * <li class='note'>
+ * Static methods can be used.
+ * <li class='note'>
+ * Multiple destroy methods can be defined on a class.
+ * <br>Destroy methods on child classes are invoked before destroy methods on parent classes.
+ * <br>The order of destroy method invocations within a class is alphabetical, then by parameter count, then by parameter types.
+ * <li class='note'>
+ * In general, destroy methods should not throw any exceptions, although if any are thrown, the stack trace will be
+ * printed to <c>System.err</c>.
+ * <li class='note'>
+ * Note that if you override a parent method, you probably need to call <code><jk>super</jk>.parentMethod(...)</code>.
+ * <br>The method is still considered part of the parent class for ordering purposes even though it's
+ * overridden by the child class.
+ * <li class='note'>
+ * The {@link RestServlet} class itself implements a method annotated with this annotation
+ * that can be overridden directly:
+ * <ul class='javatree'>
+ * <li class='jac'>{@link RestServlet}
+ * <ul>
+ * <li class='jm'>{@link RestServlet#onDestroy(RestContext) onDestroy(RestContext)}
+ * </ul>
+ * </ul>
+ * </ul>
+ *
+ * <ul class='seealso'>
+ * <li class='link'>{@doc jrs.LifecycleHooks}
+ * <li class='extlink'>{@source}
+ * </ul>
+ */
+@Target({METHOD,TYPE})
+@Retention(RUNTIME)
+@Inherited
+@Repeatable(RestDestroyAnnotation.Array.class)
+public @interface RestDestroy {
+
+ /**
+ * Dynamically apply this annotation to the specified methods.
+ *
+ * <ul class='seealso'>
+ * <li class='link'>{@doc jm.DynamicallyAppliedAnnotations}
+ * </ul>
+ *
+ * @return The annotation value.
+ */
+ String[] on() default {};
+}
diff --git a/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/annotation/RestHookAnnotation.java b/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/annotation/RestDestroyAnnotation.java
similarity index 81%
copy from juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/annotation/RestHookAnnotation.java
copy to juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/annotation/RestDestroyAnnotation.java
index d36ec77f4..dd66e57a1 100644
--- a/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/annotation/RestHookAnnotation.java
+++ b/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/annotation/RestDestroyAnnotation.java
@@ -20,21 +20,21 @@ import java.lang.annotation.*;
import org.apache.juneau.annotation.*;
/**
- * Utility classes and methods for the {@link RestHook @RestHook} annotation.
+ * Utility classes and methods for the {@link RestDestroy @RestDestroy} annotation.
*
* <ul class='seealso'>
* <li class='link'>{@doc jrs.LifecycleHooks}
* <li class='extlink'>{@source}
* </ul>
*/
-public class RestHookAnnotation {
+public class RestDestroyAnnotation {
//-----------------------------------------------------------------------------------------------------------------
// Static
//-----------------------------------------------------------------------------------------------------------------
/** Default value */
- public static final RestHook DEFAULT = create().value(HookEvent.INIT).build();
+ public static final RestDestroy DEFAULT = create().build();
/**
* Instantiates a new builder for this class.
@@ -58,35 +58,22 @@ public class RestHookAnnotation {
*/
public static class Builder extends TargetedAnnotationMBuilder {
- HookEvent value = HookEvent.INIT;
-
/**
* Constructor.
*/
protected Builder() {
- super(RestHook.class);
+ super(RestDestroy.class);
}
/**
- * Instantiates a new {@link RestHook @RestHook} object initialized with this builder.
+ * Instantiates a new {@link RestDestroy @RestDestroy} object initialized with this builder.
*
- * @return A new {@link RestHook @RestHook} object.
+ * @return A new {@link RestDestroy @RestDestroy} object.
*/
- public RestHook build() {
+ public RestDestroy build() {
return new Impl(this);
}
- /**
- * Sets the {@link RestHook#value()} property on this annotation.
- *
- * @param value The new value for this property.
- * @return This object.
- */
- public Builder value(HookEvent value) {
- this.value = value;
- return this;
- }
-
// <FluentSetters>
@Override /* GENERATED - TargetedAnnotationBuilder */
@@ -108,20 +95,12 @@ public class RestHookAnnotation {
// Implementation
//-----------------------------------------------------------------------------------------------------------------
- private static class Impl extends TargetedAnnotationImpl implements RestHook {
-
- private final HookEvent value;
+ private static class Impl extends TargetedAnnotationImpl implements RestDestroy {
Impl(Builder b) {
super(b);
- this.value = b.value;
postConstruct();
}
-
- @Override /* RestHook */
- public HookEvent value() {
- return value;
- }
}
//-----------------------------------------------------------------------------------------------------------------
@@ -129,7 +108,7 @@ public class RestHookAnnotation {
//-----------------------------------------------------------------------------------------------------------------
/**
- * A collection of {@link RestHook @RestHook annotations}.
+ * A collection of {@link RestDestroy @RestDestroy annotations}.
*/
@Documented
@Target({METHOD,TYPE})
@@ -142,6 +121,6 @@ public class RestHookAnnotation {
*
* @return The annotation value.
*/
- RestHook[] value();
+ RestDestroy[] value();
}
}
\ No newline at end of file
diff --git a/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/annotation/RestEndCall.java b/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/annotation/RestEndCall.java
new file mode 100644
index 000000000..2c58ba2f7
--- /dev/null
+++ b/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/annotation/RestEndCall.java
@@ -0,0 +1,114 @@
+// ***************************************************************************************************************************
+// * 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.annotation;
+
+import static java.lang.annotation.ElementType.*;
+import static java.lang.annotation.RetentionPolicy.*;
+
+import java.lang.annotation.*;
+
+import javax.servlet.http.*;
+
+import org.apache.juneau.rest.servlet.*;
+
+/**
+ * Identifies a method that gets called right before we exit the servlet service method.
+ *
+ * <p>
+ * At this point, the output has been written and flushed.
+ *
+ * <p>
+ * The list of valid parameter types are as follows:
+ * <ul>
+ * <li>Servlet request/response objects:
+ * <ul>
+ * <li>{@link HttpServletRequest}
+ * <li>{@link HttpServletResponse}
+ * </ul>
+ * </ul>
+ *
+ * <p>
+ * The following attributes are set on the {@link HttpServletRequest} object that can be useful for logging purposes:
+ * <ul>
+ * <li><js>"Exception"</js> - Any exceptions thrown during the request.
+ * <li><js>"ExecTime"</js> - Execution time of the request.
+ * </ul>
+ *
+ * <h5 class='figure'>Example:</h5>
+ * <p class='bjava'>
+ * <ja>@Rest</ja>(...)
+ * <jk>public class</jk> MyResource <jk>extends</jk> BasicRestServlet <jk>implements</jk> BasicUniversalConfig {
+ *
+ * <jc>// Log the time it took to execute the request.</jc>
+ * <ja>@RestEndCall
+ * <jk>public void</jk> onEndCall(HttpServletRequest <jv>req</jv>, Logger <jv>logger</jv>) {
+ * Exception <jv>exception</jv> = (Exception)<jv>req</jv>.getAttribute(<js>"Exception"</js>);
+ * Long <jv>execTime</jv> = (Long)<jv>req</jv>.getAttribute(<js>"ExecTime"</js>);
+ * <jk>if</jk> (<jv>exception</jv> != <jk>null</jk>)
+ * <jv>logger</jv>.warn(<jv>exception</jv>, <js>"Request failed in {0}ms."</js>, <jv>execTime</jv>);
+ * <jk>else</jk>
+ * <jv>logger</jv>.fine(<js>"Request finished in {0}ms."</js>, <jv>execTime</jv>);
+ * }
+ * }
+ * </p>
+ *
+ * <ul class='notes'>
+ * <li class='note'>
+ * The method should return <jk>void</jk> although if it does return any value, the value will be ignored.
+ * <li class='note'>
+ * The method should be <jk>public</jk> although other visibilities are valid if the security manager allows it.
+ * <li class='note'>
+ * Static methods can be used.
+ * <li class='note'>
+ * Multiple END_CALL methods can be defined on a class.
+ * <br>END_CALL methods on parent classes are invoked before END_CALL methods on child classes.
+ * <br>The order of END_CALL method invocations within a class is alphabetical, then by parameter count, then by parameter types.
+ * <li class='note'>
+ * The method can throw any exception, although at this point it is too late to set an HTTP error status code.
+ * <li class='note'>
+ * Note that if you override a parent method, you probably need to call <code><jk>super</jk>.parentMethod(...)</code>.
+ * <br>The method is still considered part of the parent class for ordering purposes even though it's
+ * overridden by the child class.
+ * <li class='note'>
+ * The {@link RestServlet} class itself implements a convenience method annotated with this annotation
+ * that can be overridden directly:
+ * <ul class='javatree'>
+ * <li class='jac'>{@link RestServlet}
+ * <ul>
+ * <li class='jm'>{@link RestServlet#onEndCall(HttpServletRequest,HttpServletResponse) onEndCall(HttpServletRequest,HttpServletResponse)}
+ * </ul>
+ * </ul>
+ * </ul>
+ *
+ * <ul class='seealso'>
+ * <li class='link'>{@doc jrs.LifecycleHooks}
+ * <li class='extlink'>{@source}
+ * </ul>
+ */
+@Target({METHOD,TYPE})
+@Retention(RUNTIME)
+@Inherited
+@Repeatable(RestEndCallAnnotation.Array.class)
+public @interface RestEndCall {
+
+ /**
+ * Dynamically apply this annotation to the specified methods.
+ *
+ * <ul class='seealso'>
+ * <li class='link'>{@doc jm.DynamicallyAppliedAnnotations}
+ * </ul>
+ *
+ * @return The annotation value.
+ */
+ String[] on() default {};
+}
diff --git a/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/annotation/RestHookAnnotation.java b/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/annotation/RestEndCallAnnotation.java
similarity index 81%
copy from juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/annotation/RestHookAnnotation.java
copy to juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/annotation/RestEndCallAnnotation.java
index d36ec77f4..03fae8c70 100644
--- a/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/annotation/RestHookAnnotation.java
+++ b/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/annotation/RestEndCallAnnotation.java
@@ -20,21 +20,21 @@ import java.lang.annotation.*;
import org.apache.juneau.annotation.*;
/**
- * Utility classes and methods for the {@link RestHook @RestHook} annotation.
+ * Utility classes and methods for the {@link RestEndCall @RestEndCall} annotation.
*
* <ul class='seealso'>
* <li class='link'>{@doc jrs.LifecycleHooks}
* <li class='extlink'>{@source}
* </ul>
*/
-public class RestHookAnnotation {
+public class RestEndCallAnnotation {
//-----------------------------------------------------------------------------------------------------------------
// Static
//-----------------------------------------------------------------------------------------------------------------
/** Default value */
- public static final RestHook DEFAULT = create().value(HookEvent.INIT).build();
+ public static final RestEndCall DEFAULT = create().build();
/**
* Instantiates a new builder for this class.
@@ -58,35 +58,22 @@ public class RestHookAnnotation {
*/
public static class Builder extends TargetedAnnotationMBuilder {
- HookEvent value = HookEvent.INIT;
-
/**
* Constructor.
*/
protected Builder() {
- super(RestHook.class);
+ super(RestEndCall.class);
}
/**
- * Instantiates a new {@link RestHook @RestHook} object initialized with this builder.
+ * Instantiates a new {@link RestEndCall @RestEndCall} object initialized with this builder.
*
- * @return A new {@link RestHook @RestHook} object.
+ * @return A new {@link RestEndCall @RestEndCall} object.
*/
- public RestHook build() {
+ public RestEndCall build() {
return new Impl(this);
}
- /**
- * Sets the {@link RestHook#value()} property on this annotation.
- *
- * @param value The new value for this property.
- * @return This object.
- */
- public Builder value(HookEvent value) {
- this.value = value;
- return this;
- }
-
// <FluentSetters>
@Override /* GENERATED - TargetedAnnotationBuilder */
@@ -108,20 +95,12 @@ public class RestHookAnnotation {
// Implementation
//-----------------------------------------------------------------------------------------------------------------
- private static class Impl extends TargetedAnnotationImpl implements RestHook {
-
- private final HookEvent value;
+ private static class Impl extends TargetedAnnotationImpl implements RestEndCall {
Impl(Builder b) {
super(b);
- this.value = b.value;
postConstruct();
}
-
- @Override /* RestHook */
- public HookEvent value() {
- return value;
- }
}
//-----------------------------------------------------------------------------------------------------------------
@@ -129,7 +108,7 @@ public class RestHookAnnotation {
//-----------------------------------------------------------------------------------------------------------------
/**
- * A collection of {@link RestHook @RestHook annotations}.
+ * A collection of {@link RestEndCall @RestEndCall annotations}.
*/
@Documented
@Target({METHOD,TYPE})
@@ -142,6 +121,6 @@ public class RestHookAnnotation {
*
* @return The annotation value.
*/
- RestHook[] value();
+ RestEndCall[] value();
}
}
\ No newline at end of file
diff --git a/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/annotation/RestHook.java b/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/annotation/RestHook.java
deleted file mode 100644
index 18877cb0d..000000000
--- a/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/annotation/RestHook.java
+++ /dev/null
@@ -1,125 +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.annotation;
-
-import static java.lang.annotation.ElementType.*;
-import static java.lang.annotation.RetentionPolicy.*;
-
-import java.lang.annotation.*;
-
-import javax.servlet.http.*;
-
-import org.apache.juneau.rest.*;
-import org.apache.juneau.rest.servlet.*;
-
-/**
- * Identifies Java methods on a resource/servlet class that get invoked during particular lifecycle events of
- * the servlet or REST call.
- *
- * <p>
- * For example, if you want to add an initialization method to your resource:
- * <p class='bjava'>
- * <ja>@Rest</ja>(...)
- * <jk>public class</jk> MyResource {
- *
- * <jc>// Our database.</jc>
- * <jk>private</jk> Map<Integer,Object> <jf>myDatabase</jf>;
- *
- * <ja>@RestHook</ja>(<jsf>INIT</jsf>)
- * <jk>public void</jk> initMyDatabase(RestContext.Builder <jv>builder</jv>) <jk>throws</jk> Exception {
- * <jf>myDatabase</jf> = <jk>new</jk> LinkedHashMap<>();
- * }
- * }
- * </p>
- *
- * <p>
- * Or if you want to intercept REST calls:
- * <p class='bjava'>
- * <ja>@Rest</ja>(...)
- * <jk>public class</jk> MyResource {
- *
- * <jc>// Add a request attribute to all incoming requests.</jc>
- * <ja>@RestHook</ja>(<jsf>PRE_CALL</jsf>)
- * <jk>public void</jk> onPreCall(RestRequest <jv>req</jv>) {
- * <jv>req</jv>.setAttribute(<js>"foo"</js>, <js>"bar"</js>);
- * }
- * }
- * </p>
- *
- * <p>
- * The hook events can be broken down into two categories:
- * <ul class='spaced-list'>
- * <li>Resource lifecycle events:
- * <ul>
- * <li>{@link HookEvent#INIT INIT} - Right before initialization.
- * <li>{@link HookEvent#POST_INIT POST_INIT} - Right after initialization.
- * <li>{@link HookEvent#POST_INIT_CHILD_FIRST POST_INIT_CHILD_FIRST} - Right after initialization, but run child methods first.
- * <li>{@link HookEvent#DESTROY DESTROY} - Right before servlet destroy.
- * </ul>
- * <li>REST call lifecycle events:
- * <ul>
- * <li>{@link HookEvent#START_CALL START_CALL} - At the beginning of a REST call.
- * <li>{@link HookEvent#PRE_CALL PRE_CALL} - Right before the <ja>@RestOp</ja> method is invoked.
- * <li>{@link HookEvent#POST_CALL POST_CALL} - Right after the <ja>@RestOp</ja> method is invoked.
- * <li>{@link HookEvent#END_CALL END_CALL} - At the end of the REST call after the response has been flushed.
- * </ul>
- * </ul>
- *
- * <ul class='notes'>
- * <li class='note'>
- * The {@link RestServlet} class itself implements several convenience methods annotated with this annotation
- * that can be overridden directly:
- * <ul class='javatree'>
- * <li class='jac'>{@link RestServlet}
- * <ul>
- * <li class='jm'>{@link RestServlet#onInit(RestContext.Builder) onInit(RestContext.Builder)}
- * <li class='jm'>{@link RestServlet#onPostInit(RestContext) onPostInit(RestContext)}
- * <li class='jm'>{@link RestServlet#onPostInitChildFirst(RestContext) onPostInitChildFirst(RestContext)}
- * <li class='jm'>{@link RestServlet#onDestroy(RestContext) onDestroy(RestContext)}
- * <li class='jm'>{@link RestServlet#onStartCall(HttpServletRequest,HttpServletResponse) onStartCall(HttpServletRequest,HttpServletResponse)}
- * <li class='jm'>{@link RestServlet#onPreCall(RestRequest,RestResponse) onPreCall(RestRequest,RestResponse)}
- * <li class='jm'>{@link RestServlet#onPostCall(RestRequest,RestResponse) onPostCall(RestRequest,RestResponse)}
- * <li class='jm'>{@link RestServlet#onEndCall(HttpServletRequest,HttpServletResponse) onEndCall(HttpServletRequest,HttpServletResponse)}
- * </ul>
- * </ul>
- * </ul>
- *
- * <ul class='seealso'>
- * <li class='link'>{@doc jrs.LifecycleHooks}
- * <li class='extlink'>{@source}
- * </ul>
- */
-@Target({METHOD,TYPE})
-@Retention(RUNTIME)
-@Inherited
-@Repeatable(RestHookAnnotation.Array.class)
-public @interface RestHook {
-
- /**
- * Dynamically apply this annotation to the specified methods.
- *
- * <ul class='seealso'>
- * <li class='link'>{@doc jm.DynamicallyAppliedAnnotations}
- * </ul>
- *
- * @return The annotation value.
- */
- String[] on() default {};
-
- /**
- * The lifecycle event.
- *
- * @return The annotation value.
- */
- HookEvent value() default HookEvent.INIT;
-}
diff --git a/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/annotation/RestInit.java b/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/annotation/RestInit.java
new file mode 100644
index 000000000..e6f92a5f2
--- /dev/null
+++ b/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/annotation/RestInit.java
@@ -0,0 +1,105 @@
+// ***************************************************************************************************************************
+// * 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.annotation;
+
+import static java.lang.annotation.ElementType.*;
+import static java.lang.annotation.RetentionPolicy.*;
+
+import java.lang.annotation.*;
+
+import javax.servlet.*;
+
+import org.apache.juneau.rest.*;
+import org.apache.juneau.rest.servlet.*;
+
+/**
+ * Identifies a method that gets called during servlet initialization.
+ *
+ * <p>
+ * This method is called from within the {@link Servlet#init(ServletConfig)} method after the {@link org.apache.juneau.rest.RestContext.Builder}
+ * object has been created and initialized with the annotations defined on the class, but before the
+ * {@link RestContext} object has been created.
+ *
+ * <p>
+ * The only valid parameter type for this method is {@link org.apache.juneau.rest.RestContext.Builder} which can be used to configure the servlet.
+ *
+ * <p>
+ * An example of this is the <c>PetStoreResource</c> class that uses an init method to perform initialization
+ * of an internal data structure.
+ *
+ * <h5 class='figure'>Example:</h5>
+ * <p class='bjava'>
+ * <ja>@Rest</ja>(...)
+ * <jk>public class</jk> PetStoreResource <jk>extends</jk> BasicRestServlet <jk>implements</jk> BasicUniversalJenaConfig {
+ *
+ * <jc>// Our database.</jc>
+ * <jk>private</jk> Map<Integer,Pet> <jf>petDB</jf>;
+ *
+ * <ja>@RestInit</ja>
+ * <jk>public void</jk> onInit(RestContext.Builder <jv>builder</jv>) <jk>throws</jk> Exception {
+ * <jc>// Load our database from a local JSON file.</jc>
+ * <jf>petDB</jf> = JsonParser.<jsf>DEFAULT</jsf>.parse(getClass().getResourceAsStream(<js>"PetStore.json"</js>), LinkedHashMap.<jk>class</jk>, Integer.<jk>class</jk>, Pet.<jk>class</jk>);
+ * }
+ * }
+ * </p>
+ *
+ * <ul class='notes'>
+ * <li class='note'>
+ * The method should return <jk>void</jk> although if it does return any value, the value will be ignored.
+ * <li class='note'>
+ * The method should be <jk>public</jk> although other visibilities are valid if the security manager allows it.
+ * <li class='note'>
+ * Static methods can be used.
+ * <li class='note'>
+ * Multiple init methods can be defined on a class.
+ * <br>Init methods on parent classes are invoked before init methods on child classes.
+ * <br>The order of init method invocations within a class is alphabetical, then by parameter count, then by parameter types.
+ * <li class='note'>
+ * The method can throw any exception causing initialization of the servlet to fail.
+ * <li class='note'>
+ * Note that if you override a parent method, you probably need to call <code><jk>super</jk>.parentMethod(...)</code>.
+ * <br>The method is still considered part of the parent class for ordering purposes even though it's
+ * overridden by the child class.
+ * <li class='note'>
+ * The {@link RestServlet} class itself implements the following convenience method annotated with this annotation
+ * that can be overridden directly:
+ * <ul class='javatree'>
+ * <li class='jac'>{@link RestServlet}
+ * <ul>
+ * <li class='jm'>{@link RestServlet#onInit(RestContext.Builder) onInit(RestContext.Builder)}
+ * </ul>
+ * </ul>
+ * </ul>
+ *
+ * <ul class='seealso'>
+ * <li class='link'>{@doc jrs.LifecycleHooks}
+ * <li class='extlink'>{@source}
+ * </ul>
+ */
+@Target({METHOD,TYPE})
+@Retention(RUNTIME)
+@Inherited
+@Repeatable(RestInitAnnotation.Array.class)
+public @interface RestInit {
+
+ /**
+ * Dynamically apply this annotation to the specified methods.
+ *
+ * <ul class='seealso'>
+ * <li class='link'>{@doc jm.DynamicallyAppliedAnnotations}
+ * </ul>
+ *
+ * @return The annotation value.
+ */
+ String[] on() default {};
+}
diff --git a/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/annotation/RestHookAnnotation.java b/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/annotation/RestInitAnnotation.java
similarity index 82%
copy from juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/annotation/RestHookAnnotation.java
copy to juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/annotation/RestInitAnnotation.java
index d36ec77f4..208387621 100644
--- a/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/annotation/RestHookAnnotation.java
+++ b/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/annotation/RestInitAnnotation.java
@@ -20,21 +20,21 @@ import java.lang.annotation.*;
import org.apache.juneau.annotation.*;
/**
- * Utility classes and methods for the {@link RestHook @RestHook} annotation.
+ * Utility classes and methods for the {@link RestInit @RestInit} annotation.
*
* <ul class='seealso'>
* <li class='link'>{@doc jrs.LifecycleHooks}
* <li class='extlink'>{@source}
* </ul>
*/
-public class RestHookAnnotation {
+public class RestInitAnnotation {
//-----------------------------------------------------------------------------------------------------------------
// Static
//-----------------------------------------------------------------------------------------------------------------
/** Default value */
- public static final RestHook DEFAULT = create().value(HookEvent.INIT).build();
+ public static final RestInit DEFAULT = create().build();
/**
* Instantiates a new builder for this class.
@@ -58,35 +58,22 @@ public class RestHookAnnotation {
*/
public static class Builder extends TargetedAnnotationMBuilder {
- HookEvent value = HookEvent.INIT;
-
/**
* Constructor.
*/
protected Builder() {
- super(RestHook.class);
+ super(RestInit.class);
}
/**
- * Instantiates a new {@link RestHook @RestHook} object initialized with this builder.
+ * Instantiates a new {@link RestInit @RestInit} object initialized with this builder.
*
- * @return A new {@link RestHook @RestHook} object.
+ * @return A new {@link RestInit @RestInit} object.
*/
- public RestHook build() {
+ public RestInit build() {
return new Impl(this);
}
- /**
- * Sets the {@link RestHook#value()} property on this annotation.
- *
- * @param value The new value for this property.
- * @return This object.
- */
- public Builder value(HookEvent value) {
- this.value = value;
- return this;
- }
-
// <FluentSetters>
@Override /* GENERATED - TargetedAnnotationBuilder */
@@ -108,20 +95,12 @@ public class RestHookAnnotation {
// Implementation
//-----------------------------------------------------------------------------------------------------------------
- private static class Impl extends TargetedAnnotationImpl implements RestHook {
-
- private final HookEvent value;
+ private static class Impl extends TargetedAnnotationImpl implements RestInit {
Impl(Builder b) {
super(b);
- this.value = b.value;
postConstruct();
}
-
- @Override /* RestHook */
- public HookEvent value() {
- return value;
- }
}
//-----------------------------------------------------------------------------------------------------------------
@@ -129,7 +108,7 @@ public class RestHookAnnotation {
//-----------------------------------------------------------------------------------------------------------------
/**
- * A collection of {@link RestHook @RestHook annotations}.
+ * A collection of {@link RestInit @RestInit annotations}.
*/
@Documented
@Target({METHOD,TYPE})
@@ -142,6 +121,6 @@ public class RestHookAnnotation {
*
* @return The annotation value.
*/
- RestHook[] value();
+ RestInit[] value();
}
}
\ No newline at end of file
diff --git a/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/annotation/RestPostCall.java b/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/annotation/RestPostCall.java
new file mode 100644
index 000000000..0bc8b6b66
--- /dev/null
+++ b/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/annotation/RestPostCall.java
@@ -0,0 +1,175 @@
+// ***************************************************************************************************************************
+// * 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.annotation;
+
+import static java.lang.annotation.ElementType.*;
+import static java.lang.annotation.RetentionPolicy.*;
+
+import java.io.*;
+import java.lang.annotation.*;
+import java.util.*;
+import java.util.logging.*;
+
+import javax.servlet.*;
+import javax.servlet.http.*;
+
+import org.apache.juneau.*;
+import org.apache.juneau.config.*;
+import org.apache.juneau.cp.*;
+import org.apache.juneau.http.header.*;
+import org.apache.juneau.rest.*;
+import org.apache.juneau.rest.converter.*;
+import org.apache.juneau.rest.httppart.*;
+import org.apache.juneau.rest.servlet.*;
+
+/**
+ * Identifies a method that gets called immediately after the <ja>@RestOp</ja> annotated method gets called.
+ *
+ * <p>
+ * At this point, the output object returned by the method call has been set on the response, but
+ * {@link RestConverter RestConverters} have not yet been executed and the response has not yet been written.
+ *
+ * <p>
+ * The list of valid parameter types are as follows:
+ * <ul>
+ * <li>Servlet request/response objects:
+ * <ul class='javatreec'>
+ * <li>{@link HttpServletRequest}
+ * <li>{@link HttpServletResponse}
+ * </ul>
+ * <li>Extended request/response objects:
+ * <ul class='javatreec'>
+ * <li>{@link RestRequest}
+ * <li>{@link RestResponse}
+ * </ul>
+ * <li>Header objects:
+ * <ul class='javatreec'>
+ * <li>{@link Accept}
+ * <li>{@link AcceptCharset}
+ * <li>{@link AcceptEncoding}
+ * <li>{@link AcceptLanguage}
+ * <li>{@link Authorization}
+ * <li>{@link CacheControl}
+ * <li>{@link Connection}
+ * <li>{@link ContentLength}
+ * <li>{@link ContentType}
+ * <li>{@link org.apache.juneau.http.header.Date}
+ * <li>{@link Expect}
+ * <li>{@link From}
+ * <li>{@link Host}
+ * <li>{@link IfMatch}
+ * <li>{@link IfModifiedSince}
+ * <li>{@link IfNoneMatch}
+ * <li>{@link IfRange}
+ * <li>{@link IfUnmodifiedSince}
+ * <li>{@link MaxForwards}
+ * <li>{@link Pragma}
+ * <li>{@link ProxyAuthorization}
+ * <li>{@link Range}
+ * <li>{@link Referer}
+ * <li>{@link TE}
+ * <li>{@link UserAgent}
+ * <li>{@link Upgrade}
+ * <li>{@link Via}
+ * <li>{@link Warning}
+ * <li>{@link TimeZone}
+ * </ul>
+ * <li>Other objects:
+ * <ul class='javatreec'>
+ * <li>{@link ResourceBundle}
+ * <li>{@link Messages}
+ * <li>{@link InputStream}
+ * <li>{@link ServletInputStream}
+ * <li>{@link Reader}
+ * <li>{@link OutputStream}
+ * <li>{@link ServletOutputStream}
+ * <li>{@link Writer}
+ * <li>{@link RequestHeaders}
+ * <li>{@link RequestQueryParams}
+ * <li>{@link RequestFormParams}
+ * <li>{@link RequestPathParams}
+ * <li>{@link Logger}
+ * <li>{@link RestContext}
+ * <li>{@link org.apache.juneau.parser.Parser}
+ * <li>{@link Locale}
+ * <li>{@link Swagger}
+ * <li>{@link RequestContent}
+ * <li>{@link Config}
+ * <li>{@link UriContext}
+ * <li>{@link UriResolver}
+ * </ul>
+ * </ul>
+ *
+ * <h5 class='figure'>Example:</h5>
+ * <p class='bjava'>
+ * <ja>@Rest</ja>(...)
+ * <jk>public class</jk> MyResource <jk>extends</jk> BasicRestServlet <jk>implements</jk> BasicUniversalConfig {
+ *
+ * <jc>// Log the result of the request.</jc>
+ * <ja>@RestPostCall</ja>
+ * <jk>public void</jk> onPostCall(RestResponse <jv>res</jv>, Logger <jv>logger</jv>) {
+ * <jv>logger</jv>.fine(<js>Output {0} was set on the response."</js>, <jv>res</jv>.getOutput());
+ * }
+ * }
+ * </p>
+ *
+ * <ul class='notes'>
+ * <li class='note'>
+ * The method should return <jk>void</jk> although if it does return any value, the value will be ignored.
+ * <li class='note'>
+ * The method should be <jk>public</jk> although other visibilities are valid if the security manager allows it.
+ * <li class='note'>
+ * Static methods can be used.
+ * <li class='note'>
+ * Multiple post-call methods can be defined on a class.
+ * <br>Post-call methods on parent classes are invoked before post-call methods on child classes.
+ * <br>The order of post-call method invocations within a class is alphabetical, then by parameter count, then by parameter types.
+ * <li class='note'>
+ * The method can throw any exception, although at this point it is too late to set an HTTP error status code.
+ * <li class='note'>
+ * Note that if you override a parent method, you probably need to call <code><jk>super</jk>.parentMethod(...)</code>.
+ * <br>The method is still considered part of the parent class for ordering purposes even though it's
+ * overridden by the child class.
+ * <li class='note'>
+ * The {@link RestServlet} class itself implements a convenience method annotated with this annotation
+ * that can be overridden directly:
+ * <ul class='javatree'>
+ * <li class='jac'>{@link RestServlet}
+ * <ul>
+ * <li class='jm'>{@link RestServlet#onPostCall(RestRequest,RestResponse) onPostCall(RestRequest,RestResponse)}
+ * </ul>
+ * </ul>
+ * </ul>
+ *
+ * <ul class='seealso'>
+ * <li class='link'>{@doc jrs.LifecycleHooks}
+ * <li class='extlink'>{@source}
+ * </ul>
+ */
+@Target({METHOD,TYPE})
+@Retention(RUNTIME)
+@Inherited
+@Repeatable(RestPostCallAnnotation.Array.class)
+public @interface RestPostCall {
+
+ /**
+ * Dynamically apply this annotation to the specified methods.
+ *
+ * <ul class='seealso'>
+ * <li class='link'>{@doc jm.DynamicallyAppliedAnnotations}
+ * </ul>
+ *
+ * @return The annotation value.
+ */
+ String[] on() default {};
+}
diff --git a/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/annotation/RestHookAnnotation.java b/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/annotation/RestPostCallAnnotation.java
similarity index 81%
copy from juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/annotation/RestHookAnnotation.java
copy to juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/annotation/RestPostCallAnnotation.java
index d36ec77f4..3f435ff53 100644
--- a/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/annotation/RestHookAnnotation.java
+++ b/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/annotation/RestPostCallAnnotation.java
@@ -20,21 +20,21 @@ import java.lang.annotation.*;
import org.apache.juneau.annotation.*;
/**
- * Utility classes and methods for the {@link RestHook @RestHook} annotation.
+ * Utility classes and methods for the {@link RestPostCall @RestPostCall} annotation.
*
* <ul class='seealso'>
* <li class='link'>{@doc jrs.LifecycleHooks}
* <li class='extlink'>{@source}
* </ul>
*/
-public class RestHookAnnotation {
+public class RestPostCallAnnotation {
//-----------------------------------------------------------------------------------------------------------------
// Static
//-----------------------------------------------------------------------------------------------------------------
/** Default value */
- public static final RestHook DEFAULT = create().value(HookEvent.INIT).build();
+ public static final RestPostCall DEFAULT = create().build();
/**
* Instantiates a new builder for this class.
@@ -58,35 +58,22 @@ public class RestHookAnnotation {
*/
public static class Builder extends TargetedAnnotationMBuilder {
- HookEvent value = HookEvent.INIT;
-
/**
* Constructor.
*/
protected Builder() {
- super(RestHook.class);
+ super(RestPostCall.class);
}
/**
- * Instantiates a new {@link RestHook @RestHook} object initialized with this builder.
+ * Instantiates a new {@link RestPostCall @RestPostCall} object initialized with this builder.
*
- * @return A new {@link RestHook @RestHook} object.
+ * @return A new {@link RestPostCall @RestPostCall} object.
*/
- public RestHook build() {
+ public RestPostCall build() {
return new Impl(this);
}
- /**
- * Sets the {@link RestHook#value()} property on this annotation.
- *
- * @param value The new value for this property.
- * @return This object.
- */
- public Builder value(HookEvent value) {
- this.value = value;
- return this;
- }
-
// <FluentSetters>
@Override /* GENERATED - TargetedAnnotationBuilder */
@@ -108,20 +95,12 @@ public class RestHookAnnotation {
// Implementation
//-----------------------------------------------------------------------------------------------------------------
- private static class Impl extends TargetedAnnotationImpl implements RestHook {
-
- private final HookEvent value;
+ private static class Impl extends TargetedAnnotationImpl implements RestPostCall {
Impl(Builder b) {
super(b);
- this.value = b.value;
postConstruct();
}
-
- @Override /* RestHook */
- public HookEvent value() {
- return value;
- }
}
//-----------------------------------------------------------------------------------------------------------------
@@ -129,7 +108,7 @@ public class RestHookAnnotation {
//-----------------------------------------------------------------------------------------------------------------
/**
- * A collection of {@link RestHook @RestHook annotations}.
+ * A collection of {@link RestPostCall @RestPostCall annotations}.
*/
@Documented
@Target({METHOD,TYPE})
@@ -142,6 +121,6 @@ public class RestHookAnnotation {
*
* @return The annotation value.
*/
- RestHook[] value();
+ RestPostCall[] value();
}
}
\ No newline at end of file
diff --git a/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/annotation/RestPostInit.java b/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/annotation/RestPostInit.java
new file mode 100644
index 000000000..7b13935e0
--- /dev/null
+++ b/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/annotation/RestPostInit.java
@@ -0,0 +1,95 @@
+// ***************************************************************************************************************************
+// * 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.annotation;
+
+import static java.lang.annotation.ElementType.*;
+import static java.lang.annotation.RetentionPolicy.*;
+
+import java.lang.annotation.*;
+
+import javax.servlet.*;
+
+import org.apache.juneau.rest.*;
+import org.apache.juneau.rest.servlet.*;
+
+/**
+ * Identifies a method that gets called immediately after servlet initialization.
+ *
+ * <p>
+ * This method is called from within the {@link Servlet#init(ServletConfig)} method after the {@link RestContext}
+ * object has been created.
+ *
+ * <p>
+ * The only valid parameter type for this method is {@link RestContext} which can be used to retrieve information
+ * about the servlet.
+ *
+ * <ul class='notes'>
+ * <li class='note'>
+ * The method should return <jk>void</jk> although if it does return any value, the value will be ignored.
+ * <li class='note'>
+ * The method should be <jk>public</jk> although other visibilities are valid if the security manager allows it.
+ * <li class='note'>
+ * Static methods can be used.
+ * <li class='note'>
+ * Multiple post-init methods can be defined on a class.
+ * <br>Post-init methods on parent classes are invoked before post-init methods on child classes unless {@link #childFirst()} is specified.
+ * <br>The order of Post-init method invocations within a class is alphabetical, then by parameter count, then by parameter types.
+ * <li class='note'>
+ * The method can throw any exception causing initialization of the servlet to fail.
+ * <li class='note'>
+ * Note that if you override a parent method, you probably need to call <code><jk>super</jk>.parentMethod(...)</code>.
+ * <br>The method is still considered part of the parent class for ordering purposes even though it's
+ * overridden by the child class.
+ * <li class='note'>
+ * The {@link RestServlet} class itself implements the following convenience methods annotated with this annotation
+ * that can be overridden directly:
+ * <ul class='javatree'>
+ * <li class='jac'>{@link RestServlet}
+ * <ul>
+ * <li class='jm'>{@link RestServlet#onPostInit(RestContext) onPostInit(RestContext)}
+ * <li class='jm'>{@link RestServlet#onPostInitChildFirst(RestContext) onPostInitChildFirst(RestContext)}
+ * </ul>
+ * </ul>
+ * </ul>
+ */
+@Target({METHOD,TYPE})
+@Retention(RUNTIME)
+@Inherited
+@Repeatable(RestPostInitAnnotation.Array.class)
+public @interface RestPostInit {
+
+ /**
+ * Execute in child-first order.
+ *
+ * <p>
+ * Use this annotation if you need to perform any kind of initialization on child resources before the parent resource.
+ *
+ * <p>
+ * This method is called from within the {@link Servlet#init(ServletConfig)} method after the {@link RestContext}
+ * object has been created and after the non-child-first methods have been called.
+ *
+ * @return The annotation value.
+ */
+ boolean childFirst() default false;
+
+ /**
+ * Dynamically apply this annotation to the specified methods.
+ *
+ * <ul class='seealso'>
+ * <li class='link'>{@doc jm.DynamicallyAppliedAnnotations}
+ * </ul>
+ *
+ * @return The annotation value.
+ */
+ String[] on() default {};
+}
diff --git a/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/annotation/RestHookAnnotation.java b/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/annotation/RestPostInitAnnotation.java
similarity index 83%
copy from juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/annotation/RestHookAnnotation.java
copy to juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/annotation/RestPostInitAnnotation.java
index d36ec77f4..3578744b2 100644
--- a/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/annotation/RestHookAnnotation.java
+++ b/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/annotation/RestPostInitAnnotation.java
@@ -20,21 +20,21 @@ import java.lang.annotation.*;
import org.apache.juneau.annotation.*;
/**
- * Utility classes and methods for the {@link RestHook @RestHook} annotation.
+ * Utility classes and methods for the {@link RestPostInit @RestPostInit} annotation.
*
* <ul class='seealso'>
* <li class='link'>{@doc jrs.LifecycleHooks}
* <li class='extlink'>{@source}
* </ul>
*/
-public class RestHookAnnotation {
+public class RestPostInitAnnotation {
//-----------------------------------------------------------------------------------------------------------------
// Static
//-----------------------------------------------------------------------------------------------------------------
/** Default value */
- public static final RestHook DEFAULT = create().value(HookEvent.INIT).build();
+ public static final RestPostInit DEFAULT = create().build();
/**
* Instantiates a new builder for this class.
@@ -58,32 +58,31 @@ public class RestHookAnnotation {
*/
public static class Builder extends TargetedAnnotationMBuilder {
- HookEvent value = HookEvent.INIT;
+ boolean childFirst;
/**
* Constructor.
*/
protected Builder() {
- super(RestHook.class);
+ super(RestPostInit.class);
}
/**
- * Instantiates a new {@link RestHook @RestHook} object initialized with this builder.
+ * Instantiates a new {@link RestPostInit @RestPostInit} object initialized with this builder.
*
- * @return A new {@link RestHook @RestHook} object.
+ * @return A new {@link RestPostInit @RestPostInit} object.
*/
- public RestHook build() {
+ public RestPostInit build() {
return new Impl(this);
}
/**
- * Sets the {@link RestHook#value()} property on this annotation.
+ * Sets the {@link RestPostInit#childFirst()} property on this annotation.
*
- * @param value The new value for this property.
* @return This object.
*/
- public Builder value(HookEvent value) {
- this.value = value;
+ public Builder childFirst() {
+ this.childFirst = true;
return this;
}
@@ -108,19 +107,19 @@ public class RestHookAnnotation {
// Implementation
//-----------------------------------------------------------------------------------------------------------------
- private static class Impl extends TargetedAnnotationImpl implements RestHook {
+ private static class Impl extends TargetedAnnotationImpl implements RestPostInit {
- private final HookEvent value;
+ private final boolean childFirst;
Impl(Builder b) {
super(b);
- this.value = b.value;
+ this.childFirst = b.childFirst;
postConstruct();
}
@Override /* RestHook */
- public HookEvent value() {
- return value;
+ public boolean childFirst() {
+ return childFirst;
}
}
@@ -129,7 +128,7 @@ public class RestHookAnnotation {
//-----------------------------------------------------------------------------------------------------------------
/**
- * A collection of {@link RestHook @RestHook annotations}.
+ * A collection of {@link RestPostInit @RestPostInit annotations}.
*/
@Documented
@Target({METHOD,TYPE})
@@ -142,6 +141,6 @@ public class RestHookAnnotation {
*
* @return The annotation value.
*/
- RestHook[] value();
+ RestPostInit[] value();
}
}
\ No newline at end of file
diff --git a/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/annotation/RestPreCall.java b/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/annotation/RestPreCall.java
new file mode 100644
index 000000000..68b7bbd46
--- /dev/null
+++ b/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/annotation/RestPreCall.java
@@ -0,0 +1,182 @@
+// ***************************************************************************************************************************
+// * 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.annotation;
+
+import static java.lang.annotation.ElementType.*;
+import static java.lang.annotation.RetentionPolicy.*;
+
+import java.io.*;
+import java.lang.annotation.*;
+import java.util.*;
+import java.util.logging.*;
+
+import javax.servlet.*;
+import javax.servlet.http.*;
+
+import org.apache.juneau.*;
+import org.apache.juneau.config.*;
+import org.apache.juneau.cp.*;
+import org.apache.juneau.http.header.*;
+import org.apache.juneau.http.response.*;
+import org.apache.juneau.rest.*;
+import org.apache.juneau.rest.guard.*;
+import org.apache.juneau.rest.httppart.*;
+import org.apache.juneau.rest.matcher.*;
+import org.apache.juneau.rest.servlet.*;
+
+/**
+ * Identifies a method that gets called immediately before the <ja>@RestOp</ja> annotated method gets called.
+ *
+ * <p>
+ * At this point, the {@link RestRequest} object has been fully initialized, and all {@link RestGuard} and
+ * {@link RestMatcher} objects have been called.
+ *
+ * <p>
+ * The list of valid parameter types are as follows:
+ * <ul>
+ * <li>Servlet request/response objects:
+ * <ul class='javatreec'>
+ * <li>{@link HttpServletRequest}
+ * <li>{@link HttpServletResponse}
+ * </ul>
+ * <li>Extended request/response objects:
+ * <ul class='javatreec'>
+ * <li>{@link RestRequest}
+ * <li>{@link RestResponse}
+ * </ul>
+ * <li>Header objects:
+ * <ul class='javatreec'>
+ * <li>{@link Accept}
+ * <li>{@link AcceptCharset}
+ * <li>{@link AcceptEncoding}
+ * <li>{@link AcceptLanguage}
+ * <li>{@link Authorization}
+ * <li>{@link CacheControl}
+ * <li>{@link Connection}
+ * <li>{@link ContentLength}
+ * <li>{@link ContentType}
+ * <li>{@link org.apache.juneau.http.header.Date}
+ * <li>{@link Expect}
+ * <li>{@link From}
+ * <li>{@link Host}
+ * <li>{@link IfMatch}
+ * <li>{@link IfModifiedSince}
+ * <li>{@link IfNoneMatch}
+ * <li>{@link IfRange}
+ * <li>{@link IfUnmodifiedSince}
+ * <li>{@link MaxForwards}
+ * <li>{@link Pragma}
+ * <li>{@link ProxyAuthorization}
+ * <li>{@link Range}
+ * <li>{@link Referer}
+ * <li>{@link TE}
+ * <li>{@link UserAgent}
+ * <li>{@link Upgrade}
+ * <li>{@link Via}
+ * <li>{@link Warning}
+ * <li>{@link TimeZone}
+ * </ul>
+ * <li>Other objects:
+ * <ul class='javatreec'>
+ * <li>{@link ResourceBundle}
+ * <li>{@link Messages}
+ * <li>{@link InputStream}
+ * <li>{@link ServletInputStream}
+ * <li>{@link Reader}
+ * <li>{@link OutputStream}
+ * <li>{@link ServletOutputStream}
+ * <li>{@link Writer}
+ * <li>{@link RequestHeaders}
+ * <li>{@link RequestQueryParams}
+ * <li>{@link RequestFormParams}
+ * <li>{@link RequestPathParams}
+ * <li>{@link Logger}
+ * <li>{@link RestContext}
+ * <li>{@link org.apache.juneau.parser.Parser}
+ * <li>{@link Locale}
+ * <li>{@link Swagger}
+ * <li>{@link RequestContent}
+ * <li>{@link Config}
+ * <li>{@link UriContext}
+ * <li>{@link UriResolver}
+ * </ul>
+ * </ul>
+ *
+ * <h5 class='figure'>Example:</h5>
+ * <p class='bjava'>
+ * <ja>@Rest</ja>(...)
+ * <jk>public class</jk> MyResource <jk>extends</jk> BasicRestServlet <jk>implements</jk> BasicUniversalConfig {
+ *
+ * <jc>// Log the incoming request.</jc>
+ * <ja>@RestPreCall</ja>
+ * <jk>public void</jk> onPreCall(Accept <jv>accept</jv>, Logger <jv>logger</jv>) {
+ * <jv>logger</jv>.fine(<js>"Accept {0} header found."</js>, <jv>accept</jv>);
+ * }
+ * }
+ * </p>
+ *
+ * <ul class='notes'>
+ * <li class='note'>
+ * The method should return <jk>void</jk> although if it does return any value, the value will be ignored.
+ * <li class='note'>
+ * The method should be <jk>public</jk> although other visibilities are valid if the security manager allows it.
+ * <li class='note'>
+ * Static methods can be used.
+ * <li class='note'>
+ * Multiple pre-call methods can be defined on a class.
+ * <br>Pre-call methods on parent classes are invoked before pre-call methods on child classes.
+ * <br>The order of pre-call method invocations within a class is alphabetical, then by parameter count, then by parameter types.
+ * <li class='note'>
+ * The method can throw any exception.
+ * <br>{@link BasicHttpException BasicHttpExceptions} can be thrown to cause a particular HTTP error status code.
+ * <br>All other exceptions cause an HTTP 500 error status code.
+ * <li class='note'>
+ * Note that if you override a parent method, you probably need to call <code><jk>super</jk>.parentMethod(...)</code>.
+ * <br>The method is still considered part of the parent class for ordering purposes even though it's
+ * overridden by the child class.
+ * <li class='note'>
+ * It's advisable not to mess around with the HTTP content itself since you may end up consuming the content
+ * before the actual REST method has a chance to use it.
+ * <li class='note'>
+ * The {@link RestServlet} class itself implements a convenience method annotated with this annotation
+ * that can be overridden directly:
+ * <ul class='javatree'>
+ * <li class='jac'>{@link RestServlet}
+ * <ul>
+ * <li class='jm'>{@link RestServlet#onPreCall(RestRequest,RestResponse) onPreCall(RestRequest,RestResponse)}
+ * </ul>
+ * </ul>
+ * </ul>
+ *
+ * <ul class='seealso'>
+ * <li class='link'>{@doc jrs.LifecycleHooks}
+ * <li class='extlink'>{@source}
+ * </ul>
+ */
+@Target({METHOD,TYPE})
+@Retention(RUNTIME)
+@Inherited
+@Repeatable(RestPreCallAnnotation.Array.class)
+public @interface RestPreCall {
+
+ /**
+ * Dynamically apply this annotation to the specified methods.
+ *
+ * <ul class='seealso'>
+ * <li class='link'>{@doc jm.DynamicallyAppliedAnnotations}
+ * </ul>
+ *
+ * @return The annotation value.
+ */
+ String[] on() default {};
+}
diff --git a/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/annotation/RestHookAnnotation.java b/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/annotation/RestPreCallAnnotation.java
similarity index 81%
copy from juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/annotation/RestHookAnnotation.java
copy to juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/annotation/RestPreCallAnnotation.java
index d36ec77f4..9dd9558ee 100644
--- a/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/annotation/RestHookAnnotation.java
+++ b/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/annotation/RestPreCallAnnotation.java
@@ -20,21 +20,21 @@ import java.lang.annotation.*;
import org.apache.juneau.annotation.*;
/**
- * Utility classes and methods for the {@link RestHook @RestHook} annotation.
+ * Utility classes and methods for the {@link RestPreCall @RestPreCall} annotation.
*
* <ul class='seealso'>
* <li class='link'>{@doc jrs.LifecycleHooks}
* <li class='extlink'>{@source}
* </ul>
*/
-public class RestHookAnnotation {
+public class RestPreCallAnnotation {
//-----------------------------------------------------------------------------------------------------------------
// Static
//-----------------------------------------------------------------------------------------------------------------
/** Default value */
- public static final RestHook DEFAULT = create().value(HookEvent.INIT).build();
+ public static final RestPreCall DEFAULT = create().build();
/**
* Instantiates a new builder for this class.
@@ -58,35 +58,22 @@ public class RestHookAnnotation {
*/
public static class Builder extends TargetedAnnotationMBuilder {
- HookEvent value = HookEvent.INIT;
-
/**
* Constructor.
*/
protected Builder() {
- super(RestHook.class);
+ super(RestPreCall.class);
}
/**
- * Instantiates a new {@link RestHook @RestHook} object initialized with this builder.
+ * Instantiates a new {@link RestPreCall @RestPreCall} object initialized with this builder.
*
- * @return A new {@link RestHook @RestHook} object.
+ * @return A new {@link RestPreCall @RestPreCall} object.
*/
- public RestHook build() {
+ public RestPreCall build() {
return new Impl(this);
}
- /**
- * Sets the {@link RestHook#value()} property on this annotation.
- *
- * @param value The new value for this property.
- * @return This object.
- */
- public Builder value(HookEvent value) {
- this.value = value;
- return this;
- }
-
// <FluentSetters>
@Override /* GENERATED - TargetedAnnotationBuilder */
@@ -108,20 +95,12 @@ public class RestHookAnnotation {
// Implementation
//-----------------------------------------------------------------------------------------------------------------
- private static class Impl extends TargetedAnnotationImpl implements RestHook {
-
- private final HookEvent value;
+ private static class Impl extends TargetedAnnotationImpl implements RestPreCall {
Impl(Builder b) {
super(b);
- this.value = b.value;
postConstruct();
}
-
- @Override /* RestHook */
- public HookEvent value() {
- return value;
- }
}
//-----------------------------------------------------------------------------------------------------------------
@@ -129,7 +108,7 @@ public class RestHookAnnotation {
//-----------------------------------------------------------------------------------------------------------------
/**
- * A collection of {@link RestHook @RestHook annotations}.
+ * A collection of {@link RestPreCall @RestPreCall annotations}.
*/
@Documented
@Target({METHOD,TYPE})
@@ -142,6 +121,6 @@ public class RestHookAnnotation {
*
* @return The annotation value.
*/
- RestHook[] value();
+ RestPreCall[] value();
}
}
\ No newline at end of file
diff --git a/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/annotation/RestStartCall.java b/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/annotation/RestStartCall.java
new file mode 100644
index 000000000..632237d21
--- /dev/null
+++ b/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/annotation/RestStartCall.java
@@ -0,0 +1,106 @@
+// ***************************************************************************************************************************
+// * 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.annotation;
+
+import static java.lang.annotation.ElementType.*;
+import static java.lang.annotation.RetentionPolicy.*;
+
+import java.lang.annotation.*;
+
+import javax.servlet.http.*;
+
+import org.apache.juneau.http.response.*;
+import org.apache.juneau.rest.servlet.*;
+
+/**
+ * Identifies a method that is called immediately after the <c>HttpServlet.service(HttpServletRequest, HttpServletResponse)</c>
+ * method is called.
+ *
+ * <p>
+ * Note that you only have access to the raw request and response objects at this point.
+ *
+ * <p>
+ * The list of valid parameter types are as follows:
+ * <ul>
+ * <li>Servlet request/response objects:
+ * <ul>
+ * <li>{@link HttpServletRequest}
+ * <li>{@link HttpServletResponse}
+ * </ul>
+ * </ul>
+ *
+ * <h5 class='figure'>Example:</h5>
+ * <p class='bjava'>
+ * <ja>@Rest</ja>(...)
+ * <jk>public class</jk> MyResource <jk>extends</jk> BasicRestServlet <jk>implements</jk> BasicUniversalConfig {
+ *
+ * <jc>// Add a request attribute to all incoming requests.</jc>
+ * <ja>@RestStartCall</ja>
+ * <jk>public void</jk> onStartCall(HttpServletRequest <jv>req</jv>) {
+ * <jv>req</jv>.setAttribute(<js>"foobar"</js>, <jk>new</jk> FooBar());
+ * }
+ * }
+ * </p>
+ *
+ * <ul class='notes'>
+ * <li class='note'>
+ * The method should return <jk>void</jk> although if it does return any value, the value will be ignored.
+ * <li class='note'>
+ * The method should be <jk>public</jk> although other visibilities are valid if the security manager allows it.
+ * <li class='note'>
+ * Static methods can be used.
+ * <li class='note'>
+ * Multiple start-call methods can be defined on a class.
+ * <br>Start call methods on parent classes are invoked before start-call methods on child classes.
+ * <br>The order of start-call method invocations within a class is alphabetical, then by parameter count, then by parameter types.
+ * <li class='note'>
+ * The method can throw any exception.
+ * <br>{@link BasicHttpException BasicHttpExceptions} can be thrown to cause a particular HTTP error status code.
+ * <br>All other exceptions cause an HTTP 500 error status code.
+ * <li class='note'>
+ * Note that if you override a parent method, you probably need to call <code><jk>super</jk>.parentMethod(...)</code>.
+ * <br>The method is still considered part of the parent class for ordering purposes even though it's
+ * overridden by the child class.
+ * <li class='note'>
+ * The {@link RestServlet} class itself implements a convenience method annotated with this annotation
+ * that can be overridden directly:
+ * <ul class='javatree'>
+ * <li class='jac'>{@link RestServlet}
+ * <ul>
+ * <li class='jm'>{@link RestServlet#onStartCall(HttpServletRequest,HttpServletResponse) onStartCall(HttpServletRequest,HttpServletResponse)}
+ * </ul>
+ * </ul>
+ * </ul>
+ *
+ * <ul class='seealso'>
+ * <li class='link'>{@doc jrs.LifecycleHooks}
+ * <li class='extlink'>{@source}
+ * </ul>
+ */
+@Target({METHOD,TYPE})
+@Retention(RUNTIME)
+@Inherited
+@Repeatable(RestStartCallAnnotation.Array.class)
+public @interface RestStartCall {
+
+ /**
+ * Dynamically apply this annotation to the specified methods.
+ *
+ * <ul class='seealso'>
+ * <li class='link'>{@doc jm.DynamicallyAppliedAnnotations}
+ * </ul>
+ *
+ * @return The annotation value.
+ */
+ String[] on() default {};
+}
diff --git a/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/annotation/RestHookAnnotation.java b/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/annotation/RestStartCallAnnotation.java
similarity index 81%
rename from juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/annotation/RestHookAnnotation.java
rename to juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/annotation/RestStartCallAnnotation.java
index d36ec77f4..0388ce421 100644
--- a/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/annotation/RestHookAnnotation.java
+++ b/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/annotation/RestStartCallAnnotation.java
@@ -20,21 +20,21 @@ import java.lang.annotation.*;
import org.apache.juneau.annotation.*;
/**
- * Utility classes and methods for the {@link RestHook @RestHook} annotation.
+ * Utility classes and methods for the {@link RestStartCall @RestStartCall} annotation.
*
* <ul class='seealso'>
* <li class='link'>{@doc jrs.LifecycleHooks}
* <li class='extlink'>{@source}
* </ul>
*/
-public class RestHookAnnotation {
+public class RestStartCallAnnotation {
//-----------------------------------------------------------------------------------------------------------------
// Static
//-----------------------------------------------------------------------------------------------------------------
/** Default value */
- public static final RestHook DEFAULT = create().value(HookEvent.INIT).build();
+ public static final RestStartCall DEFAULT = create().build();
/**
* Instantiates a new builder for this class.
@@ -58,35 +58,22 @@ public class RestHookAnnotation {
*/
public static class Builder extends TargetedAnnotationMBuilder {
- HookEvent value = HookEvent.INIT;
-
/**
* Constructor.
*/
protected Builder() {
- super(RestHook.class);
+ super(RestStartCall.class);
}
/**
- * Instantiates a new {@link RestHook @RestHook} object initialized with this builder.
+ * Instantiates a new {@link RestStartCall @RestStartCall} object initialized with this builder.
*
- * @return A new {@link RestHook @RestHook} object.
+ * @return A new {@link RestStartCall @RestStartCall} object.
*/
- public RestHook build() {
+ public RestStartCall build() {
return new Impl(this);
}
- /**
- * Sets the {@link RestHook#value()} property on this annotation.
- *
- * @param value The new value for this property.
- * @return This object.
- */
- public Builder value(HookEvent value) {
- this.value = value;
- return this;
- }
-
// <FluentSetters>
@Override /* GENERATED - TargetedAnnotationBuilder */
@@ -108,20 +95,12 @@ public class RestHookAnnotation {
// Implementation
//-----------------------------------------------------------------------------------------------------------------
- private static class Impl extends TargetedAnnotationImpl implements RestHook {
-
- private final HookEvent value;
+ private static class Impl extends TargetedAnnotationImpl implements RestStartCall {
Impl(Builder b) {
super(b);
- this.value = b.value;
postConstruct();
}
-
- @Override /* RestHook */
- public HookEvent value() {
- return value;
- }
}
//-----------------------------------------------------------------------------------------------------------------
@@ -129,7 +108,7 @@ public class RestHookAnnotation {
//-----------------------------------------------------------------------------------------------------------------
/**
- * A collection of {@link RestHook @RestHook annotations}.
+ * A collection of {@link RestStartCall @RestStartCall annotations}.
*/
@Documented
@Target({METHOD,TYPE})
@@ -142,6 +121,6 @@ public class RestHookAnnotation {
*
* @return The annotation value.
*/
- RestHook[] value();
+ RestStartCall[] value();
}
}
\ No newline at end of file
diff --git a/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/arg/DefaultArg.java b/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/arg/DefaultArg.java
index 5f840dac1..dcb53dc6b 100644
--- a/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/arg/DefaultArg.java
+++ b/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/arg/DefaultArg.java
@@ -79,7 +79,6 @@ public class DefaultArg implements RestOpArg {
@Override /* RestOpArg */
public Object resolve(RestOpSession opSession) throws Exception {
- System.err.println("beanStore2" + opSession.getBeanStore());
return opSession.getBeanStore().getBean(type, name).orElseThrow(()->new ArgException(paramInfo, "Could not resolve bean type {0}", type.getName()));
}
}
diff --git a/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/servlet/RestObject.java b/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/servlet/RestObject.java
index 94a2c29e4..d258fef20 100644
--- a/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/servlet/RestObject.java
+++ b/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/servlet/RestObject.java
@@ -13,7 +13,6 @@
package org.apache.juneau.rest.servlet;
import static org.apache.juneau.internal.ClassUtils.*;
-import static org.apache.juneau.rest.annotation.HookEvent.*;
import java.text.*;
import java.util.concurrent.atomic.*;
@@ -187,9 +186,9 @@ public abstract class RestObject {
* <li class='note'>
* The default implementation of this method is a no-op.
* <li class='note'>
- * Multiple INIT methods can be defined on a class.
- * <br>INIT methods on parent classes are invoked before INIT methods on child classes.
- * <br>The order of INIT method invocations within a class is alphabetical, then by parameter count, then by parameter types.
+ * Multiple init methods can be defined on a class.
+ * <br>Init methods on parent classes are invoked before init methods on child classes.
+ * <br>The order of init method invocations within a class is alphabetical, then by parameter count, then by parameter types.
* <li class='note'>
* The method can throw any exception causing initialization of the servlet to fail.
* </ul>
@@ -197,7 +196,7 @@ public abstract class RestObject {
* @param builder Context builder which can be used to configure the servlet.
* @throws Exception Any exception thrown will cause servlet to fail startup.
*/
- @RestHook(INIT)
+ @RestInit
public void onInit(RestContext.Builder builder) throws Exception {}
/**
@@ -211,9 +210,9 @@ public abstract class RestObject {
* <li class='note'>
* The default implementation of this method is a no-op.
* <li class='note'>
- * Multiple POST_INIT methods can be defined on a class.
- * <br>POST_INIT methods on parent classes are invoked before POST_INIT methods on child classes.
- * <br>The order of POST_INIT method invocations within a class is alphabetical, then by parameter count, then by parameter types.
+ * Multiple post-init methods can be defined on a class.
+ * <br>Post-init methods on parent classes are invoked before post-init methods on child classes.
+ * <br>The order of post-init method invocations within a class is alphabetical, then by parameter count, then by parameter types.
* <li class='note'>
* The method can throw any exception causing initialization of the servlet to fail.
* </ul>
@@ -221,7 +220,7 @@ public abstract class RestObject {
* @param context The initialized context object.
* @throws Exception Any exception thrown will cause servlet to fail startup.
*/
- @RestHook(POST_INIT)
+ @RestPostInit
public void onPostInit(RestContext context) throws Exception {}
/**
@@ -232,7 +231,7 @@ public abstract class RestObject {
*
* <p>
* This method is called from within the {@link Servlet#init(ServletConfig)} method after the {@link RestContext}
- * object has been created and after the {@link HookEvent#POST_INIT} methods have been called.
+ * object has been created and after the child-last {@link RestPostInit} methods have been called.
*
* <p>
* The only valid parameter type for this method is {@link RestContext} which can be used to retrieve information
@@ -242,9 +241,9 @@ public abstract class RestObject {
* <li class='note'>
* The default implementation of this method is a no-op.
* <li class='note'>
- * Multiple POST_INIT_CHILD_FIRST methods can be defined on a class.
- * <br>POST_INIT_CHILD_FIRST methods on parent classes are invoked before POST_INIT_CHILD_FIRST methods on child classes.
- * <br>The order of POST_INIT_CHILD_FIRST method invocations within a class is alphabetical, then by parameter count, then by parameter types.
+ * Multiple post-init methods can be defined on a class.
+ * <br>Post-init methods on parent classes are invoked before post-init methods on child classes.
+ * <br>The order of post-init method invocations within a class is alphabetical, then by parameter count, then by parameter types.
* <li class='note'>
* The method can throw any exception causing initialization of the servlet to fail.
* </ul>
@@ -252,7 +251,7 @@ public abstract class RestObject {
* @param context The initialized context object.
* @throws Exception Any exception thrown will cause servlet to fail startup.
*/
- @RestHook(POST_INIT_CHILD_FIRST)
+ @RestPostInit(childFirst=true)
public void onPostInitChildFirst(RestContext context) throws Exception {}
/**
@@ -280,9 +279,9 @@ public abstract class RestObject {
* <li class='note'>
* The default implementation of this method is a no-op.
* <li class='note'>
- * Multiple DESTROY methods can be defined on a class.
- * <br>DESTROY methods on child classes are invoked before DESTROY methods on parent classes.
- * <br>The order of DESTROY method invocations within a class is alphabetical, then by parameter count, then by parameter types.
+ * Multiple destroy methods can be defined on a class.
+ * <br>Destroy methods on child classes are invoked before destroy methods on parent classes.
+ * <br>The order of destroy method invocations within a class is alphabetical, then by parameter count, then by parameter types.
* <li class='note'>
* In general, destroy methods should not throw any exceptions, although if any are thrown, the stack trace will be
* printed to <c>System.err</c>.
@@ -291,7 +290,7 @@ public abstract class RestObject {
* @param context The initialized context object.
* @throws Exception Any exception thrown will cause stack trace to be printed to <c>System.err</c>.
*/
- @RestHook(DESTROY)
+ @RestDestroy
public void onDestroy(RestContext context) throws Exception {}
/**
@@ -318,9 +317,9 @@ public abstract class RestObject {
* <li class='note'>
* The default implementation of this method is a no-op.
* <li class='note'>
- * Multiple START_CALL methods can be defined on a class.
- * <br>START_CALL methods on parent classes are invoked before START_CALL methods on child classes.
- * <br>The order of START_CALL method invocations within a class is alphabetical, then by parameter count, then by parameter types.
+ * Multiple start-call methods can be defined on a class.
+ * <br>start-call methods on parent classes are invoked before start-call methods on child classes.
+ * <br>The order of start-call method invocations within a class is alphabetical, then by parameter count, then by parameter types.
* <li class='note'>
* The method can throw any exception.
* <br>{@link BasicHttpException HttpExceptions} can be thrown to cause a particular HTTP error status code.
@@ -331,7 +330,7 @@ public abstract class RestObject {
* @param res The HTTP servlet response object.
* @throws Exception Any exception.
*/
- @RestHook(START_CALL)
+ @RestStartCall
public void onStartCall(HttpServletRequest req, HttpServletResponse res) throws Exception {}
/**
@@ -345,9 +344,9 @@ public abstract class RestObject {
* <li class='note'>
* The default implementation of this method is a no-op.
* <li class='note'>
- * Multiple PRE_CALL methods can be defined on a class.
- * <br>PRE_CALL methods on parent classes are invoked before PRE_CALL methods on child classes.
- * <br>The order of PRE_CALL method invocations within a class is alphabetical, then by parameter count, then by parameter types.
+ * Multiple pre-call methods can be defined on a class.
+ * <br>Pre-call methods on parent classes are invoked before pre-call methods on child classes.
+ * <br>The order of pre-call method invocations within a class is alphabetical, then by parameter count, then by parameter types.
* <li class='note'>
* The method can throw any exception.
* <br>{@link BasicHttpException HttpExceptions} can be thrown to cause a particular HTTP error status code.
@@ -361,7 +360,7 @@ public abstract class RestObject {
* @param res The response object.
* @throws Exception Any exception.
*/
- @RestHook(PRE_CALL)
+ @RestPreCall
public void onPreCall(RestRequest req, RestResponse res) throws Exception {}
/**
@@ -375,9 +374,9 @@ public abstract class RestObject {
* <li class='note'>
* The default implementation of this method is a no-op.
* <li class='note'>
- * Multiple POST_CALL methods can be defined on a class.
- * <br>POST_CALL methods on parent classes are invoked before POST_CALL methods on child classes.
- * <br>The order of POST_CALL method invocations within a class is alphabetical, then by parameter count, then by parameter types.
+ * Multiple post-call methods can be defined on a class.
+ * <br>post-call methods on parent classes are invoked before post-call methods on child classes.
+ * <br>The order of post-call method invocations within a class is alphabetical, then by parameter count, then by parameter types.
* <li class='note'>
* The method can throw any exception, although at this point it is too late to set an HTTP error status code.
* </ul>
@@ -386,7 +385,7 @@ public abstract class RestObject {
* @param res The response object.
* @throws Exception Any exception.
*/
- @RestHook(POST_CALL)
+ @RestPostCall
public void onPostCall(RestRequest req, RestResponse res) throws Exception {}
/**
@@ -406,9 +405,9 @@ public abstract class RestObject {
* <li class='note'>
* The default implementation of this method is a no-op.
* <li class='note'>
- * Multiple END_CALL methods can be defined on a class.
- * <br>END_CALL methods on parent classes are invoked before END_CALL methods on child classes.
- * <br>The order of END_CALL method invocations within a class is alphabetical, then by parameter count, then by parameter types.
+ * Multiple end-call methods can be defined on a class.
+ * <br>end-call methods on parent classes are invoked before end-call methods on child classes.
+ * <br>The order of end-call method invocations within a class is alphabetical, then by parameter count, then by parameter types.
* <li class='note'>
* The method can throw any exception, although at this point it is too late to set an HTTP error status code.
* <li class='note'>
@@ -421,7 +420,7 @@ public abstract class RestObject {
* @param res The HTTP servlet response object.
* @throws Exception Any exception.
*/
- @RestHook(END_CALL)
+ @RestEndCall
public void onEndCall(HttpServletRequest req, HttpServletResponse res) throws Exception {}
//-----------------------------------------------------------------------------------------------------------------
diff --git a/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/servlet/RestServlet.java b/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/servlet/RestServlet.java
index a37cceb22..d1d6dfcde 100644
--- a/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/servlet/RestServlet.java
+++ b/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/servlet/RestServlet.java
@@ -17,7 +17,6 @@ import static javax.servlet.http.HttpServletResponse.*;
import static org.apache.juneau.internal.ClassUtils.*;
import static org.apache.juneau.internal.StringUtils.*;
import static org.apache.juneau.rest.HttpRuntimeException.*;
-import static org.apache.juneau.rest.annotation.HookEvent.*;
import java.io.*;
import java.text.*;
@@ -314,9 +313,9 @@ public abstract class RestServlet extends HttpServlet {
* <li class='note'>
* The default implementation of this method is a no-op.
* <li>
- * Multiple INIT methods can be defined on a class.
- * <br>INIT methods on parent classes are invoked before INIT methods on child classes.
- * <br>The order of INIT method invocations within a class is alphabetical, then by parameter count, then by parameter types.
+ * Multiple init methods can be defined on a class.
+ * <br>Init methods on parent classes are invoked before init methods on child classes.
+ * <br>The order of init method invocations within a class is alphabetical, then by parameter count, then by parameter types.
* <li>
* The method can throw any exception causing initialization of the servlet to fail.
* </ul>
@@ -324,7 +323,7 @@ public abstract class RestServlet extends HttpServlet {
* @param builder Context builder which can be used to configure the servlet.
* @throws Exception Any exception thrown will cause servlet to fail startup.
*/
- @RestHook(INIT)
+ @RestInit
public void onInit(RestContext.Builder builder) throws Exception {}
/**
@@ -338,9 +337,9 @@ public abstract class RestServlet extends HttpServlet {
* <li class='note'>
* The default implementation of this method is a no-op.
* <li class='note'>
- * Multiple POST_INIT methods can be defined on a class.
- * <br>POST_INIT methods on parent classes are invoked before POST_INIT methods on child classes.
- * <br>The order of POST_INIT method invocations within a class is alphabetical, then by parameter count, then by parameter types.
+ * Multiple post-init methods can be defined on a class.
+ * <br>post-init methods on parent classes are invoked before post-init methods on child classes.
+ * <br>The order of post-init method invocations within a class is alphabetical, then by parameter count, then by parameter types.
* <li class='note'>
* The method can throw any exception causing initialization of the servlet to fail.
* </ul>
@@ -348,7 +347,7 @@ public abstract class RestServlet extends HttpServlet {
* @param context The initialized context object.
* @throws Exception Any exception thrown will cause servlet to fail startup.
*/
- @RestHook(POST_INIT)
+ @RestPostInit
public void onPostInit(RestContext context) throws Exception {}
/**
@@ -359,7 +358,7 @@ public abstract class RestServlet extends HttpServlet {
*
* <p>
* This method is called from within the {@link Servlet#init(ServletConfig)} method after the {@link RestContext}
- * object has been created and after the {@link HookEvent#POST_INIT} methods have been called.
+ * object has been created and after the child-last {@link RestPostInit} methods have been called.
*
* <p>
* The only valid parameter type for this method is {@link RestContext} which can be used to retrieve information
@@ -379,7 +378,7 @@ public abstract class RestServlet extends HttpServlet {
* @param context The initialized context object.
* @throws Exception Any exception thrown will cause servlet to fail startup.
*/
- @RestHook(POST_INIT_CHILD_FIRST)
+ @RestPostInit(childFirst=true)
public void onPostInitChildFirst(RestContext context) throws Exception {}
/**
@@ -407,9 +406,9 @@ public abstract class RestServlet extends HttpServlet {
* <li class='note'>
* The default implementation of this method is a no-op.
* <li class='note'>
- * Multiple DESTROY methods can be defined on a class.
- * <br>DESTROY methods on child classes are invoked before DESTROY methods on parent classes.
- * <br>The order of DESTROY method invocations within a class is alphabetical, then by parameter count, then by parameter types.
+ * Multiple destroy methods can be defined on a class.
+ * <br>Destroy methods on child classes are invoked before destroy methods on parent classes.
+ * <br>The order of destroy method invocations within a class is alphabetical, then by parameter count, then by parameter types.
* <li class='note'>
* In general, destroy methods should not throw any exceptions, although if any are thrown, the stack trace will be
* printed to <c>System.err</c>.
@@ -418,7 +417,7 @@ public abstract class RestServlet extends HttpServlet {
* @param context The initialized context object.
* @throws Exception Any exception thrown will cause stack trace to be printed to <c>System.err</c>.
*/
- @RestHook(DESTROY)
+ @RestDestroy
public void onDestroy(RestContext context) throws Exception {}
/**
@@ -445,9 +444,9 @@ public abstract class RestServlet extends HttpServlet {
* <li class='note'>
* The default implementation of this method is a no-op.
* <li class='note'>
- * Multiple START_CALL methods can be defined on a class.
- * <br>START_CALL methods on parent classes are invoked before START_CALL methods on child classes.
- * <br>The order of START_CALL method invocations within a class is alphabetical, then by parameter count, then by parameter types.
+ * Multiple start-call methods can be defined on a class.
+ * <br>Start-call methods on parent classes are invoked before start-call methods on child classes.
+ * <br>The order of start-call method invocations within a class is alphabetical, then by parameter count, then by parameter types.
* <li class='note'>
* The method can throw any exception.
* <br>{@link BasicHttpException HttpExceptions} can be thrown to cause a particular HTTP error status code.
@@ -458,7 +457,7 @@ public abstract class RestServlet extends HttpServlet {
* @param res The HTTP servlet response object.
* @throws Exception Any exception.
*/
- @RestHook(START_CALL)
+ @RestStartCall
public void onStartCall(HttpServletRequest req, HttpServletResponse res) throws Exception {}
/**
@@ -472,9 +471,9 @@ public abstract class RestServlet extends HttpServlet {
* <li class='note'>
* The default implementation of this method is a no-op.
* <li class='note'>
- * Multiple PRE_CALL methods can be defined on a class.
- * <br>PRE_CALL methods on parent classes are invoked before PRE_CALL methods on child classes.
- * <br>The order of PRE_CALL method invocations within a class is alphabetical, then by parameter count, then by parameter types.
+ * Multiple pre-call methods can be defined on a class.
+ * <br>Pre-call methods on parent classes are invoked before pre-call methods on child classes.
+ * <br>The order of pre-call method invocations within a class is alphabetical, then by parameter count, then by parameter types.
* <li class='note'>
* The method can throw any exception.
* <br>{@link BasicHttpException HttpExceptions} can be thrown to cause a particular HTTP error status code.
@@ -488,7 +487,7 @@ public abstract class RestServlet extends HttpServlet {
* @param res The response object.
* @throws Exception Any exception.
*/
- @RestHook(PRE_CALL)
+ @RestPreCall
public void onPreCall(RestRequest req, RestResponse res) throws Exception {}
/**
@@ -502,9 +501,9 @@ public abstract class RestServlet extends HttpServlet {
* <li class='note'>
* The default implementation of this method is a no-op.
* <li class='note'>
- * Multiple POST_CALL methods can be defined on a class.
- * <br>POST_CALL methods on parent classes are invoked before POST_CALL methods on child classes.
- * <br>The order of POST_CALL method invocations within a class is alphabetical, then by parameter count, then by parameter types.
+ * Multiple post-call methods can be defined on a class.
+ * <br>Post-call methods on parent classes are invoked before post-call methods on child classes.
+ * <br>The order of post-call method invocations within a class is alphabetical, then by parameter count, then by parameter types.
* <li class='note'>
* The method can throw any exception, although at this point it is too late to set an HTTP error status code.
* </ul>
@@ -513,7 +512,7 @@ public abstract class RestServlet extends HttpServlet {
* @param res The response object.
* @throws Exception Any exception.
*/
- @RestHook(POST_CALL)
+ @RestPostCall
public void onPostCall(RestRequest req, RestResponse res) throws Exception {}
/**
@@ -533,9 +532,9 @@ public abstract class RestServlet extends HttpServlet {
* <li class='note'>
* The default implementation of this method is a no-op.
* <li class='note'>
- * Multiple END_CALL methods can be defined on a class.
- * <br>END_CALL methods on parent classes are invoked before END_CALL methods on child classes.
- * <br>The order of END_CALL method invocations within a class is alphabetical, then by parameter count, then by parameter types.
+ * Multiple end-call methods can be defined on a class.
+ * <br>End-call methods on parent classes are invoked before end-call methods on child classes.
+ * <br>The order of end-call method invocations within a class is alphabetical, then by parameter count, then by parameter types.
* <li class='note'>
* The method can throw any exception, although at this point it is too late to set an HTTP error status code.
* <li class='note'>
@@ -548,7 +547,7 @@ public abstract class RestServlet extends HttpServlet {
* @param res The HTTP servlet response object.
* @throws Exception Any exception.
*/
- @RestHook(END_CALL)
+ @RestEndCall
public void onEndCall(HttpServletRequest req, HttpServletResponse res) throws Exception {}
//-----------------------------------------------------------------------------------------------------------------
diff --git a/juneau-utest/src/test/java/org/apache/juneau/rest/annotation/RestHookAnnotation_Test.java b/juneau-utest/src/test/java/org/apache/juneau/rest/annotation/RestDestroyAnnotation_Test.java
similarity index 86%
copy from juneau-utest/src/test/java/org/apache/juneau/rest/annotation/RestHookAnnotation_Test.java
copy to juneau-utest/src/test/java/org/apache/juneau/rest/annotation/RestDestroyAnnotation_Test.java
index 291c26cc3..fd640c3a0 100644
--- a/juneau-utest/src/test/java/org/apache/juneau/rest/annotation/RestHookAnnotation_Test.java
+++ b/juneau-utest/src/test/java/org/apache/juneau/rest/annotation/RestDestroyAnnotation_Test.java
@@ -20,30 +20,27 @@ import org.apache.juneau.*;
import org.junit.*;
@FixMethodOrder(NAME_ASCENDING)
-public class RestHookAnnotation_Test {
+public class RestDestroyAnnotation_Test {
- private static final String CNAME = RestHookAnnotation_Test.class.getName();
+ private static final String CNAME = RestDestroyAnnotation_Test.class.getName();
//------------------------------------------------------------------------------------------------------------------
// Basic tests
//------------------------------------------------------------------------------------------------------------------
- RestHook a1 = RestHookAnnotation.create()
+ RestDestroy a1 = RestDestroyAnnotation.create()
.on("a")
- .value(HookEvent.INIT)
.build();
- RestHook a2 = RestHookAnnotation.create()
+ RestDestroy a2 = RestDestroyAnnotation.create()
.on("a")
- .value(HookEvent.INIT)
.build();
@Test
public void a01_basic() {
assertObject(a1).asJson().is(""
+ "{"
- + "on:['a'],"
- + "value:'INIT'"
+ + "on:['a']"
+ "}"
);
}
@@ -80,7 +77,7 @@ public class RestHookAnnotation_Test {
@Test
public void c01_otherMethods() throws Exception {
- RestHook c4 = RestHookAnnotation.create().on(C1.class.getMethod("m1")).on(C2.class.getMethod("m2")).build();
+ RestDestroy c4 = RestDestroyAnnotation.create().on(C1.class.getMethod("m1")).on(C2.class.getMethod("m2")).build();
assertObject(c4).asJson().isContains("on:['"+CNAME+"$C1.m1()','"+CNAME+"$C2.m2()']");
}
@@ -89,19 +86,17 @@ public class RestHookAnnotation_Test {
// Comparison with declared annotations.
//------------------------------------------------------------------------------------------------------------------
- @RestHook(
- on="a",
- value=HookEvent.INIT
+ @RestDestroy(
+ on="a"
)
public static class D1 {}
- RestHook d1 = D1.class.getAnnotationsByType(RestHook.class)[0];
+ RestDestroy d1 = D1.class.getAnnotationsByType(RestDestroy.class)[0];
- @RestHook(
- on="a",
- value=HookEvent.INIT
+ @RestDestroy(
+ on="a"
)
public static class D2 {}
- RestHook d2 = D2.class.getAnnotationsByType(RestHook.class)[0];
+ RestDestroy d2 = D2.class.getAnnotationsByType(RestDestroy.class)[0];
@Test
public void d01_comparisonWithDeclarativeAnnotations() {
diff --git a/juneau-utest/src/test/java/org/apache/juneau/rest/annotation/RestHookAnnotation_Test.java b/juneau-utest/src/test/java/org/apache/juneau/rest/annotation/RestEndCallAnnotation_Test.java
similarity index 86%
copy from juneau-utest/src/test/java/org/apache/juneau/rest/annotation/RestHookAnnotation_Test.java
copy to juneau-utest/src/test/java/org/apache/juneau/rest/annotation/RestEndCallAnnotation_Test.java
index 291c26cc3..55a189f29 100644
--- a/juneau-utest/src/test/java/org/apache/juneau/rest/annotation/RestHookAnnotation_Test.java
+++ b/juneau-utest/src/test/java/org/apache/juneau/rest/annotation/RestEndCallAnnotation_Test.java
@@ -20,30 +20,27 @@ import org.apache.juneau.*;
import org.junit.*;
@FixMethodOrder(NAME_ASCENDING)
-public class RestHookAnnotation_Test {
+public class RestEndCallAnnotation_Test {
- private static final String CNAME = RestHookAnnotation_Test.class.getName();
+ private static final String CNAME = RestEndCallAnnotation_Test.class.getName();
//------------------------------------------------------------------------------------------------------------------
// Basic tests
//------------------------------------------------------------------------------------------------------------------
- RestHook a1 = RestHookAnnotation.create()
+ RestEndCall a1 = RestEndCallAnnotation.create()
.on("a")
- .value(HookEvent.INIT)
.build();
- RestHook a2 = RestHookAnnotation.create()
+ RestEndCall a2 = RestEndCallAnnotation.create()
.on("a")
- .value(HookEvent.INIT)
.build();
@Test
public void a01_basic() {
assertObject(a1).asJson().is(""
+ "{"
- + "on:['a'],"
- + "value:'INIT'"
+ + "on:['a']"
+ "}"
);
}
@@ -80,7 +77,7 @@ public class RestHookAnnotation_Test {
@Test
public void c01_otherMethods() throws Exception {
- RestHook c4 = RestHookAnnotation.create().on(C1.class.getMethod("m1")).on(C2.class.getMethod("m2")).build();
+ RestEndCall c4 = RestEndCallAnnotation.create().on(C1.class.getMethod("m1")).on(C2.class.getMethod("m2")).build();
assertObject(c4).asJson().isContains("on:['"+CNAME+"$C1.m1()','"+CNAME+"$C2.m2()']");
}
@@ -89,19 +86,17 @@ public class RestHookAnnotation_Test {
// Comparison with declared annotations.
//------------------------------------------------------------------------------------------------------------------
- @RestHook(
- on="a",
- value=HookEvent.INIT
+ @RestEndCall(
+ on="a"
)
public static class D1 {}
- RestHook d1 = D1.class.getAnnotationsByType(RestHook.class)[0];
+ RestEndCall d1 = D1.class.getAnnotationsByType(RestEndCall.class)[0];
- @RestHook(
- on="a",
- value=HookEvent.INIT
+ @RestEndCall(
+ on="a"
)
public static class D2 {}
- RestHook d2 = D2.class.getAnnotationsByType(RestHook.class)[0];
+ RestEndCall d2 = D2.class.getAnnotationsByType(RestEndCall.class)[0];
@Test
public void d01_comparisonWithDeclarativeAnnotations() {
diff --git a/juneau-utest/src/test/java/org/apache/juneau/rest/annotation/RestHook_Test.java b/juneau-utest/src/test/java/org/apache/juneau/rest/annotation/RestHook_Test.java
deleted file mode 100644
index 1f8ea5420..000000000
--- a/juneau-utest/src/test/java/org/apache/juneau/rest/annotation/RestHook_Test.java
+++ /dev/null
@@ -1,603 +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.annotation;
-
-import static org.apache.juneau.internal.CollectionUtils.*;
-import static org.apache.juneau.rest.annotation.HookEvent.*;
-import static org.junit.runners.MethodSorters.*;
-import static java.util.Collections.*;
-
-import java.util.*;
-
-import javax.servlet.*;
-import javax.servlet.http.*;
-
-import org.apache.juneau.collections.*;
-import org.apache.juneau.http.annotation.Content;
-import org.apache.juneau.http.header.*;
-import org.apache.juneau.parser.*;
-import org.apache.juneau.rest.*;
-import org.apache.juneau.rest.RestRequest;
-import org.apache.juneau.rest.RestResponse;
-import org.apache.juneau.rest.client.*;
-import org.apache.juneau.rest.httppart.*;
-import org.apache.juneau.rest.mock.*;
-import org.apache.juneau.serializer.*;
-import org.apache.juneau.testutils.*;
-import org.junit.*;
-
-@FixMethodOrder(NAME_ASCENDING)
-public class RestHook_Test {
-
- //------------------------------------------------------------------------------------------------------------------
- // @RestHook(PRE_CALL)
- //------------------------------------------------------------------------------------------------------------------
-
- @Rest(
- parsers=A1.class,
- defaultRequestAttributes={
- "p1:sp1", // Unchanged servlet-level property.
- "p2:sp2", // Servlet-level property overridden by onPreCall.
- "p3:sp3", // Servlet-level property overridded by method.
- "p4:sp4" // Servlet-level property overridden by method then onPreCall.
- }
- )
- public static class A {
-
- @RestHook(PRE_CALL)
- public void onPreCall(RestRequest req) {
- RequestAttributes attrs = req.getAttributes();
- attrs.set("p2", "xp2");
- attrs.set("p4", "xp4");
- attrs.set("p5", "xp5"); // New property
- String overrideContentType = req.getHeader("Override-Content-Type").orElse(null);
- if (overrideContentType != null)
- req.getHeaders().set("Content-Type", overrideContentType);
- }
-
- @RestPut(
- defaultRequestAttributes={
- "p3:mp3",
- "p4:mp4"
- }
- )
- public String a(@Content String in) {
- return in;
- }
-
- @RestPut
- public String b(RestRequest req, RequestAttributes attrs) throws Exception {
- attrs.set("p3", "pp3");
- attrs.set("p4", "pp4");
- return req.getContent().as(String.class);
- }
- }
-
- public static class A1 extends MockReaderParser {
- public A1(MockReaderParser.Builder b) {
- super(b.consumes("text/a1,text/a2,text/a3").function((session,in,type)->in(session)));
- }
-
- private static Object in(ReaderParserSession session) {
- JsonMap sp = session.getSessionProperties();
- return "p1="+sp.get("p1",null)+",p2="+sp.get("p2",null)+",p3="+sp.get("p3",null)+",p4="+sp.get("p4",null)+",p5="+sp.get("p5",null);
-
- }
- }
-
- @Test
- public void a01_preCall() throws Exception {
- RestClient a = MockRestClient.build(A.class);
- a.put("/a", null).contentType("text/a1").run().assertContent().is("p1=sp1,p2=xp2,p3=mp3,p4=xp4,p5=xp5");
- a.put("/a", null).contentType("text/a1").header("Override-Content-Type", "text/a2").run().assertContent().is("p1=sp1,p2=xp2,p3=mp3,p4=xp4,p5=xp5");
- a.put("/b", null).contentType("text/a1").run().assertContent().is("p1=sp1,p2=xp2,p3=pp3,p4=pp4,p5=xp5");
- a.put("/b", null).contentType("text/a1").header("Override-Content-Type", "text/a2").run().assertContent().is("p1=sp1,p2=xp2,p3=pp3,p4=pp4,p5=xp5");
- }
-
- //------------------------------------------------------------------------------------------------------------------
- // @RestHook(POST_CALL)
- //------------------------------------------------------------------------------------------------------------------
-
- @Rest(
- serializers=B1.class,
- defaultRequestAttributes={
- "p1:sp1", // Unchanged servlet-level property.
- "p2:sp2", // Servlet-level property overridden by onPostCall.
- "p3:sp3", // Servlet-level property overridded by method.
- "p4:sp4" // Servlet-level property overridden by method then onPostCall.
- }
- )
- public static class B {
-
- @RestHook(POST_CALL)
- public void onPostCall(RestRequest req, RestResponse res) {
- RequestAttributes attrs = req.getAttributes();
- attrs.set("p2", "xp2");
- attrs.set("p4", "xp4");
- attrs.set("p5", "xp5"); // New property
- String overrideAccept = req.getHeader("Override-Accept").orElse(null);
- if (overrideAccept != null)
- req.getHeaders().set("Accept", overrideAccept);
- String overrideContentType = req.getHeader("Override-Content-Type").orElse(null);
- if (overrideContentType != null)
- attrs.set("Override-Content-Type", overrideContentType);
- }
-
- @RestPut(
- defaultRequestAttributes={
- "p3:mp3",
- "p4:mp4"
- },
- defaultRequestHeaders="Accept: text/s2"
- )
- public String a() {
- return null;
- }
-
- @RestPut
- public String b(RestRequest req, RequestAttributes attrs) throws Exception {
- attrs.set("p3", "pp3");
- attrs.set("p4", "pp4");
- String accept = req.getHeader("Accept").orElse(null);
- if (accept == null || accept.isEmpty())
- req.getHeaders().set("Accept", "text/s2");
- return null;
- }
- }
-
- public static class B1 extends MockWriterSerializer {
- public B1(MockWriterSerializer.Builder b) {
- super(b.produces("test/s1").accept("text/s1,text/s2,text/s3").function((s,o) -> out(s)).headers(s->headers(s)));
- }
- public static String out(SerializerSession s) {
- JsonMap sp = s.getSessionProperties();
- return "p1="+sp.get("p1",null)+",p2="+sp.get("p2",null)+",p3="+sp.get("p3",null)+",p4="+sp.get("p4",null)+",p5="+sp.get("p5",null);
- }
- public static Map<String,String> headers(SerializerSession s) {
- JsonMap sp = s.getSessionProperties();
- if (sp.containsKey("Override-Content-Type"))
- return map("Content-Type",sp.getString("Override-Content-Type",null));
- return emptyMap();
- }
- }
-
- @Test
- public void b01_postCall() throws Exception {
- RestClient b = MockRestClient.build(B.class);
- b.put("/a", null).accept("text/s1").run().assertContent().is("p1=sp1,p2=xp2,p3=mp3,p4=xp4,p5=xp5");
- b.put("/a", null).accept("text/s1").header("Override-Accept", "text/s2").run().assertContent().is("p1=sp1,p2=xp2,p3=mp3,p4=xp4,p5=xp5");
- b.put("/a", null).accept("text/s1").header("Override-Content-Type", "text/s3").run().assertContent().is("p1=sp1,p2=xp2,p3=mp3,p4=xp4,p5=xp5");
- b.put("/a", null).run().assertContent().is("p1=sp1,p2=xp2,p3=mp3,p4=xp4,p5=xp5");
- b.put("/a", null).header("Override-Accept", "text/s3").run().assertContent().is("p1=sp1,p2=xp2,p3=mp3,p4=xp4,p5=xp5");
- b.put("/a", null).header("Override-Content-Type", "text/s3").run().assertContent().is("p1=sp1,p2=xp2,p3=mp3,p4=xp4,p5=xp5");
- b.put("/b", null).accept("text/s1").run().assertContent().is("p1=sp1,p2=xp2,p3=pp3,p4=xp4,p5=xp5");
- b.put("/b", null).accept("text/s1").header("Override-Accept", "text/s2").run().assertContent().is("p1=sp1,p2=xp2,p3=pp3,p4=xp4,p5=xp5");
- b.put("/b", null).accept("text/s1").header("Override-Content-Type", "text/s3").run().assertContent().is("p1=sp1,p2=xp2,p3=pp3,p4=xp4,p5=xp5");
- b.put("/b", null).run().assertContent().is("p1=sp1,p2=xp2,p3=pp3,p4=xp4,p5=xp5");
- b.put("/b", null).header("Override-Accept", "text/s3").run().assertContent().is("p1=sp1,p2=xp2,p3=pp3,p4=xp4,p5=xp5");
- b.put("/b", null).header("Override-Content-Type", "text/s3").run().assertContent().is("p1=sp1,p2=xp2,p3=pp3,p4=xp4,p5=xp5");
- }
-
- //------------------------------------------------------------------------------------------------------------------
- // @RestHook(INIT)
- //------------------------------------------------------------------------------------------------------------------
-
- @Rest(children={C_Super.class,C_Sub.class})
- public static class C {}
-
- @Rest(path="/super")
- public static class C_Super {
- protected JsonList events = new JsonList();
- @RestHook(INIT)
- public void init1c(RestContext.Builder builder) {
- events.add("super-1c");
- }
- @RestHook(INIT)
- public void init1a(ServletConfig config) {
- events.add("super-1a");
- }
- @RestHook(INIT)
- public void init1b() {
- events.add("super-1b");
- }
- @RestHook(INIT)
- public void init2a() {
- events.add("super-2a");
- }
- @RestGet
- public JsonList getEvents() {
- return events;
- }
- }
-
- @Rest(path="/sub", children={C_Child.class})
- public static class C_Sub extends C_Super {
- @Override
- @RestHook(INIT)
- public void init1c(RestContext.Builder builder) {
- events.add("sub-1c");
- }
- @Override
- @RestHook(INIT)
- public void init1a(ServletConfig config) {
- events.add("sub-1a");
- }
- @Override
- @RestHook(INIT)
- public void init1b() {
- events.add("sub-1b");
- }
- @RestHook(INIT)
- public void init2b() {
- events.add("sub-2b");
- }
- }
-
- @Rest(path="/child")
- public static class C_Child extends C_Super {
- @Override
- @RestHook(INIT)
- public void init1c(RestContext.Builder builder) {
- events.add("child-1c");
- }
- @RestHook(INIT)
- public void init2b() {
- events.add("child-2b");
- }
- }
-
- @Test
- public void c01_init() throws Exception {
- RestClient c = MockRestClient.build(C.class);
- c.get("/super/events").run().assertContent().is("['super-1a','super-1b','super-1c','super-2a']");
- c.get("/sub/events").run().assertContent().is("['sub-1a','sub-1b','sub-1c','super-2a','sub-2b']");
- c.get("/sub/child/events").run().assertContent().is("['super-1a','super-1b','child-1c','super-2a','child-2b']");
- }
-
- //------------------------------------------------------------------------------------------------------------------
- // @RestHook(POST_INIT)
- //------------------------------------------------------------------------------------------------------------------
- @Rest(children={D_Super.class,D_Sub.class})
- public static class D {}
-
- @Rest(path="/super")
- public static class D_Super {
- protected JsonList events = new JsonList();
- @RestHook(POST_INIT)
- public void postInit1c(RestContext context) {
- events.add("super-1c");
- }
- @RestHook(POST_INIT)
- public void postInit1a(RestContext context) {
- events.add("super-1a");
- }
- @RestHook(POST_INIT)
- public void postInit1b() {
- events.add("super-1b");
- }
- @RestHook(POST_INIT)
- public void postInit2a() {
- events.add("super-2a");
- }
- @RestGet
- public JsonList getEvents() {
- return events;
- }
- }
-
- @Rest(path="/sub",children={D_Child.class})
- public static class D_Sub extends D_Super {
- protected static String LAST_CALLED;
- @Override
- @RestHook(POST_INIT)
- public void postInit1c(RestContext context) {
- events.add("sub-1c");
- }
- @Override
- @RestHook(POST_INIT)
- public void postInit1a(RestContext context) {
- events.add("sub-1a");
- }
- @Override
- @RestHook(POST_INIT)
- public void postInit1b() {
- events.add("sub-1b");
- }
- @RestHook(POST_INIT)
- public void postInit2b() {
- events.add("sub-2b");
- }
- @RestHook(POST_INIT)
- public void postInitOrderTestSub() {
- LAST_CALLED = "PARENT";
- }
- @RestGet
- public String getLastCalled() {
- return LAST_CALLED;
- }
- }
-
- @Rest(path="/child")
- public static class D_Child extends D_Super {
- @Override
- @RestHook(POST_INIT)
- public void postInit1c(RestContext context) {
- events.add("child-1c");
- }
- @RestHook(POST_INIT)
- public void postInit2b() {
- events.add("child-2b");
- }
- @RestHook(POST_INIT)
- public void postInitOrderTestSub() {
- D_Sub.LAST_CALLED = "CHILD";
- }
- }
-
- @Test
- public void d01_postInit() throws Exception {
- RestClient d = MockRestClient.build(D.class);
- d.get("/super/events").run().assertContent().is("['super-1a','super-1b','super-1c','super-2a']");
- d.get("/sub/events").run().assertContent().is("['sub-1a','sub-1b','sub-1c','super-2a','sub-2b']");
- d.get("/sub/child/events").run().assertContent().is("['super-1a','super-1b','child-1c','super-2a','child-2b']");
- d.get("/sub/lastCalled").run().assertContent().is("CHILD");
- }
-
- //------------------------------------------------------------------------------------------------------------------
- // @RestHook(POST_INIT_CHILD_FIRST)
- //------------------------------------------------------------------------------------------------------------------
-
- @Rest(
- children={
- E_Super.class,
- E_Sub.class
- }
- )
- public static class E {}
-
- @Rest(path="/super")
- public static class E_Super {
- protected JsonList events = new JsonList();
- @RestHook(POST_INIT_CHILD_FIRST)
- public void postInitChildFirst1c(RestContext context) {
- events.add("super-1c");
- }
- @RestHook(POST_INIT_CHILD_FIRST)
- public void postInitChildFirst1a(RestContext context) {
- events.add("super-1a");
- }
- @RestHook(POST_INIT_CHILD_FIRST)
- public void postInitChildFirst1b() {
- events.add("super-1b");
- }
- @RestHook(POST_INIT_CHILD_FIRST)
- public void postInitChildFirst2a() {
- events.add("super-2a");
- }
- @RestGet
- public JsonList getPostInitChildFirstEvents() {
- return events;
- }
- }
-
- @Rest(path="/sub", children={E_Child.class})
- public static class E_Sub extends E_Super {
- protected static String LAST_CALLED;
- @Override
- @RestHook(POST_INIT_CHILD_FIRST)
- public void postInitChildFirst1c(RestContext context) {
- events.add("sub-1c");
- }
- @Override
- @RestHook(POST_INIT_CHILD_FIRST)
- public void postInitChildFirst1a(RestContext context) {
- events.add("sub-1a");
- }
- @Override
- @RestHook(POST_INIT_CHILD_FIRST)
- public void postInitChildFirst1b() {
- events.add("sub-1b");
- }
- @RestHook(POST_INIT_CHILD_FIRST)
- public void postInitChildFirst2b() {
- events.add("sub-2b");
- }
- @RestHook(POST_INIT_CHILD_FIRST)
- public void postInitChildFirstOrderTestSub() {
- LAST_CALLED = "PARENT";
- }
- @RestGet
- public String getLastCalled() {
- return LAST_CALLED;
- }
- }
-
- @Rest(path="/child")
- public static class E_Child extends E_Super {
- @Override
- @RestHook(POST_INIT_CHILD_FIRST)
- public void postInitChildFirst1c(RestContext context) {
- events.add("child-1c");
- }
- @RestHook(POST_INIT_CHILD_FIRST)
- public void postInitChildFirst2b() {
- events.add("child-2b");
- }
- @RestHook(POST_INIT_CHILD_FIRST)
- public void postInitChildFirstOrderTestSub() {
- E_Sub.LAST_CALLED = "CHILD";
- }
- }
-
- @Test
- public void e01_postInitChildFirst() throws Exception {
- RestClient e = MockRestClient.build(E.class);
- e.get("/super/postInitChildFirstEvents").run().assertContent().is("['super-1a','super-1b','super-1c','super-2a']");
- e.get("/sub/postInitChildFirstEvents").run().assertContent().is("['sub-1a','sub-1b','sub-1c','super-2a','sub-2b']");
- e.get("/sub/child/postInitChildFirstEvents").run().assertContent().is("['super-1a','super-1b','child-1c','super-2a','child-2b']");
- e.get("/sub/lastCalled").run().assertContent().is("PARENT");
- }
-
- //------------------------------------------------------------------------------------------------------------------
- // @RestHook(START_CALL)
- //------------------------------------------------------------------------------------------------------------------
-
- @Rest
- public static class F extends F_Parent {
- private boolean start3Called;
- @RestHook(START_CALL)
- public void start3() {
- start3Called = true;
- }
- @RestHook(START_CALL)
- public void start4(HttpServletRequest req, HttpServletResponse res) {
- res.setHeader("start3-called", ""+start3Called);
- start3Called = false;
- if (res.getHeader("start4-called") != null)
- throw new RuntimeException("start4 called multiple times.");
- res.setHeader("start4-called", "true");
- }
- @RestGet(path="/")
- public JsonMap a(RestRequest req, RestResponse res) {
- return JsonMap.create()
- .append("1", res.getHeader("start1-called"))
- .append("2", res.getHeader("start2-called"))
- .append("3", res.getHeader("start3-called"))
- .append("4", res.getHeader("start4-called"));
- }
- }
-
- public static class F_Parent {
- private boolean start1Called;
- @RestHook(START_CALL)
- public void start1() {
- start1Called = true;
- }
- @RestHook(START_CALL)
- public void start2(HttpServletRequest req, HttpServletResponse res) {
- res.setHeader("start1-called", ""+start1Called);
- start1Called = false;
- if (res.getHeader("start2-called") != null)
- throw new RuntimeException("start2 called multiple times.");
- res.setHeader("start2-called", "true");
- }
- }
-
- @Test
- public void f01_startCall() throws Exception {
- RestClient f = MockRestClient.build(F.class);
- f.get("/").run().assertContent().is("{'1':'true','2':'true','3':'true','4':'true'}");
- }
-
- //------------------------------------------------------------------------------------------------------------------
- // @RestHook(PRE_CALL)
- //------------------------------------------------------------------------------------------------------------------
-
- @Rest
- public static class G extends G_Parent {
- private boolean pre3Called;
- @RestHook(PRE_CALL)
- public void pre3() {
- pre3Called = true;
- }
- @RestHook(PRE_CALL)
- public void pre4(HttpServletRequest req, HttpServletResponse res) {
- res.setHeader("pre3-called", ""+pre3Called);
- pre3Called = false;
- if (res.getHeader("pre4-called") != null)
- throw new RuntimeException("pre4 called multiple times.");
- res.setHeader("pre4-called", "true");
- }
- @RestGet(path="/")
- public JsonMap a(RestRequest req, RestResponse res) {
- return JsonMap.create()
- .append("1", res.getHeader("pre1-called"))
- .append("2", res.getHeader("pre2-called"))
- .append("3", res.getHeader("pre3-called"))
- .append("4", res.getHeader("pre4-called"));
- }
- }
-
- public static class G_Parent {
- private boolean pre1Called;
- @RestHook(PRE_CALL)
- public void pre1() {
- pre1Called = true;
- }
- @RestHook(PRE_CALL)
- public void pre2(Accept accept, RestRequest req, RestResponse res) {
- res.setHeader("pre1-called", ""+pre1Called);
- pre1Called = false;
- if (res.getHeader("pre2-called") != null)
- throw new RuntimeException("pre2 called multiple times.");
- res.setHeader("pre2-called", "true");
- }
- }
-
- @Test
- public void g01_preCall() throws Exception {
- RestClient g = MockRestClient.build(G.class);
- g.get("/").run().assertContent().is("{'1':'true','2':'true','3':'true','4':'true'}");
- }
-
- //------------------------------------------------------------------------------------------------------------------
- // @RestHook(POST_CALL)
- //------------------------------------------------------------------------------------------------------------------
-
- @Rest
- public static class H extends H_Parent {
- private boolean post3Called;
- @RestHook(POST_CALL)
- public void post3() {
- post3Called = true;
- }
- @RestHook(POST_CALL)
- public void post4(HttpServletRequest req, HttpServletResponse res) {
- res.setHeader("post3-called", ""+post3Called);
- post3Called = false;
- if (res.getHeader("post4-called") != null)
- throw new RuntimeException("post4 called multiple times.");
- res.setHeader("post4-called", "true");
- }
- @RestGet(path="/")
- public String a() {
- return "OK";
- }
- }
-
- public static class H_Parent {
- private boolean post1Called;
- @RestHook(POST_CALL)
- public void post1() {
- post1Called = true;
- }
- @RestHook(POST_CALL)
- public void post2(Accept accept, RestRequest req, RestResponse res) {
- res.setHeader("post1-called", ""+post1Called);
- post1Called = false;
- if (res.getHeader("post2-called") != null)
- throw new RuntimeException("post2 called multiple times.");
- res.setHeader("post2-called", "true");
- }
- }
-
- @Test
- public void h01_postCall() throws Exception {
- RestClient h = MockRestClient.build(H.class);
- h.get("/").run()
- .assertHeader("post1-called").is("true")
- .assertHeader("post2-called").is("true")
- .assertHeader("post3-called").is("true")
- .assertHeader("post4-called").is("true");
- }
-}
diff --git a/juneau-utest/src/test/java/org/apache/juneau/rest/annotation/RestHookAnnotation_Test.java b/juneau-utest/src/test/java/org/apache/juneau/rest/annotation/RestInitAnnotation_Test.java
similarity index 87%
copy from juneau-utest/src/test/java/org/apache/juneau/rest/annotation/RestHookAnnotation_Test.java
copy to juneau-utest/src/test/java/org/apache/juneau/rest/annotation/RestInitAnnotation_Test.java
index 291c26cc3..e265eaec9 100644
--- a/juneau-utest/src/test/java/org/apache/juneau/rest/annotation/RestHookAnnotation_Test.java
+++ b/juneau-utest/src/test/java/org/apache/juneau/rest/annotation/RestInitAnnotation_Test.java
@@ -20,30 +20,27 @@ import org.apache.juneau.*;
import org.junit.*;
@FixMethodOrder(NAME_ASCENDING)
-public class RestHookAnnotation_Test {
+public class RestInitAnnotation_Test {
- private static final String CNAME = RestHookAnnotation_Test.class.getName();
+ private static final String CNAME = RestInitAnnotation_Test.class.getName();
//------------------------------------------------------------------------------------------------------------------
// Basic tests
//------------------------------------------------------------------------------------------------------------------
- RestHook a1 = RestHookAnnotation.create()
+ RestInit a1 = RestInitAnnotation.create()
.on("a")
- .value(HookEvent.INIT)
.build();
- RestHook a2 = RestHookAnnotation.create()
+ RestInit a2 = RestInitAnnotation.create()
.on("a")
- .value(HookEvent.INIT)
.build();
@Test
public void a01_basic() {
assertObject(a1).asJson().is(""
+ "{"
- + "on:['a'],"
- + "value:'INIT'"
+ + "on:['a']"
+ "}"
);
}
@@ -80,7 +77,7 @@ public class RestHookAnnotation_Test {
@Test
public void c01_otherMethods() throws Exception {
- RestHook c4 = RestHookAnnotation.create().on(C1.class.getMethod("m1")).on(C2.class.getMethod("m2")).build();
+ RestInit c4 = RestInitAnnotation.create().on(C1.class.getMethod("m1")).on(C2.class.getMethod("m2")).build();
assertObject(c4).asJson().isContains("on:['"+CNAME+"$C1.m1()','"+CNAME+"$C2.m2()']");
}
@@ -89,19 +86,17 @@ public class RestHookAnnotation_Test {
// Comparison with declared annotations.
//------------------------------------------------------------------------------------------------------------------
- @RestHook(
- on="a",
- value=HookEvent.INIT
+ @RestInit(
+ on="a"
)
public static class D1 {}
- RestHook d1 = D1.class.getAnnotationsByType(RestHook.class)[0];
+ RestInit d1 = D1.class.getAnnotationsByType(RestInit.class)[0];
- @RestHook(
- on="a",
- value=HookEvent.INIT
+ @RestInit(
+ on="a"
)
public static class D2 {}
- RestHook d2 = D2.class.getAnnotationsByType(RestHook.class)[0];
+ RestInit d2 = D2.class.getAnnotationsByType(RestInit.class)[0];
@Test
public void d01_comparisonWithDeclarativeAnnotations() {
diff --git a/juneau-utest/src/test/java/org/apache/juneau/rest/annotation/Rest_Context_Test.java b/juneau-utest/src/test/java/org/apache/juneau/rest/annotation/RestInit_Test.java
similarity index 53%
copy from juneau-utest/src/test/java/org/apache/juneau/rest/annotation/Rest_Context_Test.java
copy to juneau-utest/src/test/java/org/apache/juneau/rest/annotation/RestInit_Test.java
index 96a9862c9..f572ac1f9 100644
--- a/juneau-utest/src/test/java/org/apache/juneau/rest/annotation/Rest_Context_Test.java
+++ b/juneau-utest/src/test/java/org/apache/juneau/rest/annotation/RestInit_Test.java
@@ -12,93 +12,92 @@
// ***************************************************************************************************************************
package org.apache.juneau.rest.annotation;
-import static org.apache.juneau.assertions.Assertions.*;
import static org.junit.runners.MethodSorters.*;
+import javax.servlet.*;
+
+import org.apache.juneau.collections.*;
import org.apache.juneau.rest.*;
+import org.apache.juneau.rest.client.*;
import org.apache.juneau.rest.mock.*;
import org.junit.*;
@FixMethodOrder(NAME_ASCENDING)
-public class Rest_Context_Test {
+public class RestInit_Test {
- public static class X1 extends RestContext {
- public X1(RestContext.Builder builder) throws Exception {
- super(builder);
- }
- }
+ //------------------------------------------------------------------------------------------------------------------
+ // @RestInit
+ //------------------------------------------------------------------------------------------------------------------
- @Rest
- public static class A1 {
+ @Rest(children={A_Super.class,A_Sub.class})
+ public static class A {}
+
+ @Rest(path="/super")
+ public static class A_Super {
+ protected JsonList events = new JsonList();
+ @RestInit
+ public void init1c(RestContext.Builder builder) {
+ events.add("super-1c");
+ }
+ @RestInit
+ public void init1a(ServletConfig config) {
+ events.add("super-1a");
+ }
+ @RestInit
+ public void init1b() {
+ events.add("super-1b");
+ }
+ @RestInit
+ public void init2a() {
+ events.add("super-2a");
+ }
@RestGet
- public String get(RestContext context) {
- return context.getClass().getSimpleName();
+ public JsonList getEvents() {
+ return events;
}
}
- @Test
- public void a01_default() throws Exception {
- MockRestClient a1 = client(A1.class);
- a1.get().run().assertContent().is("RestContext");
- }
-
- @Rest(contextClass=X1.class)
- public static class A2 extends A1 {}
-
- @Test
- public void a02_custom() throws Exception {
- MockRestClient a2 = client(A2.class);
- a2.get().run().assertContent().is("X1");
- }
-
- @Rest
- public static class A3 extends A2 {}
-
- @Test
- public void a03_notOverriddenByChild() throws Exception {
- MockRestClient a3 = client(A3.class);
- a3.get().run().assertContent().is("X1");
- }
-
- @Rest
- public static class A4 extends A1 {
- @RestHook(HookEvent.INIT)
- public void init(RestContext.Builder builder) throws Exception {
- builder.type(X1.class);
- }
- }
-
- @Test
- public void a04_definedInBuilder() throws Exception {
- MockRestClient a4 = client(A4.class);
- a4.get().run().assertContent().is("X1");
- }
-
-
- public static class X2 extends RestContext {
- public X2() throws Exception {
- super(null);
+ @Rest(path="/sub", children={A_Child.class})
+ public static class A_Sub extends A_Super {
+ @Override
+ @RestInit
+ public void init1c(RestContext.Builder builder) {
+ events.add("sub-1c");
+ }
+ @Override
+ @RestInit
+ public void init1a(ServletConfig config) {
+ events.add("sub-1a");
+ }
+ @Override
+ @RestInit
+ public void init1b() {
+ events.add("sub-1b");
+ }
+ @RestInit
+ public void init2b() {
+ events.add("sub-2b");
}
}
- @Rest(contextClass=X2.class)
- public static class A5 {
- @RestGet
- public String get(RestContext context) {
- return context.getClass().getSimpleName();
+ @Rest(path="/child")
+ public static class A_Child extends A_Super {
+ @Override
+ @RestInit
+ public void init1c(RestContext.Builder builder) {
+ events.add("child-1c");
+ }
+ @RestInit
+ public void init2b() {
+ events.add("child-2b");
}
}
@Test
- public void a05_invalidConstructor() throws Exception {
- assertThrown(()->client(A5.class)).asMessages().isContains("Could not instantiate RestContext.");
- }
-
- //------------------------------------------------------------------------------------------------------------------
- // Helper methods
- //------------------------------------------------------------------------------------------------------------------
-
- private static MockRestClient client(Class<?> c) {
- return MockRestClient.create(c).build();
+ public void a01_init() throws Exception {
+ RestClient a = MockRestClient.build(A.class);
+ a.get("/super/events").run().assertContent().is("['super-1a','super-1b','super-1c','super-2a']");
+ a.get("/sub/events").run().assertContent().is("['sub-1a','sub-1b','sub-1c','super-2a','sub-2b']");
+ a.get("/sub/child/events").run().assertContent().is("['super-1a','super-1b','child-1c','super-2a','child-2b']");
}
}
diff --git a/juneau-utest/src/test/java/org/apache/juneau/rest/annotation/RestHookAnnotation_Test.java b/juneau-utest/src/test/java/org/apache/juneau/rest/annotation/RestPostCallAnnotation_Test.java
similarity index 86%
copy from juneau-utest/src/test/java/org/apache/juneau/rest/annotation/RestHookAnnotation_Test.java
copy to juneau-utest/src/test/java/org/apache/juneau/rest/annotation/RestPostCallAnnotation_Test.java
index 291c26cc3..437ec1fad 100644
--- a/juneau-utest/src/test/java/org/apache/juneau/rest/annotation/RestHookAnnotation_Test.java
+++ b/juneau-utest/src/test/java/org/apache/juneau/rest/annotation/RestPostCallAnnotation_Test.java
@@ -20,30 +20,27 @@ import org.apache.juneau.*;
import org.junit.*;
@FixMethodOrder(NAME_ASCENDING)
-public class RestHookAnnotation_Test {
+public class RestPostCallAnnotation_Test {
- private static final String CNAME = RestHookAnnotation_Test.class.getName();
+ private static final String CNAME = RestPostCallAnnotation_Test.class.getName();
//------------------------------------------------------------------------------------------------------------------
// Basic tests
//------------------------------------------------------------------------------------------------------------------
- RestHook a1 = RestHookAnnotation.create()
+ RestPostCall a1 = RestPostCallAnnotation.create()
.on("a")
- .value(HookEvent.INIT)
.build();
- RestHook a2 = RestHookAnnotation.create()
+ RestPostCall a2 = RestPostCallAnnotation.create()
.on("a")
- .value(HookEvent.INIT)
.build();
@Test
public void a01_basic() {
assertObject(a1).asJson().is(""
+ "{"
- + "on:['a'],"
- + "value:'INIT'"
+ + "on:['a']"
+ "}"
);
}
@@ -80,7 +77,7 @@ public class RestHookAnnotation_Test {
@Test
public void c01_otherMethods() throws Exception {
- RestHook c4 = RestHookAnnotation.create().on(C1.class.getMethod("m1")).on(C2.class.getMethod("m2")).build();
+ RestPostCall c4 = RestPostCallAnnotation.create().on(C1.class.getMethod("m1")).on(C2.class.getMethod("m2")).build();
assertObject(c4).asJson().isContains("on:['"+CNAME+"$C1.m1()','"+CNAME+"$C2.m2()']");
}
@@ -89,19 +86,17 @@ public class RestHookAnnotation_Test {
// Comparison with declared annotations.
//------------------------------------------------------------------------------------------------------------------
- @RestHook(
- on="a",
- value=HookEvent.INIT
+ @RestPostCall(
+ on="a"
)
public static class D1 {}
- RestHook d1 = D1.class.getAnnotationsByType(RestHook.class)[0];
+ RestPostCall d1 = D1.class.getAnnotationsByType(RestPostCall.class)[0];
- @RestHook(
- on="a",
- value=HookEvent.INIT
+ @RestPostCall(
+ on="a"
)
public static class D2 {}
- RestHook d2 = D2.class.getAnnotationsByType(RestHook.class)[0];
+ RestPostCall d2 = D2.class.getAnnotationsByType(RestPostCall.class)[0];
@Test
public void d01_comparisonWithDeclarativeAnnotations() {
diff --git a/juneau-utest/src/test/java/org/apache/juneau/rest/annotation/Rest_Context_Test.java b/juneau-utest/src/test/java/org/apache/juneau/rest/annotation/RestPostCall_Test.java
similarity index 52%
copy from juneau-utest/src/test/java/org/apache/juneau/rest/annotation/Rest_Context_Test.java
copy to juneau-utest/src/test/java/org/apache/juneau/rest/annotation/RestPostCall_Test.java
index 96a9862c9..b43154e83 100644
--- a/juneau-utest/src/test/java/org/apache/juneau/rest/annotation/Rest_Context_Test.java
+++ b/juneau-utest/src/test/java/org/apache/juneau/rest/annotation/RestPostCall_Test.java
@@ -12,93 +12,68 @@
// ***************************************************************************************************************************
package org.apache.juneau.rest.annotation;
-import static org.apache.juneau.assertions.Assertions.*;
import static org.junit.runners.MethodSorters.*;
-import org.apache.juneau.rest.*;
+import javax.servlet.http.*;
+
+import org.apache.juneau.http.header.*;
+import org.apache.juneau.rest.RestRequest;
+import org.apache.juneau.rest.RestResponse;
+import org.apache.juneau.rest.client.*;
import org.apache.juneau.rest.mock.*;
import org.junit.*;
@FixMethodOrder(NAME_ASCENDING)
-public class Rest_Context_Test {
+public class RestPostCall_Test {
- public static class X1 extends RestContext {
- public X1(RestContext.Builder builder) throws Exception {
- super(builder);
- }
- }
+ //------------------------------------------------------------------------------------------------------------------
+ // @RestPostCall
+ //------------------------------------------------------------------------------------------------------------------
@Rest
- public static class A1 {
- @RestGet
- public String get(RestContext context) {
- return context.getClass().getSimpleName();
+ public static class A extends A_Parent {
+ private boolean post3Called;
+ @RestPostCall
+ public void post3() {
+ post3Called = true;
}
- }
-
- @Test
- public void a01_default() throws Exception {
- MockRestClient a1 = client(A1.class);
- a1.get().run().assertContent().is("RestContext");
- }
-
- @Rest(contextClass=X1.class)
- public static class A2 extends A1 {}
-
- @Test
- public void a02_custom() throws Exception {
- MockRestClient a2 = client(A2.class);
- a2.get().run().assertContent().is("X1");
- }
-
- @Rest
- public static class A3 extends A2 {}
-
- @Test
- public void a03_notOverriddenByChild() throws Exception {
- MockRestClient a3 = client(A3.class);
- a3.get().run().assertContent().is("X1");
- }
-
- @Rest
- public static class A4 extends A1 {
- @RestHook(HookEvent.INIT)
- public void init(RestContext.Builder builder) throws Exception {
- builder.type(X1.class);
- }
- }
-
- @Test
- public void a04_definedInBuilder() throws Exception {
- MockRestClient a4 = client(A4.class);
- a4.get().run().assertContent().is("X1");
- }
-
-
- public static class X2 extends RestContext {
- public X2() throws Exception {
- super(null);
+ @RestPostCall
+ public void post4(HttpServletRequest req, HttpServletResponse res) {
+ res.setHeader("post3-called", ""+post3Called);
+ post3Called = false;
+ if (res.getHeader("post4-called") != null)
+ throw new RuntimeException("post4 called multiple times.");
+ res.setHeader("post4-called", "true");
+ }
+ @RestGet(path="/")
+ public String a() {
+ return "OK";
}
}
- @Rest(contextClass=X2.class)
- public static class A5 {
- @RestGet
- public String get(RestContext context) {
- return context.getClass().getSimpleName();
+ public static class A_Parent {
+ private boolean post1Called;
+ @RestPostCall
+ public void post1() {
+ post1Called = true;
+ }
+ @RestPostCall
+ public void post2(Accept accept, RestRequest req, RestResponse res) {
+ res.setHeader("post1-called", ""+post1Called);
+ post1Called = false;
+ if (res.getHeader("post2-called") != null)
+ throw new RuntimeException("post2 called multiple times.");
+ res.setHeader("post2-called", "true");
}
}
@Test
- public void a05_invalidConstructor() throws Exception {
- assertThrown(()->client(A5.class)).asMessages().isContains("Could not instantiate RestContext.");
- }
-
- //------------------------------------------------------------------------------------------------------------------
- // Helper methods
- //------------------------------------------------------------------------------------------------------------------
-
- private static MockRestClient client(Class<?> c) {
- return MockRestClient.create(c).build();
+ public void a01_postCall() throws Exception {
+ RestClient a = MockRestClient.build(A.class);
+ a.get("/").run()
+ .assertHeader("post1-called").is("true")
+ .assertHeader("post2-called").is("true")
+ .assertHeader("post3-called").is("true")
+ .assertHeader("post4-called").is("true");
}
}
diff --git a/juneau-utest/src/test/java/org/apache/juneau/rest/annotation/RestHookAnnotation_Test.java b/juneau-utest/src/test/java/org/apache/juneau/rest/annotation/RestPostInitAnnotation_Test.java
similarity index 85%
copy from juneau-utest/src/test/java/org/apache/juneau/rest/annotation/RestHookAnnotation_Test.java
copy to juneau-utest/src/test/java/org/apache/juneau/rest/annotation/RestPostInitAnnotation_Test.java
index 291c26cc3..529e08f9a 100644
--- a/juneau-utest/src/test/java/org/apache/juneau/rest/annotation/RestHookAnnotation_Test.java
+++ b/juneau-utest/src/test/java/org/apache/juneau/rest/annotation/RestPostInitAnnotation_Test.java
@@ -20,30 +20,30 @@ import org.apache.juneau.*;
import org.junit.*;
@FixMethodOrder(NAME_ASCENDING)
-public class RestHookAnnotation_Test {
+public class RestPostInitAnnotation_Test {
- private static final String CNAME = RestHookAnnotation_Test.class.getName();
+ private static final String CNAME = RestPostInitAnnotation_Test.class.getName();
//------------------------------------------------------------------------------------------------------------------
// Basic tests
//------------------------------------------------------------------------------------------------------------------
- RestHook a1 = RestHookAnnotation.create()
+ RestPostInit a1 = RestPostInitAnnotation.create()
.on("a")
- .value(HookEvent.INIT)
+ .childFirst()
.build();
- RestHook a2 = RestHookAnnotation.create()
+ RestPostInit a2 = RestPostInitAnnotation.create()
.on("a")
- .value(HookEvent.INIT)
+ .childFirst()
.build();
@Test
public void a01_basic() {
assertObject(a1).asJson().is(""
+ "{"
- + "on:['a'],"
- + "value:'INIT'"
+ + "childFirst:true,"
+ + "on:['a']"
+ "}"
);
}
@@ -80,7 +80,7 @@ public class RestHookAnnotation_Test {
@Test
public void c01_otherMethods() throws Exception {
- RestHook c4 = RestHookAnnotation.create().on(C1.class.getMethod("m1")).on(C2.class.getMethod("m2")).build();
+ RestPostInit c4 = RestPostInitAnnotation.create().on(C1.class.getMethod("m1")).on(C2.class.getMethod("m2")).build();
assertObject(c4).asJson().isContains("on:['"+CNAME+"$C1.m1()','"+CNAME+"$C2.m2()']");
}
@@ -89,19 +89,19 @@ public class RestHookAnnotation_Test {
// Comparison with declared annotations.
//------------------------------------------------------------------------------------------------------------------
- @RestHook(
- on="a",
- value=HookEvent.INIT
+ @RestPostInit(
+ childFirst=true,
+ on="a"
)
public static class D1 {}
- RestHook d1 = D1.class.getAnnotationsByType(RestHook.class)[0];
+ RestPostInit d1 = D1.class.getAnnotationsByType(RestPostInit.class)[0];
- @RestHook(
- on="a",
- value=HookEvent.INIT
+ @RestPostInit(
+ childFirst=true,
+ on="a"
)
public static class D2 {}
- RestHook d2 = D2.class.getAnnotationsByType(RestHook.class)[0];
+ RestPostInit d2 = D2.class.getAnnotationsByType(RestPostInit.class)[0];
@Test
public void d01_comparisonWithDeclarativeAnnotations() {
diff --git a/juneau-utest/src/test/java/org/apache/juneau/rest/annotation/RestPostInit_Test.java b/juneau-utest/src/test/java/org/apache/juneau/rest/annotation/RestPostInit_Test.java
new file mode 100644
index 000000000..83befee14
--- /dev/null
+++ b/juneau-utest/src/test/java/org/apache/juneau/rest/annotation/RestPostInit_Test.java
@@ -0,0 +1,209 @@
+// ***************************************************************************************************************************
+// * 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.annotation;
+
+import static org.junit.runners.MethodSorters.*;
+
+import org.apache.juneau.collections.*;
+import org.apache.juneau.rest.*;
+import org.apache.juneau.rest.client.*;
+import org.apache.juneau.rest.mock.*;
+import org.junit.*;
+
+@FixMethodOrder(NAME_ASCENDING)
+public class RestPostInit_Test {
+
+ //------------------------------------------------------------------------------------------------------------------
+ // @RestPostInit
+ //------------------------------------------------------------------------------------------------------------------
+ @Rest(children={A_Super.class,A_Sub.class})
+ public static class A {}
+
+ @Rest(path="/super")
+ public static class A_Super {
+ protected JsonList events = new JsonList();
+ @RestPostInit
+ public void postInit1c(RestContext context) {
+ events.add("super-1c");
+ }
+ @RestPostInit
+ public void postInit1a(RestContext context) {
+ events.add("super-1a");
+ }
+ @RestPostInit
+ public void postInit1b() {
+ events.add("super-1b");
+ }
+ @RestPostInit
+ public void postInit2a() {
+ events.add("super-2a");
+ }
+ @RestGet
+ public JsonList getEvents() {
+ return events;
+ }
+ }
+
+ @Rest(path="/sub",children={A_Child.class})
+ public static class A_Sub extends A_Super {
+ protected static String LAST_CALLED;
+ @Override
+ @RestPostInit
+ public void postInit1c(RestContext context) {
+ events.add("sub-1c");
+ }
+ @Override
+ @RestPostInit
+ public void postInit1a(RestContext context) {
+ events.add("sub-1a");
+ }
+ @Override
+ @RestPostInit
+ public void postInit1b() {
+ events.add("sub-1b");
+ }
+ @RestPostInit
+ public void postInit2b() {
+ events.add("sub-2b");
+ }
+ @RestPostInit
+ public void postInitOrderTestSub() {
+ LAST_CALLED = "PARENT";
+ }
+ @RestGet
+ public String getLastCalled() {
+ return LAST_CALLED;
+ }
+ }
+
+ @Rest(path="/child")
+ public static class A_Child extends A_Super {
+ @Override
+ @RestPostInit
+ public void postInit1c(RestContext context) {
+ events.add("child-1c");
+ }
+ @RestPostInit
+ public void postInit2b() {
+ events.add("child-2b");
+ }
+ @RestPostInit
+ public void postInitOrderTestSub() {
+ A_Sub.LAST_CALLED = "CHILD";
+ }
+ }
+
+ @Test
+ public void a01_postInit() throws Exception {
+ RestClient a = MockRestClient.build(A.class);
+ a.get("/super/events").run().assertContent().is("['super-1a','super-1b','super-1c','super-2a']");
+ a.get("/sub/events").run().assertContent().is("['sub-1a','sub-1b','sub-1c','super-2a','sub-2b']");
+ a.get("/sub/child/events").run().assertContent().is("['super-1a','super-1b','child-1c','super-2a','child-2b']");
+ a.get("/sub/lastCalled").run().assertContent().is("CHILD");
+ }
+
+ //------------------------------------------------------------------------------------------------------------------
+ // @RestPostInit(childFirst=true)
+ //------------------------------------------------------------------------------------------------------------------
+
+ @Rest(
+ children={
+ B_Super.class,
+ B_Sub.class
+ }
+ )
+ public static class B {}
+
+ @Rest(path="/super")
+ public static class B_Super {
+ protected JsonList events = new JsonList();
+ @RestPostInit(childFirst=true)
+ public void postInitChildFirst1c(RestContext context) {
+ events.add("super-1c");
+ }
+ @RestPostInit(childFirst=true)
+ public void postInitChildFirst1a(RestContext context) {
+ events.add("super-1a");
+ }
+ @RestPostInit(childFirst=true)
+ public void postInitChildFirst1b() {
+ events.add("super-1b");
+ }
+ @RestPostInit(childFirst=true)
+ public void postInitChildFirst2a() {
+ events.add("super-2a");
+ }
+ @RestGet
+ public JsonList getPostInitChildFirstEvents() {
+ return events;
+ }
+ }
+
+ @Rest(path="/sub", children={B_Child.class})
+ public static class B_Sub extends B_Super {
+ protected static String LAST_CALLED;
+ @Override
+ @RestPostInit(childFirst=true)
+ public void postInitChildFirst1c(RestContext context) {
+ events.add("sub-1c");
+ }
+ @Override
+ @RestPostInit(childFirst=true)
+ public void postInitChildFirst1a(RestContext context) {
+ events.add("sub-1a");
+ }
+ @Override
+ @RestPostInit(childFirst=true)
+ public void postInitChildFirst1b() {
+ events.add("sub-1b");
+ }
+ @RestPostInit(childFirst=true)
+ public void postInitChildFirst2b() {
+ events.add("sub-2b");
+ }
+ @RestPostInit(childFirst=true)
+ public void postInitChildFirstOrderTestSub() {
+ LAST_CALLED = "PARENT";
+ }
+ @RestGet
+ public String getLastCalled() {
+ return LAST_CALLED;
+ }
+ }
+
+ @Rest(path="/child")
+ public static class B_Child extends B_Super {
+ @Override
+ @RestPostInit(childFirst=true)
+ public void postInitChildFirst1c(RestContext context) {
+ events.add("child-1c");
+ }
+ @RestPostInit(childFirst=true)
+ public void postInitChildFirst2b() {
+ events.add("child-2b");
+ }
+ @RestPostInit(childFirst=true)
+ public void postInitChildFirstOrderTestSub() {
+ B_Sub.LAST_CALLED = "CHILD";
+ }
+ }
+
+ @Test
+ public void b01_postInitChildFirst() throws Exception {
+ RestClient b = MockRestClient.build(B.class);
+ b.get("/super/postInitChildFirstEvents").run().assertContent().is("['super-1a','super-1b','super-1c','super-2a']");
+ b.get("/sub/postInitChildFirstEvents").run().assertContent().is("['sub-1a','sub-1b','sub-1c','super-2a','sub-2b']");
+ b.get("/sub/child/postInitChildFirstEvents").run().assertContent().is("['super-1a','super-1b','child-1c','super-2a','child-2b']");
+ b.get("/sub/lastCalled").run().assertContent().is("PARENT");
+ }
+}
diff --git a/juneau-utest/src/test/java/org/apache/juneau/rest/annotation/RestHookAnnotation_Test.java b/juneau-utest/src/test/java/org/apache/juneau/rest/annotation/RestPreCallAnnotation_Test.java
similarity index 86%
copy from juneau-utest/src/test/java/org/apache/juneau/rest/annotation/RestHookAnnotation_Test.java
copy to juneau-utest/src/test/java/org/apache/juneau/rest/annotation/RestPreCallAnnotation_Test.java
index 291c26cc3..1a84d69a9 100644
--- a/juneau-utest/src/test/java/org/apache/juneau/rest/annotation/RestHookAnnotation_Test.java
+++ b/juneau-utest/src/test/java/org/apache/juneau/rest/annotation/RestPreCallAnnotation_Test.java
@@ -20,30 +20,27 @@ import org.apache.juneau.*;
import org.junit.*;
@FixMethodOrder(NAME_ASCENDING)
-public class RestHookAnnotation_Test {
+public class RestPreCallAnnotation_Test {
- private static final String CNAME = RestHookAnnotation_Test.class.getName();
+ private static final String CNAME = RestPreCallAnnotation_Test.class.getName();
//------------------------------------------------------------------------------------------------------------------
// Basic tests
//------------------------------------------------------------------------------------------------------------------
- RestHook a1 = RestHookAnnotation.create()
+ RestPreCall a1 = RestPreCallAnnotation.create()
.on("a")
- .value(HookEvent.INIT)
.build();
- RestHook a2 = RestHookAnnotation.create()
+ RestPreCall a2 = RestPreCallAnnotation.create()
.on("a")
- .value(HookEvent.INIT)
.build();
@Test
public void a01_basic() {
assertObject(a1).asJson().is(""
+ "{"
- + "on:['a'],"
- + "value:'INIT'"
+ + "on:['a']"
+ "}"
);
}
@@ -80,7 +77,7 @@ public class RestHookAnnotation_Test {
@Test
public void c01_otherMethods() throws Exception {
- RestHook c4 = RestHookAnnotation.create().on(C1.class.getMethod("m1")).on(C2.class.getMethod("m2")).build();
+ RestPreCall c4 = RestPreCallAnnotation.create().on(C1.class.getMethod("m1")).on(C2.class.getMethod("m2")).build();
assertObject(c4).asJson().isContains("on:['"+CNAME+"$C1.m1()','"+CNAME+"$C2.m2()']");
}
@@ -89,19 +86,17 @@ public class RestHookAnnotation_Test {
// Comparison with declared annotations.
//------------------------------------------------------------------------------------------------------------------
- @RestHook(
- on="a",
- value=HookEvent.INIT
+ @RestPreCall(
+ on="a"
)
public static class D1 {}
- RestHook d1 = D1.class.getAnnotationsByType(RestHook.class)[0];
+ RestPreCall d1 = D1.class.getAnnotationsByType(RestPreCall.class)[0];
- @RestHook(
- on="a",
- value=HookEvent.INIT
+ @RestPreCall(
+ on="a"
)
public static class D2 {}
- RestHook d2 = D2.class.getAnnotationsByType(RestHook.class)[0];
+ RestPreCall d2 = D2.class.getAnnotationsByType(RestPreCall.class)[0];
@Test
public void d01_comparisonWithDeclarativeAnnotations() {
diff --git a/juneau-utest/src/test/java/org/apache/juneau/rest/annotation/Rest_Context_Test.java b/juneau-utest/src/test/java/org/apache/juneau/rest/annotation/RestPreCall_Test.java
similarity index 52%
copy from juneau-utest/src/test/java/org/apache/juneau/rest/annotation/Rest_Context_Test.java
copy to juneau-utest/src/test/java/org/apache/juneau/rest/annotation/RestPreCall_Test.java
index 96a9862c9..a39312939 100644
--- a/juneau-utest/src/test/java/org/apache/juneau/rest/annotation/Rest_Context_Test.java
+++ b/juneau-utest/src/test/java/org/apache/juneau/rest/annotation/RestPreCall_Test.java
@@ -12,93 +12,69 @@
// ***************************************************************************************************************************
package org.apache.juneau.rest.annotation;
-import static org.apache.juneau.assertions.Assertions.*;
import static org.junit.runners.MethodSorters.*;
-import org.apache.juneau.rest.*;
+import javax.servlet.http.*;
+
+import org.apache.juneau.collections.*;
+import org.apache.juneau.http.header.*;
+import org.apache.juneau.rest.RestRequest;
+import org.apache.juneau.rest.RestResponse;
+import org.apache.juneau.rest.client.*;
import org.apache.juneau.rest.mock.*;
import org.junit.*;
@FixMethodOrder(NAME_ASCENDING)
-public class Rest_Context_Test {
+public class RestPreCall_Test {
- public static class X1 extends RestContext {
- public X1(RestContext.Builder builder) throws Exception {
- super(builder);
- }
- }
+ //------------------------------------------------------------------------------------------------------------------
+ // @RestPreCall
+ //------------------------------------------------------------------------------------------------------------------
@Rest
- public static class A1 {
- @RestGet
- public String get(RestContext context) {
- return context.getClass().getSimpleName();
+ public static class A extends A_Parent {
+ private boolean pre3Called;
+ @RestPreCall
+ public void pre3() {
+ pre3Called = true;
}
- }
-
- @Test
- public void a01_default() throws Exception {
- MockRestClient a1 = client(A1.class);
- a1.get().run().assertContent().is("RestContext");
- }
-
- @Rest(contextClass=X1.class)
- public static class A2 extends A1 {}
-
- @Test
- public void a02_custom() throws Exception {
- MockRestClient a2 = client(A2.class);
- a2.get().run().assertContent().is("X1");
- }
-
- @Rest
- public static class A3 extends A2 {}
-
- @Test
- public void a03_notOverriddenByChild() throws Exception {
- MockRestClient a3 = client(A3.class);
- a3.get().run().assertContent().is("X1");
- }
-
- @Rest
- public static class A4 extends A1 {
- @RestHook(HookEvent.INIT)
- public void init(RestContext.Builder builder) throws Exception {
- builder.type(X1.class);
- }
- }
-
- @Test
- public void a04_definedInBuilder() throws Exception {
- MockRestClient a4 = client(A4.class);
- a4.get().run().assertContent().is("X1");
- }
-
-
- public static class X2 extends RestContext {
- public X2() throws Exception {
- super(null);
+ @RestPreCall
+ public void pre4(HttpServletRequest req, HttpServletResponse res) {
+ res.setHeader("pre3-called", ""+pre3Called);
+ pre3Called = false;
+ if (res.getHeader("pre4-called") != null)
+ throw new RuntimeException("pre4 called multiple times.");
+ res.setHeader("pre4-called", "true");
+ }
+ @RestGet(path="/")
+ public JsonMap a(RestRequest req, RestResponse res) {
+ return JsonMap.create()
+ .append("1", res.getHeader("pre1-called"))
+ .append("2", res.getHeader("pre2-called"))
+ .append("3", res.getHeader("pre3-called"))
+ .append("4", res.getHeader("pre4-called"));
}
}
- @Rest(contextClass=X2.class)
- public static class A5 {
- @RestGet
- public String get(RestContext context) {
- return context.getClass().getSimpleName();
+ public static class A_Parent {
+ private boolean pre1Called;
+ @RestPreCall
+ public void pre1() {
+ pre1Called = true;
+ }
+ @RestPreCall
+ public void pre2(Accept accept, RestRequest req, RestResponse res) {
+ res.setHeader("pre1-called", ""+pre1Called);
+ pre1Called = false;
+ if (res.getHeader("pre2-called") != null)
+ throw new RuntimeException("pre2 called multiple times.");
+ res.setHeader("pre2-called", "true");
}
}
@Test
- public void a05_invalidConstructor() throws Exception {
- assertThrown(()->client(A5.class)).asMessages().isContains("Could not instantiate RestContext.");
- }
-
- //------------------------------------------------------------------------------------------------------------------
- // Helper methods
- //------------------------------------------------------------------------------------------------------------------
-
- private static MockRestClient client(Class<?> c) {
- return MockRestClient.create(c).build();
+ public void a01_preCall() throws Exception {
+ RestClient a = MockRestClient.build(A.class);
+ a.get("/").run().assertContent().is("{'1':'true','2':'true','3':'true','4':'true'}");
}
}
diff --git a/juneau-utest/src/test/java/org/apache/juneau/rest/annotation/RestHookAnnotation_Test.java b/juneau-utest/src/test/java/org/apache/juneau/rest/annotation/RestStartCallAnnotation_Test.java
similarity index 86%
rename from juneau-utest/src/test/java/org/apache/juneau/rest/annotation/RestHookAnnotation_Test.java
rename to juneau-utest/src/test/java/org/apache/juneau/rest/annotation/RestStartCallAnnotation_Test.java
index 291c26cc3..72caff8e1 100644
--- a/juneau-utest/src/test/java/org/apache/juneau/rest/annotation/RestHookAnnotation_Test.java
+++ b/juneau-utest/src/test/java/org/apache/juneau/rest/annotation/RestStartCallAnnotation_Test.java
@@ -20,30 +20,27 @@ import org.apache.juneau.*;
import org.junit.*;
@FixMethodOrder(NAME_ASCENDING)
-public class RestHookAnnotation_Test {
+public class RestStartCallAnnotation_Test {
- private static final String CNAME = RestHookAnnotation_Test.class.getName();
+ private static final String CNAME = RestStartCallAnnotation_Test.class.getName();
//------------------------------------------------------------------------------------------------------------------
// Basic tests
//------------------------------------------------------------------------------------------------------------------
- RestHook a1 = RestHookAnnotation.create()
+ RestStartCall a1 = RestStartCallAnnotation.create()
.on("a")
- .value(HookEvent.INIT)
.build();
- RestHook a2 = RestHookAnnotation.create()
+ RestStartCall a2 = RestStartCallAnnotation.create()
.on("a")
- .value(HookEvent.INIT)
.build();
@Test
public void a01_basic() {
assertObject(a1).asJson().is(""
+ "{"
- + "on:['a'],"
- + "value:'INIT'"
+ + "on:['a']"
+ "}"
);
}
@@ -80,7 +77,7 @@ public class RestHookAnnotation_Test {
@Test
public void c01_otherMethods() throws Exception {
- RestHook c4 = RestHookAnnotation.create().on(C1.class.getMethod("m1")).on(C2.class.getMethod("m2")).build();
+ RestStartCall c4 = RestStartCallAnnotation.create().on(C1.class.getMethod("m1")).on(C2.class.getMethod("m2")).build();
assertObject(c4).asJson().isContains("on:['"+CNAME+"$C1.m1()','"+CNAME+"$C2.m2()']");
}
@@ -89,19 +86,17 @@ public class RestHookAnnotation_Test {
// Comparison with declared annotations.
//------------------------------------------------------------------------------------------------------------------
- @RestHook(
- on="a",
- value=HookEvent.INIT
+ @RestStartCall(
+ on="a"
)
public static class D1 {}
- RestHook d1 = D1.class.getAnnotationsByType(RestHook.class)[0];
+ RestStartCall d1 = D1.class.getAnnotationsByType(RestStartCall.class)[0];
- @RestHook(
- on="a",
- value=HookEvent.INIT
+ @RestStartCall(
+ on="a"
)
public static class D2 {}
- RestHook d2 = D2.class.getAnnotationsByType(RestHook.class)[0];
+ RestStartCall d2 = D2.class.getAnnotationsByType(RestStartCall.class)[0];
@Test
public void d01_comparisonWithDeclarativeAnnotations() {
diff --git a/juneau-utest/src/test/java/org/apache/juneau/rest/annotation/Rest_Context_Test.java b/juneau-utest/src/test/java/org/apache/juneau/rest/annotation/RestStartCall_Test.java
similarity index 52%
copy from juneau-utest/src/test/java/org/apache/juneau/rest/annotation/Rest_Context_Test.java
copy to juneau-utest/src/test/java/org/apache/juneau/rest/annotation/RestStartCall_Test.java
index 96a9862c9..fe306a606 100644
--- a/juneau-utest/src/test/java/org/apache/juneau/rest/annotation/Rest_Context_Test.java
+++ b/juneau-utest/src/test/java/org/apache/juneau/rest/annotation/RestStartCall_Test.java
@@ -12,93 +12,68 @@
// ***************************************************************************************************************************
package org.apache.juneau.rest.annotation;
-import static org.apache.juneau.assertions.Assertions.*;
import static org.junit.runners.MethodSorters.*;
-import org.apache.juneau.rest.*;
+import javax.servlet.http.*;
+
+import org.apache.juneau.collections.*;
+import org.apache.juneau.rest.RestRequest;
+import org.apache.juneau.rest.RestResponse;
+import org.apache.juneau.rest.client.*;
import org.apache.juneau.rest.mock.*;
import org.junit.*;
@FixMethodOrder(NAME_ASCENDING)
-public class Rest_Context_Test {
+public class RestStartCall_Test {
- public static class X1 extends RestContext {
- public X1(RestContext.Builder builder) throws Exception {
- super(builder);
- }
- }
+ //------------------------------------------------------------------------------------------------------------------
+ // @RestStartCall
+ //------------------------------------------------------------------------------------------------------------------
@Rest
- public static class A1 {
- @RestGet
- public String get(RestContext context) {
- return context.getClass().getSimpleName();
+ public static class A extends A_Parent {
+ private boolean start3Called;
+ @RestStartCall
+ public void start3() {
+ start3Called = true;
}
- }
-
- @Test
- public void a01_default() throws Exception {
- MockRestClient a1 = client(A1.class);
- a1.get().run().assertContent().is("RestContext");
- }
-
- @Rest(contextClass=X1.class)
- public static class A2 extends A1 {}
-
- @Test
- public void a02_custom() throws Exception {
- MockRestClient a2 = client(A2.class);
- a2.get().run().assertContent().is("X1");
- }
-
- @Rest
- public static class A3 extends A2 {}
-
- @Test
- public void a03_notOverriddenByChild() throws Exception {
- MockRestClient a3 = client(A3.class);
- a3.get().run().assertContent().is("X1");
- }
-
- @Rest
- public static class A4 extends A1 {
- @RestHook(HookEvent.INIT)
- public void init(RestContext.Builder builder) throws Exception {
- builder.type(X1.class);
- }
- }
-
- @Test
- public void a04_definedInBuilder() throws Exception {
- MockRestClient a4 = client(A4.class);
- a4.get().run().assertContent().is("X1");
- }
-
-
- public static class X2 extends RestContext {
- public X2() throws Exception {
- super(null);
+ @RestStartCall
+ public void start4(HttpServletRequest req, HttpServletResponse res) {
+ res.setHeader("start3-called", ""+start3Called);
+ start3Called = false;
+ if (res.getHeader("start4-called") != null)
+ throw new RuntimeException("start4 called multiple times.");
+ res.setHeader("start4-called", "true");
+ }
+ @RestGet(path="/")
+ public JsonMap a(RestRequest req, RestResponse res) {
+ return JsonMap.create()
+ .append("1", res.getHeader("start1-called"))
+ .append("2", res.getHeader("start2-called"))
+ .append("3", res.getHeader("start3-called"))
+ .append("4", res.getHeader("start4-called"));
}
}
- @Rest(contextClass=X2.class)
- public static class A5 {
- @RestGet
- public String get(RestContext context) {
- return context.getClass().getSimpleName();
+ public static class A_Parent {
+ private boolean start1Called;
+ @RestStartCall
+ public void start1() {
+ start1Called = true;
+ }
+ @RestStartCall
+ public void start2(HttpServletRequest req, HttpServletResponse res) {
+ res.setHeader("start1-called", ""+start1Called);
+ start1Called = false;
+ if (res.getHeader("start2-called") != null)
+ throw new RuntimeException("start2 called multiple times.");
+ res.setHeader("start2-called", "true");
}
}
@Test
- public void a05_invalidConstructor() throws Exception {
- assertThrown(()->client(A5.class)).asMessages().isContains("Could not instantiate RestContext.");
- }
-
- //------------------------------------------------------------------------------------------------------------------
- // Helper methods
- //------------------------------------------------------------------------------------------------------------------
-
- private static MockRestClient client(Class<?> c) {
- return MockRestClient.create(c).build();
+ public void a01_startCall() throws Exception {
+ RestClient a = MockRestClient.build(A.class);
+ a.get("/").run().assertContent().is("{'1':'true','2':'true','3':'true','4':'true'}");
}
}
diff --git a/juneau-utest/src/test/java/org/apache/juneau/rest/annotation/Rest_Context_Test.java b/juneau-utest/src/test/java/org/apache/juneau/rest/annotation/Rest_Context_Test.java
index 96a9862c9..4fb6bc0e6 100644
--- a/juneau-utest/src/test/java/org/apache/juneau/rest/annotation/Rest_Context_Test.java
+++ b/juneau-utest/src/test/java/org/apache/juneau/rest/annotation/Rest_Context_Test.java
@@ -62,10 +62,10 @@ public class Rest_Context_Test {
@Rest
public static class A4 extends A1 {
- @RestHook(HookEvent.INIT)
- public void init(RestContext.Builder builder) throws Exception {
- builder.type(X1.class);
- }
+ @RestInit
+ public void init(RestContext.Builder builder) throws Exception {
+ builder.type(X1.class);
+ }
}
@Test
diff --git a/juneau-utest/src/test/java/org/apache/juneau/rest/annotation/Rest_DefaultRequestAttributes_Test.java b/juneau-utest/src/test/java/org/apache/juneau/rest/annotation/Rest_DefaultRequestAttributes_Test.java
new file mode 100644
index 000000000..1d5384287
--- /dev/null
+++ b/juneau-utest/src/test/java/org/apache/juneau/rest/annotation/Rest_DefaultRequestAttributes_Test.java
@@ -0,0 +1,184 @@
+// ***************************************************************************************************************************
+// * 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.annotation;
+
+import static java.util.Collections.*;
+import static org.apache.juneau.internal.CollectionUtils.*;
+import static org.junit.runners.MethodSorters.*;
+
+import java.util.*;
+
+import org.apache.juneau.collections.*;
+import org.apache.juneau.http.annotation.Content;
+import org.apache.juneau.parser.*;
+import org.apache.juneau.rest.RestRequest;
+import org.apache.juneau.rest.RestResponse;
+import org.apache.juneau.rest.client.*;
+import org.apache.juneau.rest.httppart.*;
+import org.apache.juneau.rest.mock.*;
+import org.apache.juneau.serializer.*;
+import org.apache.juneau.testutils.*;
+import org.junit.*;
+
+@FixMethodOrder(NAME_ASCENDING)
+public class Rest_DefaultRequestAttributes_Test {
+
+ //------------------------------------------------------------------------------------------------------------------
+ // @RestPreCall
+ //------------------------------------------------------------------------------------------------------------------
+
+ @Rest(
+ parsers=A1.class,
+ defaultRequestAttributes={
+ "p1:sp1", // Unchanged servlet-level property.
+ "p2:sp2", // Servlet-level property overridden by onPreCall.
+ "p3:sp3", // Servlet-level property overridded by method.
+ "p4:sp4" // Servlet-level property overridden by method then onPreCall.
+ }
+ )
+ public static class A {
+
+ @RestPreCall
+ public void onPreCall(RestRequest req) {
+ RequestAttributes attrs = req.getAttributes();
+ attrs.set("p2", "xp2");
+ attrs.set("p4", "xp4");
+ attrs.set("p5", "xp5"); // New property
+ String overrideContentType = req.getHeader("Override-Content-Type").orElse(null);
+ if (overrideContentType != null)
+ req.getHeaders().set("Content-Type", overrideContentType);
+ }
+
+ @RestPut(
+ defaultRequestAttributes={
+ "p3:mp3",
+ "p4:mp4"
+ }
+ )
+ public String a(@Content String in) {
+ return in;
+ }
+
+ @RestPut
+ public String b(RestRequest req, RequestAttributes attrs) throws Exception {
+ attrs.set("p3", "pp3");
+ attrs.set("p4", "pp4");
+ return req.getContent().as(String.class);
+ }
+ }
+
+ public static class A1 extends MockReaderParser {
+ public A1(MockReaderParser.Builder b) {
+ super(b.consumes("text/a1,text/a2,text/a3").function((session,in,type)->in(session)));
+ }
+
+ private static Object in(ReaderParserSession session) {
+ JsonMap sp = session.getSessionProperties();
+ return "p1="+sp.get("p1",null)+",p2="+sp.get("p2",null)+",p3="+sp.get("p3",null)+",p4="+sp.get("p4",null)+",p5="+sp.get("p5",null);
+
+ }
+ }
+
+ @Test
+ public void a01_preCall() throws Exception {
+ RestClient a = MockRestClient.build(A.class);
+ a.put("/a", null).contentType("text/a1").run().assertContent().is("p1=sp1,p2=xp2,p3=mp3,p4=xp4,p5=xp5");
+ a.put("/a", null).contentType("text/a1").header("Override-Content-Type", "text/a2").run().assertContent().is("p1=sp1,p2=xp2,p3=mp3,p4=xp4,p5=xp5");
+ a.put("/b", null).contentType("text/a1").run().assertContent().is("p1=sp1,p2=xp2,p3=pp3,p4=pp4,p5=xp5");
+ a.put("/b", null).contentType("text/a1").header("Override-Content-Type", "text/a2").run().assertContent().is("p1=sp1,p2=xp2,p3=pp3,p4=pp4,p5=xp5");
+ }
+
+ //------------------------------------------------------------------------------------------------------------------
+ // @RestPostCall
+ //------------------------------------------------------------------------------------------------------------------
+
+ @Rest(
+ serializers=B1.class,
+ defaultRequestAttributes={
+ "p1:sp1", // Unchanged servlet-level property.
+ "p2:sp2", // Servlet-level property overridden by onPostCall.
+ "p3:sp3", // Servlet-level property overridded by method.
+ "p4:sp4" // Servlet-level property overridden by method then onPostCall.
+ }
+ )
+ public static class B {
+
+ @RestPostCall
+ public void onPostCall(RestRequest req, RestResponse res) {
+ RequestAttributes attrs = req.getAttributes();
+ attrs.set("p2", "xp2");
+ attrs.set("p4", "xp4");
+ attrs.set("p5", "xp5"); // New property
+ String overrideAccept = req.getHeader("Override-Accept").orElse(null);
+ if (overrideAccept != null)
+ req.getHeaders().set("Accept", overrideAccept);
+ String overrideContentType = req.getHeader("Override-Content-Type").orElse(null);
+ if (overrideContentType != null)
+ attrs.set("Override-Content-Type", overrideContentType);
+ }
+
+ @RestPut(
+ defaultRequestAttributes={
+ "p3:mp3",
+ "p4:mp4"
+ },
+ defaultRequestHeaders="Accept: text/s2"
+ )
+ public String a() {
+ return null;
+ }
+
+ @RestPut
+ public String b(RestRequest req, RequestAttributes attrs) throws Exception {
+ attrs.set("p3", "pp3");
+ attrs.set("p4", "pp4");
+ String accept = req.getHeader("Accept").orElse(null);
+ if (accept == null || accept.isEmpty())
+ req.getHeaders().set("Accept", "text/s2");
+ return null;
+ }
+ }
+
+ public static class B1 extends MockWriterSerializer {
+ public B1(MockWriterSerializer.Builder b) {
+ super(b.produces("test/s1").accept("text/s1,text/s2,text/s3").function((s,o) -> out(s)).headers(s->headers(s)));
+ }
+ public static String out(SerializerSession s) {
+ JsonMap sp = s.getSessionProperties();
+ return "p1="+sp.get("p1",null)+",p2="+sp.get("p2",null)+",p3="+sp.get("p3",null)+",p4="+sp.get("p4",null)+",p5="+sp.get("p5",null);
+ }
+ public static Map<String,String> headers(SerializerSession s) {
+ JsonMap sp = s.getSessionProperties();
+ if (sp.containsKey("Override-Content-Type"))
+ return map("Content-Type",sp.getString("Override-Content-Type",null));
+ return emptyMap();
+ }
+ }
+
+ @Test
+ public void b01_postCall() throws Exception {
+ RestClient b = MockRestClient.build(B.class);
+ b.put("/a", null).accept("text/s1").run().assertContent().is("p1=sp1,p2=xp2,p3=mp3,p4=xp4,p5=xp5");
+ b.put("/a", null).accept("text/s1").header("Override-Accept", "text/s2").run().assertContent().is("p1=sp1,p2=xp2,p3=mp3,p4=xp4,p5=xp5");
+ b.put("/a", null).accept("text/s1").header("Override-Content-Type", "text/s3").run().assertContent().is("p1=sp1,p2=xp2,p3=mp3,p4=xp4,p5=xp5");
+ b.put("/a", null).run().assertContent().is("p1=sp1,p2=xp2,p3=mp3,p4=xp4,p5=xp5");
+ b.put("/a", null).header("Override-Accept", "text/s3").run().assertContent().is("p1=sp1,p2=xp2,p3=mp3,p4=xp4,p5=xp5");
+ b.put("/a", null).header("Override-Content-Type", "text/s3").run().assertContent().is("p1=sp1,p2=xp2,p3=mp3,p4=xp4,p5=xp5");
+ b.put("/b", null).accept("text/s1").run().assertContent().is("p1=sp1,p2=xp2,p3=pp3,p4=xp4,p5=xp5");
+ b.put("/b", null).accept("text/s1").header("Override-Accept", "text/s2").run().assertContent().is("p1=sp1,p2=xp2,p3=pp3,p4=xp4,p5=xp5");
+ b.put("/b", null).accept("text/s1").header("Override-Content-Type", "text/s3").run().assertContent().is("p1=sp1,p2=xp2,p3=pp3,p4=xp4,p5=xp5");
+ b.put("/b", null).run().assertContent().is("p1=sp1,p2=xp2,p3=pp3,p4=xp4,p5=xp5");
+ b.put("/b", null).header("Override-Accept", "text/s3").run().assertContent().is("p1=sp1,p2=xp2,p3=pp3,p4=xp4,p5=xp5");
+ b.put("/b", null).header("Override-Content-Type", "text/s3").run().assertContent().is("p1=sp1,p2=xp2,p3=pp3,p4=xp4,p5=xp5");
+ }
+}
diff --git a/juneau-utest/src/test/java/org/apache/juneau/rest/annotation/Rest_Messages_Test.java b/juneau-utest/src/test/java/org/apache/juneau/rest/annotation/Rest_Messages_Test.java
index 04c566b6b..3802ac335 100644
--- a/juneau-utest/src/test/java/org/apache/juneau/rest/annotation/Rest_Messages_Test.java
+++ b/juneau-utest/src/test/java/org/apache/juneau/rest/annotation/Rest_Messages_Test.java
@@ -101,10 +101,10 @@ public class Rest_Messages_Test {
}
public static class B3 extends B1 {
- @RestHook(HookEvent.INIT)
- public void init(RestContext.Builder builder) throws Exception {
- builder.messages().location(null, "B2x").location(B1.class, "B1x");
- }
+ @RestInit
+ public void init(RestContext.Builder builder) throws Exception {
+ builder.messages().location(null, "B2x").location(B1.class, "B1x");
+ }
}
@Test