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.cp.Messages;
025import org.apache.juneau.dto.swagger.*;
026import org.apache.juneau.http.header.*;
027import org.apache.juneau.http.exception.*;
028import org.apache.juneau.rest.*;
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 RestLifecycleHooks}
036 * </ul>
037 */
038public enum HookEvent {
039
040   /**
041    * Identifies a method that is 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>@Rest</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 HttpException HttpExceptions} 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.header.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 Messages}
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 Logger}
159    *          <li>{@link RestContext}
160    *          <li>{@link org.apache.juneau.parser.Parser}
161    *          <li>{@link Locale}
162    *          <li>{@link Swagger}
163    *          <li>{@link RequestPath}
164    *          <li>{@link RequestBody}
165    *          <li>{@link Config}
166    *          <li>{@link UriContext}
167    *          <li>{@link UriResolver}
168    *       </ul>
169    * </ul>
170    *
171    * <h5 class='figure'>Example:</h5>
172    * <p class='bcode w800'>
173    *    <ja>@Rest</ja>(...)
174    *    <jk>public class</jk> MyResource <jk>extends</jk> BasicRestServlet {
175    *
176    *       <jc>// Log the incoming request.</jc>
177    *       <ja>@RestHook</ja>(<jsf>PRE_CALL</jsf>)
178    *       <jk>public void</jk> onPreCall(Accept accept, Logger logger) {
179    *          logger.fine(<js>"Accept {0} header found."</js>, accept);
180    *       }
181    *    }
182    * </p>
183    *
184    * <ul class='notes'>
185    *    <li>
186    *       The method should return <jk>void</jk> although if it does return any value, the value will be ignored.
187    *    <li>
188    *       The method should be <jk>public</jk> although other visibilities are valid if the security manager allows it.
189    *    <li>
190    *       Static methods can be used.
191    *    <li>
192    *       Multiple PRE_CALL methods can be defined on a class.
193    *       <br>PRE_CALL methods on parent classes are invoked before PRE_CALL methods on child classes.
194    *       <br>The order of PRE_CALL method invocations within a class is alphabetical, then by parameter count, then by parameter types.
195    *    <li>
196    *       The method can throw any exception.
197    *       <br>{@link HttpException HttpExceptions} can be thrown to cause a particular HTTP error status code.
198    *       <br>All other exceptions cause an HTTP 500 error status code.
199    *    <li>
200    *       Note that if you override a parent method, you probably need to call <code><jk>super</jk>.parentMethod(...)</code>.
201    *       <br>The method is still considered part of the parent class for ordering purposes even though it's
202    *       overridden by the child class.
203    *    <li>
204    *       It's advisable not to mess around with the HTTP body itself since you may end up consuming the body
205    *       before the actual REST method has a chance to use it.
206    * </ul>
207    */
208   PRE_CALL,
209
210   /**
211    * Identifies a method that gets called immediately after the <ja>@RestMethod</ja> annotated method gets called.
212    *
213    * <p>
214    * At this point, the output object returned by the method call has been set on the response, but
215    * {@link RestConverter RestConverters} have not yet been executed and the response has not yet been written.
216    *
217    * <p>
218    * The list of valid parameter types are the same as {@link #PRE_CALL}.
219    *
220    * <h5 class='figure'>Example:</h5>
221    * <p class='bcode w800'>
222    *    <ja>@Rest</ja>(...)
223    *    <jk>public class</jk> MyResource <jk>extends</jk> BasicRestServlet {
224    *
225    *       <jc>// Log the result of the request.</jc>
226    *       <ja>@RestHook</ja>(<jsf>POST_CALL</jsf>)
227    *       <jk>public void</jk> onPostCall(RestResponse res, Logger logger) {
228    *          logger.fine(<js>Output {0} was set on the response."</js>, res.getOutput());
229    *       }
230    *    }
231    * </p>
232    *
233    * <ul class='notes'>
234    *    <li>
235    *       The method should return <jk>void</jk> although if it does return any value, the value will be ignored.
236    *    <li>
237    *       The method should be <jk>public</jk> although other visibilities are valid if the security manager allows it.
238    *    <li>
239    *       Static methods can be used.
240    *    <li>
241    *       Multiple POST_CALL methods can be defined on a class.
242    *       <br>POST_CALL methods on parent classes are invoked before POST_CALL methods on child classes.
243    *       <br>The order of POST_CALL method invocations within a class is alphabetical, then by parameter count, then by parameter types.
244    *    <li>
245    *       The method can throw any exception, although at this point it is too late to set an HTTP error status code.
246    *    <li>
247    *       Note that if you override a parent method, you probably need to call <code><jk>super</jk>.parentMethod(...)</code>.
248    *       <br>The method is still considered part of the parent class for ordering purposes even though it's
249    *       overridden by the child class.
250    * </ul>
251    */
252   POST_CALL,
253
254   /**
255    * Identifies a method that gets called right before we exit the servlet service method.
256    *
257    * <p>
258    * At this point, the output has been written and flushed.
259    *
260    * <p>
261    * The list of valid parameter types are as follows:
262    * <ul>
263    *    <li>Servlet request/response objects:
264    *       <ul>
265    *          <li>{@link HttpServletRequest}
266    *          <li>{@link HttpServletResponse}
267    *       </ul>
268    * </ul>
269    *
270    * <p>
271    * The following attributes are set on the {@link HttpServletRequest} object that can be useful for logging purposes:
272    * <ul>
273    *    <li><js>"Exception"</js> - Any exceptions thrown during the request.
274    *    <li><js>"ExecTime"</js> - Execution time of the request.
275    * </ul>
276    *
277    * <h5 class='figure'>Example:</h5>
278    * <p class='bcode w800'>
279    *    <ja>@Rest</ja>(...)
280    *    <jk>public class</jk> MyResource <jk>extends</jk> BasicRestServlet {
281    *
282    *       <jc>// Log the time it took to execute the request.</jc>
283    *       <ja>@RestHook</ja>(<jsf>END_CALL</jsf>)
284    *       <jk>public void</jk> onEndCall(HttpServletRequest req, Logger logger) {
285    *          Exception e = (Exception)req.getAttribute(<js>"Exception"</js>);
286    *          Long execTime = (Long)req.getAttribute(<js>"ExecTime"</js>);
287    *          <jk>if</jk> (e != <jk>null</jk>)
288    *             logger.warn(e, <js>"Request failed in {0}ms."</js>, execTime);
289    *          <jk>else</jk>
290    *             logger.fine(<js>"Request finished in {0}ms."</js>, execTime);
291    *       }
292    *    }
293    * </p>
294    *
295    * <ul class='notes'>
296    *    <li>
297    *       The method should return <jk>void</jk> although if it does return any value, the value will be ignored.
298    *    <li>
299    *       The method should be <jk>public</jk> although other visibilities are valid if the security manager allows it.
300    *    <li>
301    *       Static methods can be used.
302    *    <li>
303    *       Multiple END_CALL methods can be defined on a class.
304    *       <br>END_CALL methods on parent classes are invoked before END_CALL methods on child classes.
305    *       <br>The order of END_CALL method invocations within a class is alphabetical, then by parameter count, then by parameter types.
306    *    <li>
307    *       The method can throw any exception, although at this point it is too late to set an HTTP error status code.
308    *    <li>
309    *       Note that if you override a parent method, you probably need to call <code><jk>super</jk>.parentMethod(...)</code>.
310    *       <br>The method is still considered part of the parent class for ordering purposes even though it's
311    *       overridden by the child class.
312    * </ul>
313    */
314   END_CALL,
315
316   /**
317    * Identifies a method that gets called during servlet initialization.
318    *
319    * <p>
320    * This method is called from within the {@link Servlet#init(ServletConfig)} method after the {@link RestContextBuilder}
321    * object has been created and initialized with the annotations defined on the class, but before the
322    * {@link RestContext} object has been created.
323    *
324    * <p>
325    * The only valid parameter type for this method is {@link RestContextBuilder} which can be used to configure the servlet.
326    *
327    * <p>
328    * An example of this is the <c>PetStoreResource</c> class that uses an init method to perform initialization
329    * of an internal data structure.
330    *
331    * <h5 class='figure'>Example:</h5>
332    * <p class='bcode w800'>
333    *    <ja>@Rest</ja>(...)
334    *    <jk>public class</jk> PetStoreResource <jk>extends</jk> ResourceJena {
335    *
336    *       <jc>// Our database.</jc>
337    *       <jk>private</jk> Map&lt;Integer,Pet&gt; <jf>petDB</jf>;
338    *
339    *       <ja>@RestHook</ja>(<jsf>INIT</jsf>)
340    *       <jk>public void</jk> onInit(RestContextBuilder builder) <jk>throws</jk> Exception {
341    *          <jc>// Load our database from a local JSON file.</jc>
342    *          <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>);
343    *       }
344    *    }
345    * </p>
346    *
347    * <ul class='notes'>
348    *    <li>
349    *       The method should return <jk>void</jk> although if it does return any value, the value will be ignored.
350    *    <li>
351    *       The method should be <jk>public</jk> although other visibilities are valid if the security manager allows it.
352    *    <li>
353    *       Static methods can be used.
354    *    <li>
355    *       Multiple INIT methods can be defined on a class.
356    *       <br>INIT methods on parent classes are invoked before INIT methods on child classes.
357    *       <br>The order of INIT method invocations within a class is alphabetical, then by parameter count, then by parameter types.
358    *    <li>
359    *       The method can throw any exception causing initialization of the servlet to fail.
360    *    <li>
361    *       Note that if you override a parent method, you probably need to call <code><jk>super</jk>.parentMethod(...)</code>.
362    *       <br>The method is still considered part of the parent class for ordering purposes even though it's
363    *       overridden by the child class.
364    * </ul>
365    */
366   INIT,
367
368   /**
369    * Identifies a method that gets called immediately after servlet initialization.
370    *
371    * <p>
372    * This method is called from within the {@link Servlet#init(ServletConfig)} method after the {@link RestContext}
373    * object has been created.
374    *
375    * <p>
376    * The only valid parameter type for this method is {@link RestContext} which can be used to retrieve information
377    * about the servlet.
378    *
379    * <ul class='notes'>
380    *    <li>
381    *       The method should return <jk>void</jk> although if it does return any value, the value will be ignored.
382    *    <li>
383    *       The method should be <jk>public</jk> although other visibilities are valid if the security manager allows it.
384    *    <li>
385    *       Static methods can be used.
386    *    <li>
387    *       Multiple POST_INIT methods can be defined on a class.
388    *       <br>POST_INIT methods on parent classes are invoked before POST_INIT methods on child classes.
389    *       <br>The order of POST_INIT method invocations within a class is alphabetical, then by parameter count, then by parameter types.
390    *    <li>
391    *       The method can throw any exception causing initialization of the servlet to fail.
392    *    <li>
393    *       Note that if you override a parent method, you probably need to call <code><jk>super</jk>.parentMethod(...)</code>.
394    *       <br>The method is still considered part of the parent class for ordering purposes even though it's
395    *       overridden by the child class.
396    * </ul>
397    */
398   POST_INIT,
399
400   /**
401    * Identical to {@link #POST_INIT} except the order of execution is child-resources first.
402    *
403    * <p>
404    * Use this annotation if you need to perform any kind of initialization on child resources before the parent resource.
405    *
406    * <p>
407    * This method is called from within the {@link Servlet#init(ServletConfig)} method after the {@link RestContext}
408    * object has been created and after the {@link #POST_INIT} methods have been called.
409    *
410    * <p>
411    * The only valid parameter type for this method is {@link RestContext} which can be used to retrieve information
412    * about the servlet.
413    *
414    * <ul class='notes'>
415    *    <li>
416    *       The method should return <jk>void</jk> although if it does return any value, the value will be ignored.
417    *    <li>
418    *       The method should be <jk>public</jk> although other visibilities are valid if the security manager allows it.
419    *    <li>
420    *       Static methods can be used.
421    *    <li>
422    *       Multiple POST_INIT_CHILD_FIRST methods can be defined on a class.
423    *       <br>POST_INIT_CHILD_FIRST methods on parent classes are invoked before POST_INIT_CHILD_FIRST methods on child classes.
424    *       <br>The order of POST_INIT_CHILD_FIRST method invocations within a class is alphabetical, then by parameter count, then by parameter types.
425    *    <li>
426    *       The method can throw any exception causing initialization of the servlet to fail.
427    * </ul>
428    */
429   POST_INIT_CHILD_FIRST,
430
431   /**
432    * Identifies a method that gets called during servlet destroy.
433    *
434    * <p>
435    * This method is called from within the {@link Servlet#destroy()}.
436    *
437    * <p>
438    * The only valid parameter type for this method is {@link RestContext}, although typically no arguments will
439    * be specified.
440    *
441    * <h5 class='figure'>Example:</h5>
442    * <p class='bcode w800'>
443    *    <ja>@Rest</ja>(...)
444    *    <jk>public class</jk> PetStoreResource <jk>extends</jk> ResourceJena {
445    *
446    *       <jc>// Our database.</jc>
447    *       <jk>private</jk> Map&lt;Integer,Pet&gt; <jf>petDB</jf>;
448    *
449    *       <ja>@RestHook</ja>(<jsf>DESTROY</jsf>)
450    *       <jk>public void</jk> onDestroy() {
451    *          <jf>petDB</jf> = <jk>null</jk>;
452    *       }
453    *    }
454    * </p>
455    *
456    * <ul class='notes'>
457    *    <li>
458    *       The method should return <jk>void</jk> although if it does return any value, the value will be ignored.
459    *    <li>
460    *       The method should be <jk>public</jk> although other visibilities are valid if the security manager allows it.
461    *    <li>
462    *       Static methods can be used.
463    *    <li>
464    *       Multiple DESTROY methods can be defined on a class.
465    *       <br>DESTROY methods on child classes are invoked before DESTROY methods on parent classes.
466    *       <br>The order of DESTROY method invocations within a class is alphabetical, then by parameter count, then by parameter types.
467    *    <li>
468    *       In general, destroy methods should not throw any exceptions, although if any are thrown, the stack trace will be
469    *       printed to <c>System.err</c>.
470    *    <li>
471    *       Note that if you override a parent method, you probably need to call <code><jk>super</jk>.parentMethod(...)</code>.
472    *       <br>The method is still considered part of the parent class for ordering purposes even though it's
473    *       overridden by the child class.
474    * </ul>
475    */
476   DESTROY
477}