Repository: incubator-juneau
Updated Branches:
  refs/heads/master 50baa1e20 -> 6d63a4183


http://git-wip-us.apache.org/repos/asf/incubator-juneau/blob/6d63a418/juneau-rest/src/main/java/org/apache/juneau/rest/RestServlet.java
----------------------------------------------------------------------
diff --git a/juneau-rest/src/main/java/org/apache/juneau/rest/RestServlet.java 
b/juneau-rest/src/main/java/org/apache/juneau/rest/RestServlet.java
index fc9ff2e..0c691d0 100644
--- a/juneau-rest/src/main/java/org/apache/juneau/rest/RestServlet.java
+++ b/juneau-rest/src/main/java/org/apache/juneau/rest/RestServlet.java
@@ -48,12 +48,11 @@ public abstract class RestServlet extends HttpServlet {
        public final synchronized void init(ServletConfig servletConfig) throws 
ServletException {
                try {
                        RestConfig rsc = new RestConfig(servletConfig, 
this.getClass(), null);
-                       init(rsc);
-                       if (! isInitialized) {
-                               // Subclass may not have called 
super.init(RestServletConfig), so initialize here.
-                               createContext(rsc);
-                               super.init(servletConfig);
-                       }
+                       rsc.init(this);
+                       RestContext context = createContext(rsc);
+                       super.init(servletConfig);
+                       context.postInit();
+                       context.postInitChildFirst();
                } catch (RestException e) {
                        // Thrown RestExceptions are simply caught and 
re-thrown on subsequent calls to service().
                        initException = e;
@@ -75,33 +74,21 @@ public abstract class RestServlet extends HttpServlet {
                }
        }
 
-       /**
-        * Resource initialization method.
-        *
-        * <p>
-        * Identical to {@link Servlet#init(ServletConfig)} except the config 
object provides access to the external config
-        * file, configuration properties, and variable resolver defined for 
this resource.
-        *
-        * <p>
-        * Classes can also use {@link HttpServlet#init()} and {@link 
RestServlet#getServletConfig()} as well to perform
-        * initialization.
-        *
-        * <p>
-        * Note that if you override this method, you must first call 
<code><jk>super</jk>.init(servletConfig)</code>!
-        *
-        * <p>
-        * Resource classes that don't extend from {@link RestServlet} can add 
this method to their class to get access to
-        * the config object.
-        *
-        * @param config The servlet configuration.
-        * @throws Exception Any exception can be thrown to signal an 
initialization failure.
+       /*
+        * Bypasses the init(ServletConfig) method and just calls the 
super.init(ServletConfig) method directly.
+        * Used when subclasses of RestServlet are attached as child resources.
         */
-       public synchronized void init(RestConfig config) throws Exception {
-               if (isInitialized)
-                       return;
-               createContext(config);
-               super.init(config);
-               init(context);
+       void innerInit(ServletConfig servletConfig) throws ServletException {
+               super.init(servletConfig);
+       }
+
+       /*
+        * Sets the context object for this servlet.
+        * Used when subclasses of RestServlet are attached as child resources.
+        */
+       void setContext(RestContext context) {
+               this.config = context.config;
+               this.context = context;
        }
 
        /**
@@ -120,12 +107,13 @@ public abstract class RestServlet extends HttpServlet {
        public synchronized void init(RestContext context) throws Exception {}
 
 
-       private synchronized void createContext(RestConfig config) throws 
Exception {
-               if (isInitialized)
-                       return;
-               this.config = config;
-               this.context = new RestContext(this, this.getServletContext(), 
config);
-               this.isInitialized = true;
+       private synchronized RestContext createContext(RestConfig config) 
throws Exception {
+               if (! isInitialized) {
+                       this.config = config;
+                       this.context = new RestContext(this, 
this.getServletContext(), config);
+                       this.isInitialized = true;
+               }
+               return context;
        }
 
 
@@ -142,7 +130,6 @@ public abstract class RestServlet extends HttpServlet {
        @Override /* Servlet */
        public void service(HttpServletRequest r1, HttpServletResponse r2) 
throws ServletException, IOException {
                try {
-
                        if (initException != null) {
                                if (initException instanceof RestException)
                                        throw (RestException)initException;
@@ -166,7 +153,7 @@ public abstract class RestServlet extends HttpServlet {
         * Returns the read-only context object that contains all the 
configuration information about this resource.
         *
         * <p>
-        * This object is <jk>null</jk> during the call to {@link 
#init(RestConfig)} but is populated by the time
+        * This object is <jk>null</jk> during the call to {@link 
#init(ServletConfig)} but is populated by the time
         * {@link #init()} is called.
         *
         * <p>
@@ -183,59 +170,6 @@ public abstract class RestServlet extends HttpServlet {
        }
 
        /**
-        * Callback method for listening for successful completion of requests.
-        *
-        * <p>
-        * Subclasses can override this method for gathering performance 
statistics.
-        *
-        * <p>
-        * The default implementation does nothing.
-        *
-        * <p>
-        * Resources that don't extend from {@link RestServlet} can implement 
an equivalent method by overriding the
-        * {@link RestCallHandler#onSuccess(RestRequest, RestResponse, long)} 
method.
-        *
-        * @param req The HTTP request.
-        * @param res The HTTP response.
-        * @param time The time in milliseconds it took to process the request.
-        */
-       protected void onSuccess(RestRequest req, RestResponse res, long time) 
{}
-
-       /**
-        * Callback method that gets invoked right before the REST Java method 
is invoked.
-        *
-        * <p>
-        * Subclasses can override this method to override request headers or 
set request-duration properties before the
-        * Java method is invoked.
-        *
-        * <p>
-        * Resources that don't extend from {@link RestServlet} can implement 
an equivalent method by overriding the
-        * {@link RestCallHandler#onPreCall(RestRequest)} method.
-        *
-        * @param req The HTTP servlet request object.
-        * @throws RestException If any error occurs.
-        */
-       protected void onPreCall(RestRequest req) throws RestException {}
-
-       /**
-        * Callback method that gets invoked right after the REST Java method 
is invoked, but before the serializer is
-        * invoked.
-        *
-        * <p>
-        * Subclasses can override this method to override request and response 
headers, or set/override properties used by
-        * the serializer.
-        *
-        * <p>
-        * Resources that don't extend from {@link RestServlet} can implement 
an equivalent method by overriding the
-        * {@link RestCallHandler#onPostCall(RestRequest,RestResponse)} method.
-        *
-        * @param req The HTTP servlet request object.
-        * @param res The HTTP servlet response object.
-        * @throws RestException If any error occurs.
-        */
-       protected void onPostCall(RestRequest req, RestResponse res) throws 
RestException {}
-
-       /**
         * Convenience method for calling 
<code>getContext().getLogger().log(level, msg, args);</code>
         *
         * @param level The log level.

http://git-wip-us.apache.org/repos/asf/incubator-juneau/blob/6d63a418/juneau-rest/src/main/java/org/apache/juneau/rest/annotation/HookEvent.java
----------------------------------------------------------------------
diff --git 
a/juneau-rest/src/main/java/org/apache/juneau/rest/annotation/HookEvent.java 
b/juneau-rest/src/main/java/org/apache/juneau/rest/annotation/HookEvent.java
new file mode 100644
index 0000000..74684e8
--- /dev/null
+++ b/juneau-rest/src/main/java/org/apache/juneau/rest/annotation/HookEvent.java
@@ -0,0 +1,419 @@
+// 
***************************************************************************************************************************
+// * 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.dto.swagger.*;
+import org.apache.juneau.http.*;
+import org.apache.juneau.ini.*;
+import org.apache.juneau.internal.*;
+import org.apache.juneau.rest.*;
+import org.apache.juneau.utils.*;
+
+/**
+ * Identifies servlet and REST call lifecycle events which cause {@link 
RestHook @RestHook}-annotated Java methods
+ * to be called.
+ */
+public enum HookEvent {
+
+       /**
+        * Identifies a method that should be called immediately after the 
<code>HttpServlet.service(HttpServletRequest, HttpServletResponse)</code>
+        * 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>
+        *
+        * <h6 class='figure'>Example:</h6>
+        * <p class='bcode'>
+        *      <ja>@RestResource</ja>(...)
+        *      <jk>public class</jk> MyResource <jk>extends</jk> 
RestServletDefault {
+        *
+        *              <jc>// Add a request attribute to all incoming 
requests.</jc>
+        *              <ja>@RestHook</ja>(<jsf>START_CALL</jsf>)
+        *              <jk>public void</jk> onStartCall(HttpServletRequest 
req) {
+        *                      req.setAttribute(<js>"foobar"</js>, 
<jk>new</jk> FooBar());
+        *              }
+        *      }
+        * </p>
+        *
+        * <h5 class='section'>Notes:</h5>
+        * <ul class='spaced-list'>
+        *      <li>If the method returns any value, it is ignored.
+        *      <li>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>The method can throw any exception.
+        *              <br>{@link RestException RestExceptions} can be thrown 
to cause a particular HTTP error status code.
+        *              <br>All other exceptions cause an HTTP 500 error status 
code.
+        *      <li>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>@RestMethod</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.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 MessageBundle}
+        *                      <li>{@link InputStream}
+        *                      <li>{@link ServletInputStream}
+        *                      <li>{@link Reader}
+        *                      <li>{@link OutputStream}
+        *                      <li>{@link ServletOutputStream}
+        *                      <li>{@link Writer}
+        *                      <li>{@link RequestHeaders}
+        *                      <li>{@link RequestQuery}
+        *                      <li>{@link RequestFormData}
+        *                      <li>{@link HttpMethod}
+        *                      <li>{@link Logger}
+        *                      <li>{@link JuneauLogger}
+        *                      <li>{@link RestContext}
+        *                      <li>{@link org.apache.juneau.parser.Parser}
+        *                      <li>{@link Locale}
+        *                      <li>{@link Swagger}
+        *                      <li>{@link RequestPathMatch}
+        *                      <li>{@link RequestBody}
+        *                      <li>{@link ConfigFile}
+        *                      <li>{@link UriContext}
+        *                      <li>{@link UriResolver}
+        *              </ul>
+        * </ul>
+        *
+        * <h6 class='figure'>Example:</h6>
+        * <p class='bcode'>
+        *      <ja>@RestResource</ja>(...)
+        *      <jk>public class</jk> MyResource <jk>extends</jk> 
RestServletDefault {
+        *
+        *              <jc>// Log the incoming request.</jc>
+        *              <ja>@RestHook</ja>(<jsf>PRE_CALL</jsf>)
+        *              <jk>public void</jk> onPreCall(Accept accept, Logger 
logger) {
+        *                      logger.fine(<js>"Accept {0} header 
found."</js>, accept);
+        *              }
+        *      }
+        * </p>
+        *
+        * <h5 class='section'>Notes:</h5>
+        * <ul class='spaced-list'>
+        *      <li>If the method returns any value, it is ignored.
+        *      <li>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>The method can throw any exception.
+        *              <br>{@link RestException RestExceptions} can be thrown 
to cause a particular HTTP error status code.
+        *              <br>All other exceptions cause an HTTP 500 error status 
code.
+        *      <li>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>It's advisable not to mess around with the HTTP body itself 
since you may end up consuming the body
+        *              before the actual REST method has a chance to use it.
+        * </ul>
+        */
+       PRE_CALL,
+
+       /**
+        * Identifies a method that gets called immediately after the 
<ja>@RestMethod</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}.
+        *
+        * <h6 class='figure'>Example:</h6>
+        * <p class='bcode'>
+        *      <ja>@RestResource</ja>(...)
+        *      <jk>public class</jk> MyResource <jk>extends</jk> 
RestServletDefault {
+        *
+        *              <jc>// Log the result of the request.</jc>
+        *              <ja>@RestHook</ja>(<jsf>POST_CALL</jsf>)
+        *              <jk>public void</jk> onPostCall(RestResponse res, 
Logger logger) {
+        *                      logger.fine(<js>Output {0} was set on the 
response."</js>, res.getOutput());
+        *              }
+        *      }
+        * </p>
+        *
+        * <h5 class='section'>Notes:</h5>
+        * <ul class='spaced-list'>
+        *      <li>If the method returns any value, it is ignored.
+        *      <li>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>The method can throw any exception, although at this point 
it is too late to set an HTTP error status code.
+        *      <li>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>
+        *
+        * <h6 class='figure'>Example:</h6>
+        * <p class='bcode'>
+        *      <ja>@RestResource</ja>(...)
+        *      <jk>public class</jk> MyResource <jk>extends</jk> 
RestServletDefault {
+        *
+        *              <jc>// Log the time it took to execute the request.</jc>
+        *              <ja>@RestHook</ja>(<jsf>END_CALL</jsf>)
+        *              <jk>public void</jk> onEndCall(RestRequest req, Logger 
logger) {
+        *                      Exception e = 
(Exception)req.getAttribute(<js>"Exception"</js>);
+        *                      Long execTime = 
(Long)req.getAttribute(<js>"ExecTime"</js>);
+        *                      <jk>if</jk> (e != <jk>null</jk>)
+        *                              logger.warn(e, <js>"Request failed in 
{0}ms."</js>, execTime);
+        *                      <jk>else</jk>
+        *                              logger.fine(<js>"Request finished in 
{0}ms."</js>, execTime);
+        *              }
+        *      }
+        * </p>
+        *
+        * <h5 class='section'>Notes:</h5>
+        * <ul class='spaced-list'>
+        *      <li>If the method returns any value, it is ignored.
+        *      <li>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>The method can throw any exception, although at this point 
it is too late to set an HTTP error status code.
+        *      <li>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 RestConfig}
+        * 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 RestConfig} 
which can be used to configure the servlet.
+        *
+        * <p>
+        * An example of this is the <code>PetStoreResource</code> class that 
uses an init method to perform initialization
+        * of an internal data structure.
+        *
+        * <h6 class='figure'>Example:</h6>
+        * <p class='bcode'>
+        *      <ja>@RestResource</ja>(...)
+        *      <jk>public class</jk> PetStoreResource <jk>extends</jk> 
ResourceJena {
+        *
+        *              <jc>// Our database.</jc>
+        *              <jk>private</jk> Map<Integer,Pet> <jf>petDB</jf>;
+        *
+        *              <ja>@RestHook</ja>(<jsf>INIT</jsf>)
+        *              <jk>public void</jk> onInit(RestConfig config) 
<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>
+        *
+        * <h5 class='section'>Notes:</h5>
+        * <ul class='spaced-list'>
+        *      <li>If the method returns any value, it is ignored.
+        *      <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.
+        *      <li>The method can throw any exception causing initialization 
of the servlet to fail.
+        *      <li>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.
+        *
+        * <h5 class='section'>Notes:</h5>
+        * <ul class='spaced-list'>
+        *      <li>If the method returns any value, it is ignored.
+        *      <li>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>The method can throw any exception causing initialization 
of the servlet to fail.
+        *      <li>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.
+        *
+        * <h5 class='section'>Notes:</h5>
+        * <ul class='spaced-list'>
+        *      <li>If the method returns any value, it is ignored.
+        *      <li>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>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.
+        *
+        * <h6 class='figure'>Example:</h6>
+        * <p class='bcode'>
+        *      <ja>@RestResource</ja>(...)
+        *      <jk>public class</jk> PetStoreResource <jk>extends</jk> 
ResourceJena {
+        *
+        *              <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>
+        *
+        * <h5 class='section'>Notes:</h5>
+        * <ul class='spaced-list'>
+        *      <li>If the method returns any value, it is ignored.
+        *      <li>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>In general, destroy methods should not throw any 
exceptions, although if any are thrown, the stack trace will be
+        *              printed to <code>System.err</code>.
+        *      <li>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
+}

http://git-wip-us.apache.org/repos/asf/incubator-juneau/blob/6d63a418/juneau-rest/src/main/java/org/apache/juneau/rest/annotation/RestHook.java
----------------------------------------------------------------------
diff --git 
a/juneau-rest/src/main/java/org/apache/juneau/rest/annotation/RestHook.java 
b/juneau-rest/src/main/java/org/apache/juneau/rest/annotation/RestHook.java
new file mode 100644
index 0000000..828df43
--- /dev/null
+++ b/juneau-rest/src/main/java/org/apache/juneau/rest/annotation/RestHook.java
@@ -0,0 +1,86 @@
+// 
***************************************************************************************************************************
+// * 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.*;
+
+/**
+ * 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='bcode'>
+ *     <ja>@RestResource</ja>(...)
+ *     <jk>public class</jk> MyResource  {
+ *
+ *             <jc>// Our database.</jc>
+ *             <jk>private</jk> Map&lt;Integer,Object&gt; <jf>myDatabase</jf>;
+ *
+ *             <ja>@RestHook</ja>(<jsf>INIT</jsf>)
+ *             <jk>public void</jk> initMyDatabase(RestConfig config) 
<jk>throws</jk> Exception {
+ *                     <jf>myDatabase</jf> = <jk>new</jk> 
LinkedHashMap&lt;&gt;();
+ *             }
+ *     }
+ * </p>
+ *
+ * <p>
+ * Or if you want to intercept REST calls:
+ * <p class='bcode'>
+ *     <ja>@RestResource</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 req) {
+ *                     req.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>@RestMethod</ja> method is invoked.
+ *                     <li>{@link HookEvent#POST_CALL POST_CALL} - Right after 
the <ja>@RestMethod</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>
+ *
+ * <p>
+ * See the {@link HookEvent} class for information about individual event 
types.
+ */
+@Documented
+@Target(METHOD)
+@Retention(RUNTIME)
+@Inherited
+public @interface RestHook {
+
+       /**
+        * The lifecycle event.
+        */
+       HookEvent value();
+}

http://git-wip-us.apache.org/repos/asf/incubator-juneau/blob/6d63a418/juneau-rest/src/main/java/org/apache/juneau/rest/package.html
----------------------------------------------------------------------
diff --git a/juneau-rest/src/main/java/org/apache/juneau/rest/package.html 
b/juneau-rest/src/main/java/org/apache/juneau/rest/package.html
index 8097a17..e3f1427 100644
--- a/juneau-rest/src/main/java/org/apache/juneau/rest/package.html
+++ b/juneau-rest/src/main/java/org/apache/juneau/rest/package.html
@@ -2485,28 +2485,9 @@
        <h3 class='topic' onclick='toggle(this)'>4.16 - Listener Methods</h3>   
        <div class='topic'>
                <p>
-                       Various convenience listener methods are provided on 
the {@link org.apache.juneau.rest.RestCallHandler} 
-                       class that subclasses can use to intercept requests:
+                       Various convenience listener methods can be implemented 
by using the {@link org.apache.juneau.rest.annotation.RestHook @RestHook}
+                       annotation on methods in your resource class.
                </p>
-               <ul class='doctree'>
-                       <li class='jac'>
-                               {@link org.apache.juneau.rest.RestCallHandler}
-                               <ul>
-                                       <li class='jm'>
-                                               {@link 
org.apache.juneau.rest.RestCallHandler#onPreCall(RestRequest) 
onPreCall(RestRequest)}
-                                               <br>Callback method that gets 
invoked right before the REST Java method is invoked.
-                                       <li class='jm'>
-                                               {@link 
org.apache.juneau.rest.RestCallHandler#onPostCall(RestRequest,RestResponse) 
onPostCall(RestRequest,RestResponse)}
-                                               <br>Callback method that gets 
invoked right after the REST Java method is invoked, but before the serializer 
is invoked.
-                                       <li class='jm'>
-                                               {@link 
org.apache.juneau.rest.RestCallHandler#onSuccess(RestRequest,RestResponse,long) 
onSuccess(RestRequest,RestResponse,long)}
-                                               <br>Callback method for 
listening for successful completion of requests.
-                                       <li class='jm'>
-                                               {@link 
org.apache.juneau.rest.RestLogger#onError(HttpServletRequest,HttpServletResponse,RestException)
 onError(HttpServletRequest,HttpServletResponse,RestException)}
-                                               <br>Callback method for logging 
errors during HTTP requests.
-                               </ul>
-                       </li>
-               </ul>
        </div>
 
        <!-- 
========================================================================================================
 -->

Reply via email to