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