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