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