001// ***************************************************************************************************************************
002// * Licensed to the Apache Software Foundation (ASF) under one or more contributor license agreements.  See the NOTICE file *
003// * distributed with this work for additional information regarding copyright ownership.  The ASF licenses this file        *
004// * to you under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance            *
005// * with the License.  You may obtain a copy of the License at                                                              *
006// *                                                                                                                         *
007// *  http://www.apache.org/licenses/LICENSE-2.0                                                                             *
008// *                                                                                                                         *
009// * Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an  *
010// * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.  See the License for the        *
011// * specific language governing permissions and limitations under the License.                                              *
012// ***************************************************************************************************************************
013package org.apache.juneau.rest.annotation;
014
015import java.io.*;
016import java.util.*;
017import java.util.logging.*;
018
019import javax.servlet.*;
020import javax.servlet.http.*;
021
022import org.apache.juneau.*;
023import org.apache.juneau.config.*;
024import org.apache.juneau.dto.swagger.*;
025import org.apache.juneau.http.*;
026import org.apache.juneau.internal.*;
027import org.apache.juneau.rest.*;
028import org.apache.juneau.utils.*;
029
030/**
031 * Identifies servlet and REST call lifecycle events which cause {@link RestHook @RestHook}-annotated Java methods
032 * to be called.
033 *
034 * <ul class='seealso'>
035 *    <li class='link'>{@doc juneau-rest-server.Instantiation.LifecycleHooks}
036 * </ul>
037 */
038public enum HookEvent {
039
040   /**
041    * Identifies a method that should be called immediately after the <c>HttpServlet.service(HttpServletRequest, HttpServletResponse)</c>
042    * method is called.
043    *
044    * <p>
045    * Note that you only have access to the raw request and response objects at this point.
046    *
047    * <p>
048    * The list of valid parameter types are as follows:
049    * <ul>
050    *    <li>Servlet request/response objects:
051    *       <ul>
052    *          <li>{@link HttpServletRequest}
053    *          <li>{@link HttpServletResponse}
054    *       </ul>
055    * </ul>
056    *
057    * <h5 class='figure'>Example:</h5>
058    * <p class='bcode w800'>
059    *    <ja>@RestResource</ja>(...)
060    *    <jk>public class</jk> MyResource <jk>extends</jk> BasicRestServlet {
061    *
062    *       <jc>// Add a request attribute to all incoming requests.</jc>
063    *       <ja>@RestHook</ja>(<jsf>START_CALL</jsf>)
064    *       <jk>public void</jk> onStartCall(HttpServletRequest req) {
065    *          req.setAttribute(<js>"foobar"</js>, <jk>new</jk> FooBar());
066    *       }
067    *    }
068    * </p>
069    *
070    * <ul class='notes'>
071    *    <li>
072    *       The method should return <jk>void</jk> although if it does return any value, the value will be ignored.
073    *    <li>
074    *       The method should be <jk>public</jk> although other visibilities are valid if the security manager allows it.
075    *    <li>
076    *       Static methods can be used.
077    *    <li>
078    *       Multiple START_CALL methods can be defined on a class.
079    *       <br>START_CALL methods on parent classes are invoked before START_CALL methods on child classes.
080    *       <br>The order of START_CALL method invocations within a class is alphabetical, then by parameter count, then by parameter types.
081    *    <li>
082    *       The method can throw any exception.
083    *       <br>{@link RestException RestExceptions} can be thrown to cause a particular HTTP error status code.
084    *       <br>All other exceptions cause an HTTP 500 error status code.
085    *    <li>
086    *       Note that if you override a parent method, you probably need to call <code><jk>super</jk>.parentMethod(...)</code>.
087    *       <br>The method is still considered part of the parent class for ordering purposes even though it's
088    *       overridden by the child class.
089    * </ul>
090    */
091   START_CALL,
092
093   /**
094    * Identifies a method that gets called immediately before the <ja>@RestMethod</ja> annotated method gets called.
095    *
096    * <p>
097    * At this point, the {@link RestRequest} object has been fully initialized, and all {@link RestGuard} and
098    * {@link RestMatcher} objects have been called.
099    *
100    * <p>
101    * The list of valid parameter types are as follows:
102    * <ul>
103    *    <li>Servlet request/response objects:
104    *       <ul>
105    *          <li>{@link HttpServletRequest}
106    *          <li>{@link HttpServletResponse}
107    *       </ul>
108    *    <li>Extended request/response objects:
109    *       <ul>
110    *          <li>{@link RestRequest}
111    *          <li>{@link RestResponse}
112    *       </ul>
113    *    <li>Header objects:
114    *       <ul>
115    *          <li>{@link Accept}
116    *          <li>{@link AcceptCharset}
117    *          <li>{@link AcceptEncoding}
118    *          <li>{@link AcceptLanguage}
119    *          <li>{@link Authorization}
120    *          <li>{@link CacheControl}
121    *          <li>{@link Connection}
122    *          <li>{@link ContentLength}
123    *          <li>{@link ContentType}
124    *          <li>{@link org.apache.juneau.http.Date}
125    *          <li>{@link Expect}
126    *          <li>{@link From}
127    *          <li>{@link Host}
128    *          <li>{@link IfMatch}
129    *          <li>{@link IfModifiedSince}
130    *          <li>{@link IfNoneMatch}
131    *          <li>{@link IfRange}
132    *          <li>{@link IfUnmodifiedSince}
133    *          <li>{@link MaxForwards}
134    *          <li>{@link Pragma}
135    *          <li>{@link ProxyAuthorization}
136    *          <li>{@link Range}
137    *          <li>{@link Referer}
138    *          <li>{@link TE}
139    *          <li>{@link UserAgent}
140    *          <li>{@link Upgrade}
141    *          <li>{@link Via}
142    *          <li>{@link Warning}
143    *          <li>{@link TimeZone}
144    *       </ul>
145    *    <li>Other objects:
146    *       <ul>
147    *          <li>{@link ResourceBundle}
148    *          <li>{@link MessageBundle}
149    *          <li>{@link InputStream}
150    *          <li>{@link ServletInputStream}
151    *          <li>{@link Reader}
152    *          <li>{@link OutputStream}
153    *          <li>{@link ServletOutputStream}
154    *          <li>{@link Writer}
155    *          <li>{@link RequestHeaders}
156    *          <li>{@link RequestQuery}
157    *          <li>{@link RequestFormData}
158    *          <li>{@link HttpMethod}
159    *          <li>{@link Logger}
160    *          <li>{@link JuneauLogger}
161    *          <li>{@link RestContext}
162    *          <li>{@link org.apache.juneau.parser.Parser}
163    *          <li>{@link Locale}
164    *          <li>{@link Swagger}
165    *          <li>{@link RequestPath}
166    *          <li>{@link RequestBody}
167    *          <li>{@link Config}
168    *          <li>{@link UriContext}
169    *          <li>{@link UriResolver}
170    *       </ul>
171    * </ul>
172    *
173    * <h5 class='figure'>Example:</h5>
174    * <p class='bcode w800'>
175    *    <ja>@RestResource</ja>(...)
176    *    <jk>public class</jk> MyResource <jk>extends</jk> BasicRestServlet {
177    *
178    *       <jc>// Log the incoming request.</jc>
179    *       <ja>@RestHook</ja>(<jsf>PRE_CALL</jsf>)
180    *       <jk>public void</jk> onPreCall(Accept accept, Logger logger) {
181    *          logger.fine(<js>"Accept {0} header found."</js>, accept);
182    *       }
183    *    }
184    * </p>
185    *
186    * <ul class='notes'>
187    *    <li>
188    *       The method should return <jk>void</jk> although if it does return any value, the value will be ignored.
189    *    <li>
190    *       The method should be <jk>public</jk> although other visibilities are valid if the security manager allows it.
191    *    <li>
192    *       Static methods can be used.
193    *    <li>
194    *       Multiple PRE_CALL methods can be defined on a class.
195    *       <br>PRE_CALL methods on parent classes are invoked before PRE_CALL methods on child classes.
196    *       <br>The order of PRE_CALL method invocations within a class is alphabetical, then by parameter count, then by parameter types.
197    *    <li>
198    *       The method can throw any exception.
199    *       <br>{@link RestException RestExceptions} can be thrown to cause a particular HTTP error status code.
200    *       <br>All other exceptions cause an HTTP 500 error status code.
201    *    <li>
202    *       Note that if you override a parent method, you probably need to call <code><jk>super</jk>.parentMethod(...)</code>.
203    *       <br>The method is still considered part of the parent class for ordering purposes even though it's
204    *       overridden by the child class.
205    *    <li>
206    *       It's advisable not to mess around with the HTTP body itself since you may end up consuming the body
207    *       before the actual REST method has a chance to use it.
208    * </ul>
209    */
210   PRE_CALL,
211
212   /**
213    * Identifies a method that gets called immediately after the <ja>@RestMethod</ja> annotated method gets called.
214    *
215    * <p>
216    * At this point, the output object returned by the method call has been set on the response, but
217    * {@link RestConverter RestConverters} have not yet been executed and the response has not yet been written.
218    *
219    * <p>
220    * The list of valid parameter types are the same as {@link #PRE_CALL}.
221    *
222    * <h5 class='figure'>Example:</h5>
223    * <p class='bcode w800'>
224    *    <ja>@RestResource</ja>(...)
225    *    <jk>public class</jk> MyResource <jk>extends</jk> BasicRestServlet {
226    *
227    *       <jc>// Log the result of the request.</jc>
228    *       <ja>@RestHook</ja>(<jsf>POST_CALL</jsf>)
229    *       <jk>public void</jk> onPostCall(RestResponse res, Logger logger) {
230    *          logger.fine(<js>Output {0} was set on the response."</js>, res.getOutput());
231    *       }
232    *    }
233    * </p>
234    *
235    * <ul class='notes'>
236    *    <li>
237    *       The method should return <jk>void</jk> although if it does return any value, the value will be ignored.
238    *    <li>
239    *       The method should be <jk>public</jk> although other visibilities are valid if the security manager allows it.
240    *    <li>
241    *       Static methods can be used.
242    *    <li>
243    *       Multiple POST_CALL methods can be defined on a class.
244    *       <br>POST_CALL methods on parent classes are invoked before POST_CALL methods on child classes.
245    *       <br>The order of POST_CALL method invocations within a class is alphabetical, then by parameter count, then by parameter types.
246    *    <li>
247    *       The method can throw any exception, although at this point it is too late to set an HTTP error status code.
248    *    <li>
249    *       Note that if you override a parent method, you probably need to call <code><jk>super</jk>.parentMethod(...)</code>.
250    *       <br>The method is still considered part of the parent class for ordering purposes even though it's
251    *       overridden by the child class.
252    * </ul>
253    */
254   POST_CALL,
255
256   /**
257    * Identifies a method that gets called right before we exit the servlet service method.
258    *
259    * <p>
260    * At this point, the output has been written and flushed.
261    *
262    * <p>
263    * The list of valid parameter types are as follows:
264    * <ul>
265    *    <li>Servlet request/response objects:
266    *       <ul>
267    *          <li>{@link HttpServletRequest}
268    *          <li>{@link HttpServletResponse}
269    *       </ul>
270    * </ul>
271    *
272    * <p>
273    * The following attributes are set on the {@link HttpServletRequest} object that can be useful for logging purposes:
274    * <ul>
275    *    <li><js>"Exception"</js> - Any exceptions thrown during the request.
276    *    <li><js>"ExecTime"</js> - Execution time of the request.
277    * </ul>
278    *
279    * <h5 class='figure'>Example:</h5>
280    * <p class='bcode w800'>
281    *    <ja>@RestResource</ja>(...)
282    *    <jk>public class</jk> MyResource <jk>extends</jk> BasicRestServlet {
283    *
284    *       <jc>// Log the time it took to execute the request.</jc>
285    *       <ja>@RestHook</ja>(<jsf>END_CALL</jsf>)
286    *       <jk>public void</jk> onEndCall(HttpServletRequest req, Logger logger) {
287    *          Exception e = (Exception)req.getAttribute(<js>"Exception"</js>);
288    *          Long execTime = (Long)req.getAttribute(<js>"ExecTime"</js>);
289    *          <jk>if</jk> (e != <jk>null</jk>)
290    *             logger.warn(e, <js>"Request failed in {0}ms."</js>, execTime);
291    *          <jk>else</jk>
292    *             logger.fine(<js>"Request finished in {0}ms."</js>, execTime);
293    *       }
294    *    }
295    * </p>
296    *
297    * <ul class='notes'>
298    *    <li>
299    *       The method should return <jk>void</jk> although if it does return any value, the value will be ignored.
300    *    <li>
301    *       The method should be <jk>public</jk> although other visibilities are valid if the security manager allows it.
302    *    <li>
303    *       Static methods can be used.
304    *    <li>
305    *       Multiple END_CALL methods can be defined on a class.
306    *       <br>END_CALL methods on parent classes are invoked before END_CALL methods on child classes.
307    *       <br>The order of END_CALL method invocations within a class is alphabetical, then by parameter count, then by parameter types.
308    *    <li>
309    *       The method can throw any exception, although at this point it is too late to set an HTTP error status code.
310    *    <li>
311    *       Note that if you override a parent method, you probably need to call <code><jk>super</jk>.parentMethod(...)</code>.
312    *       <br>The method is still considered part of the parent class for ordering purposes even though it's
313    *       overridden by the child class.
314    * </ul>
315    */
316   END_CALL,
317
318   /**
319    * Identifies a method that gets called during servlet initialization.
320    *
321    * <p>
322    * This method is called from within the {@link Servlet#init(ServletConfig)} method after the {@link RestContextBuilder}
323    * object has been created and initialized with the annotations defined on the class, but before the
324    * {@link RestContext} object has been created.
325    *
326    * <p>
327    * The only valid parameter type for this method is {@link RestContextBuilder} which can be used to configure the servlet.
328    *
329    * <p>
330    * An example of this is the <c>PetStoreResource</c> class that uses an init method to perform initialization
331    * of an internal data structure.
332    *
333    * <h5 class='figure'>Example:</h5>
334    * <p class='bcode w800'>
335    *    <ja>@RestResource</ja>(...)
336    *    <jk>public class</jk> PetStoreResource <jk>extends</jk> ResourceJena {
337    *
338    *       <jc>// Our database.</jc>
339    *       <jk>private</jk> Map&lt;Integer,Pet&gt; <jf>petDB</jf>;
340    *
341    *       <ja>@RestHook</ja>(<jsf>INIT</jsf>)
342    *       <jk>public void</jk> onInit(RestContextBuilder builder) <jk>throws</jk> Exception {
343    *          <jc>// Load our database from a local JSON file.</jc>
344    *          <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>);
345    *       }
346    *    }
347    * </p>
348    *
349    * <ul class='notes'>
350    *    <li>
351    *       The method should return <jk>void</jk> although if it does return any value, the value will be ignored.
352    *    <li>
353    *       The method should be <jk>public</jk> although other visibilities are valid if the security manager allows it.
354    *    <li>
355    *       Static methods can be used.
356    *    <li>
357    *       Multiple INIT methods can be defined on a class.
358    *       <br>INIT methods on parent classes are invoked before INIT methods on child classes.
359    *       <br>The order of INIT method invocations within a class is alphabetical, then by parameter count, then by parameter types.
360    *    <li>
361    *       The method can throw any exception causing initialization of the servlet to fail.
362    *    <li>
363    *       Note that if you override a parent method, you probably need to call <code><jk>super</jk>.parentMethod(...)</code>.
364    *       <br>The method is still considered part of the parent class for ordering purposes even though it's
365    *       overridden by the child class.
366    * </ul>
367    */
368   INIT,
369
370   /**
371    * Identifies a method that gets called immediately after servlet initialization.
372    *
373    * <p>
374    * This method is called from within the {@link Servlet#init(ServletConfig)} method after the {@link RestContext}
375    * object has been created.
376    *
377    * <p>
378    * The only valid parameter type for this method is {@link RestContext} which can be used to retrieve information
379    * about the servlet.
380    *
381    * <ul class='notes'>
382    *    <li>
383    *       The method should return <jk>void</jk> although if it does return any value, the value will be ignored.
384    *    <li>
385    *       The method should be <jk>public</jk> although other visibilities are valid if the security manager allows it.
386    *    <li>
387    *       Static methods can be used.
388    *    <li>
389    *       Multiple POST_INIT methods can be defined on a class.
390    *       <br>POST_INIT methods on parent classes are invoked before POST_INIT methods on child classes.
391    *       <br>The order of POST_INIT method invocations within a class is alphabetical, then by parameter count, then by parameter types.
392    *    <li>
393    *       The method can throw any exception causing initialization of the servlet to fail.
394    *    <li>
395    *       Note that if you override a parent method, you probably need to call <code><jk>super</jk>.parentMethod(...)</code>.
396    *       <br>The method is still considered part of the parent class for ordering purposes even though it's
397    *       overridden by the child class.
398    * </ul>
399    */
400   POST_INIT,
401
402   /**
403    * Identical to {@link #POST_INIT} except the order of execution is child-resources first.
404    *
405    * <p>
406    * Use this annotation if you need to perform any kind of initialization on child resources before the parent resource.
407    *
408    * <p>
409    * This method is called from within the {@link Servlet#init(ServletConfig)} method after the {@link RestContext}
410    * object has been created and after the {@link #POST_INIT} methods have been called.
411    *
412    * <p>
413    * The only valid parameter type for this method is {@link RestContext} which can be used to retrieve information
414    * about the servlet.
415    *
416    * <ul class='notes'>
417    *    <li>
418    *       The method should return <jk>void</jk> although if it does return any value, the value will be ignored.
419    *    <li>
420    *       The method should be <jk>public</jk> although other visibilities are valid if the security manager allows it.
421    *    <li>
422    *       Static methods can be used.
423    *    <li>
424    *       Multiple POST_INIT_CHILD_FIRST methods can be defined on a class.
425    *       <br>POST_INIT_CHILD_FIRST methods on parent classes are invoked before POST_INIT_CHILD_FIRST methods on child classes.
426    *       <br>The order of POST_INIT_CHILD_FIRST method invocations within a class is alphabetical, then by parameter count, then by parameter types.
427    *    <li>
428    *       The method can throw any exception causing initialization of the servlet to fail.
429    * </ul>
430    */
431   POST_INIT_CHILD_FIRST,
432
433   /**
434    * Identifies a method that gets called during servlet destroy.
435    *
436    * <p>
437    * This method is called from within the {@link Servlet#destroy()}.
438    *
439    * <p>
440    * The only valid parameter type for this method is {@link RestContext}, although typically no arguments will
441    * be specified.
442    *
443    * <h5 class='figure'>Example:</h5>
444    * <p class='bcode w800'>
445    *    <ja>@RestResource</ja>(...)
446    *    <jk>public class</jk> PetStoreResource <jk>extends</jk> ResourceJena {
447    *
448    *       <jc>// Our database.</jc>
449    *       <jk>private</jk> Map&lt;Integer,Pet&gt; <jf>petDB</jf>;
450    *
451    *       <ja>@RestHook</ja>(<jsf>DESTROY</jsf>)
452    *       <jk>public void</jk> onDestroy() {
453    *          <jf>petDB</jf> = <jk>null</jk>;
454    *       }
455    *    }
456    * </p>
457    *
458    * <ul class='notes'>
459    *    <li>
460    *       The method should return <jk>void</jk> although if it does return any value, the value will be ignored.
461    *    <li>
462    *       The method should be <jk>public</jk> although other visibilities are valid if the security manager allows it.
463    *    <li>
464    *       Static methods can be used.
465    *    <li>
466    *       Multiple DESTROY methods can be defined on a class.
467    *       <br>DESTROY methods on child classes are invoked before DESTROY methods on parent classes.
468    *       <br>The order of DESTROY method invocations within a class is alphabetical, then by parameter count, then by parameter types.
469    *    <li>
470    *       In general, destroy methods should not throw any exceptions, although if any are thrown, the stack trace will be
471    *       printed to <c>System.err</c>.
472    *    <li>
473    *       Note that if you override a parent method, you probably need to call <code><jk>super</jk>.parentMethod(...)</code>.
474    *       <br>The method is still considered part of the parent class for ordering purposes even though it's
475    *       overridden by the child class.
476    * </ul>
477    */
478   DESTROY
479}