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