001/*
002 * Licensed to the Apache Software Foundation (ASF) under one or more
003 * contributor license agreements.  See the NOTICE file distributed with
004 * this work for additional information regarding copyright ownership.
005 * The ASF licenses this file to You under the Apache License, Version 2.0
006 * (the "License"); you may not use this file except in compliance with
007 * the License.  You may obtain a copy of the License at
008 *
009 *      http://www.apache.org/licenses/LICENSE-2.0
010 *
011 * Unless required by applicable law or agreed to in writing, software
012 * distributed under the License is distributed on an "AS IS" BASIS,
013 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
014 * See the License for the specific language governing permissions and
015 * limitations under the License.
016 */
017package org.apache.juneau.rest.annotation;
018
019import static java.lang.annotation.ElementType.*;
020import static java.lang.annotation.RetentionPolicy.*;
021
022import java.lang.annotation.*;
023
024import jakarta.servlet.http.*;
025
026/**
027 * Identifies a method that gets called right before we exit the servlet service method.
028 *
029 * <p>
030 * At this point, the output has been written and flushed.
031 *
032 * <p>
033 * The list of valid parameter types are as follows:
034 * <ul>
035 *    <li>Servlet request/response objects:
036 *       <ul>
037 *          <li>{@link HttpServletRequest}
038 *          <li>{@link HttpServletResponse}
039 *       </ul>
040 * </ul>
041 *
042 * <p>
043 * The following attributes are set on the {@link HttpServletRequest} object that can be useful for logging purposes:
044 * <ul>
045 *    <li><js>"Exception"</js> - Any exceptions thrown during the request.
046 *    <li><js>"ExecTime"</js> - Execution time of the request.
047 * </ul>
048 *
049 * <h5 class='figure'>Example:</h5>
050 * <p class='bjava'>
051 *    <ja>@Rest</ja>(...)
052 *    <jk>public class</jk> MyResource <jk>extends</jk> BasicRestServlet {
053 *
054 *       <jc>// Log the time it took to execute the request.</jc>
055 *       <ja>@RestEndCall
056 *       <jk>public void</jk> onEndCall(HttpServletRequest <jv>req</jv>, Logger <jv>logger</jv>) {
057 *          Exception <jv>exception</jv> = (Exception)<jv>req</jv>.getAttribute(<js>"Exception"</js>);
058 *          Long <jv>execTime</jv> = (Long)<jv>req</jv>.getAttribute(<js>"ExecTime"</js>);
059 *          <jk>if</jk> (<jv>exception</jv> != <jk>null</jk>)
060 *             <jv>logger</jv>.warn(<jv>exception</jv>, <js>"Request failed in {0}ms."</js>, <jv>execTime</jv>);
061 *          <jk>else</jk>
062 *             <jv>logger</jv>.fine(<js>"Request finished in {0}ms."</js>, <jv>execTime</jv>);
063 *       }
064 *    }
065 * </p>
066 *
067 * <h5 class='section'>Notes:</h5><ul>
068 *    <li class='note'>
069 *       The method should return <jk>void</jk> although if it does return any value, the value will be ignored.
070 *    <li class='note'>
071 *       The method should be <jk>public</jk> although other visibilities are valid if the security manager allows it.
072 *    <li class='note'>
073 *       Static methods can be used.
074 *    <li class='note'>
075 *       Multiple END_CALL methods can be defined on a class.
076 *       <br>END_CALL methods on parent classes are invoked before END_CALL methods on child classes.
077 *       <br>The order of END_CALL method invocations within a class is alphabetical, then by parameter count, then by parameter types.
078 *    <li class='note'>
079 *       The method can throw any exception, although at this point it is too late to set an HTTP error status code.
080 *    <li class='note'>
081 *       Note that if you override a parent method, you probably need to call <code><jk>super</jk>.parentMethod(...)</code>.
082 *       <br>The method is still considered part of the parent class for ordering purposes even though it's
083 *       overridden by the child class.
084 * </ul>
085 *
086 * <h5 class='section'>See Also:</h5><ul>
087 *    <li class='link'><a class="doclink" href="https://juneau.apache.org/docs/topics/LifecycleHooks">Lifecycle Hooks</a>
088 * </ul>
089 */
090@Target({METHOD,TYPE})
091@Retention(RUNTIME)
092@Inherited
093@Repeatable(RestEndCallAnnotation.Array.class)
094public @interface RestEndCall {
095
096    /**
097     * Optional description for the exposed API.
098     *
099     * @return The annotation value.
100     * @since 9.2.0
101     */
102    String[] description() default {};
103
104    /**
105    * Dynamically apply this annotation to the specified methods.
106    *
107    * <h5 class='section'>See Also:</h5><ul>
108    *    <li class='link'><a class="doclink" href="https://juneau.apache.org/docs/topics/DynamicallyAppliedAnnotations">Dynamically Applied Annotations</a>
109    * </ul>
110    *
111    * @return The annotation value.
112    */
113   String[] on() default {};
114}