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<Integer,Pet> <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<Integer,Pet> <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}