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 static java.lang.annotation.ElementType.*;
016import static java.lang.annotation.RetentionPolicy.*;
017
018import java.io.*;
019import java.lang.annotation.*;
020import java.util.*;
021import java.util.logging.*;
022
023import jakarta.servlet.*;
024import jakarta.servlet.http.*;
025
026import org.apache.juneau.*;
027import org.apache.juneau.config.*;
028import org.apache.juneau.cp.*;
029import org.apache.juneau.http.header.*;
030import org.apache.juneau.rest.*;
031import org.apache.juneau.rest.converter.*;
032import org.apache.juneau.rest.httppart.*;
033
034/**
035 * Identifies a method that gets called immediately after the <ja>@RestOp</ja> annotated method gets called.
036 *
037 * <p>
038 * At this point, the output object returned by the method call has been set on the response, but
039 * {@link RestConverter RestConverters} have not yet been executed and the response has not yet been written.
040 *
041 * <p>
042 * The list of valid parameter types are as follows:
043 * <ul>
044 *    <li>Servlet request/response objects:
045 *       <ul class='javatreec'>
046 *          <li>{@link HttpServletRequest}
047 *          <li>{@link HttpServletResponse}
048 *       </ul>
049 *    <li>Extended request/response objects:
050 *       <ul class='javatreec'>
051 *          <li>{@link RestRequest}
052 *          <li>{@link RestResponse}
053 *       </ul>
054 *    <li>Header objects:
055 *       <ul class='javatreec'>
056 *          <li>{@link Accept}
057 *          <li>{@link AcceptCharset}
058 *          <li>{@link AcceptEncoding}
059 *          <li>{@link AcceptLanguage}
060 *          <li>{@link Authorization}
061 *          <li>{@link CacheControl}
062 *          <li>{@link Connection}
063 *          <li>{@link ContentLength}
064 *          <li>{@link ContentType}
065 *          <li>{@link org.apache.juneau.http.header.Date}
066 *          <li>{@link Expect}
067 *          <li>{@link From}
068 *          <li>{@link Host}
069 *          <li>{@link IfMatch}
070 *          <li>{@link IfModifiedSince}
071 *          <li>{@link IfNoneMatch}
072 *          <li>{@link IfRange}
073 *          <li>{@link IfUnmodifiedSince}
074 *          <li>{@link MaxForwards}
075 *          <li>{@link Pragma}
076 *          <li>{@link ProxyAuthorization}
077 *          <li>{@link Range}
078 *          <li>{@link Referer}
079 *          <li>{@link TE}
080 *          <li>{@link UserAgent}
081 *          <li>{@link Upgrade}
082 *          <li>{@link Via}
083 *          <li>{@link Warning}
084 *          <li>{@link TimeZone}
085 *       </ul>
086 *    <li>Other objects:
087 *       <ul class='javatreec'>
088 *          <li>{@link ResourceBundle}
089 *          <li>{@link Messages}
090 *          <li>{@link InputStream}
091 *          <li>{@link ServletInputStream}
092 *          <li>{@link Reader}
093 *          <li>{@link OutputStream}
094 *          <li>{@link ServletOutputStream}
095 *          <li>{@link Writer}
096 *          <li>{@link RequestHeaders}
097 *          <li>{@link RequestQueryParams}
098 *          <li>{@link RequestFormParams}
099 *          <li>{@link RequestPathParams}
100 *          <li>{@link Logger}
101 *          <li>{@link RestContext}
102 *          <li>{@link org.apache.juneau.parser.Parser}
103 *          <li>{@link Locale}
104 *          <li>{@link Swagger}
105 *          <li>{@link RequestContent}
106 *          <li>{@link Config}
107 *          <li>{@link UriContext}
108 *          <li>{@link UriResolver}
109 *       </ul>
110 * </ul>
111 *
112 * <h5 class='figure'>Example:</h5>
113 * <p class='bjava'>
114 *    <ja>@Rest</ja>(...)
115 *    <jk>public class</jk> MyResource <jk>extends</jk> BasicRestServlet {
116 *
117 *       <jc>// Log the result of the request.</jc>
118 *       <ja>@RestPostCall</ja>
119 *       <jk>public void</jk> onPostCall(RestResponse <jv>res</jv>, Logger <jv>logger</jv>) {
120 *          <jv>logger</jv>.fine(<js>Output {0} was set on the response."</js>, <jv>res</jv>.getOutput());
121 *       }
122 *    }
123 * </p>
124 *
125 * <h5 class='section'>Notes:</h5><ul>
126 *    <li class='note'>
127 *       The method should return <jk>void</jk> although if it does return any value, the value will be ignored.
128 *    <li class='note'>
129 *       The method should be <jk>public</jk> although other visibilities are valid if the security manager allows it.
130 *    <li class='note'>
131 *       Static methods can be used.
132 *    <li class='note'>
133 *       Multiple post-call methods can be defined on a class.
134 *       <br>Post-call methods on parent classes are invoked before post-call methods on child classes.
135 *       <br>The order of post-call method invocations within a class is alphabetical, then by parameter count, then by parameter types.
136 *    <li class='note'>
137 *       The method can throw any exception, although at this point it is too late to set an HTTP error status code.
138 *    <li class='note'>
139 *       Note that if you override a parent method, you probably need to call <code><jk>super</jk>.parentMethod(...)</code>.
140 *       <br>The method is still considered part of the parent class for ordering purposes even though it's
141 *       overridden by the child class.
142 * </ul>
143 *
144 * <h5 class='section'>See Also:</h5><ul>
145 *    <li class='link'><a class="doclink" href="../../../../../index.html#jrs.LifecycleHooks">Lifecycle Hooks</a>
146 * </ul>
147 */
148@Target({METHOD,TYPE})
149@Retention(RUNTIME)
150@Inherited
151@Repeatable(RestPostCallAnnotation.Array.class)
152public @interface RestPostCall {
153
154   /**
155    * Dynamically apply this annotation to the specified methods.
156    *
157    * <h5 class='section'>See Also:</h5><ul>
158    *    <li class='link'><a class="doclink" href="../../../../../index.html#jm.DynamicallyAppliedAnnotations">Dynamically Applied Annotations</a>
159    * </ul>
160    *
161    * @return The annotation value.
162    */
163   String[] on() default {};
164}