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