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.lang.annotation.*;
019import java.util.logging.*;
020
021import org.apache.juneau.*;
022import org.apache.juneau.config.*;
023import org.apache.juneau.cp.*;
024import org.apache.juneau.encoders.*;
025import org.apache.juneau.http.header.*;
026import org.apache.juneau.http.part.*;
027import org.apache.juneau.httppart.*;
028import org.apache.juneau.jsonschema.*;
029import org.apache.juneau.parser.*;
030import org.apache.juneau.rest.*;
031import org.apache.juneau.rest.arg.*;
032import org.apache.juneau.rest.converter.*;
033import org.apache.juneau.rest.debug.*;
034import org.apache.juneau.rest.guard.*;
035import org.apache.juneau.rest.httppart.*;
036import org.apache.juneau.rest.logger.*;
037import org.apache.juneau.rest.matcher.*;
038import org.apache.juneau.rest.processor.*;
039import org.apache.juneau.rest.staticfile.*;
040import org.apache.juneau.rest.stats.*;
041import org.apache.juneau.rest.swagger.*;
042import org.apache.juneau.rest.util.*;
043import org.apache.juneau.serializer.*;
044import org.apache.juneau.svl.*;
045
046/**
047 * Rest bean injection annotation.
048 *
049 * <p>
050 * Used on methods of {@link Rest}-annotated classes to denote methods and fields that override and customize beans
051 * used by the REST framework.
052 *
053 * <h5 class='figure'>Example</h5>
054 * <p class='bcode'>
055 *    <jc>// Rest resource that uses a customized call logger.</jc>
056 *    <ja>@Rest</ja>
057 *    <jk>public class</jk> MyRest <jk>extends</jk> BasicRestServlet {
058 *
059 *       <jc>// Option #1:  As a field.</jc>
060 *       <ja>@RestInject</ja>
061 *       CallLogger <jf>myCallLogger</jf> = CallLogger.<jsm>create</jsm>().logger(<js>"mylogger"</js>).build();
062 *
063 *       <jc>// Option #2:  As a method.</jc>
064 *       <ja>@RestInject</ja>
065 *       <jk>public</jk> CallLogger myCallLogger() {
066 *          <jk>return</jk> CallLogger.<jsm>create</jsm>().logger(<js>"mylogger"</js>).build();
067 *       }
068 *    }
069 * </p>
070 *
071 * <p>
072 *    The {@link RestInject#name()}/{@link RestInject#value()} attributes are used to differentiate between named beans.
073 * </p>
074 * <h5 class='figure'>Example</h5>
075 * <p class='bcode'>
076 *    <jc>// Customized default request headers.</jc>
077 *    <ja>@RestInject</ja>(<js>"defaultRequestHeaders"</js>)
078 *    HeaderList <jf>defaultRequestHeaders</jf> = HeaderList.<jsm>create</jsm>().set(ContentType.<jsf>TEXT_PLAIN</jsf>).build();
079 *
080 *    <jc>// Customized default response headers.</jc>
081 *    <ja>@RestInject</ja>(<js>"defaultResponseHeaders"</js>)
082 *    HeaderList <jf>defaultResponseHeaders</jf> = HeaderList.<jsm>create</jsm>().set(ContentType.<jsf>TEXT_PLAIN</jsf>).build();
083 * </p>
084 *
085 * <p>
086 *    The {@link RestInject#methodScope()} attribute is used to define beans in the scope of specific {@link RestOp}-annotated methods.
087 * </p>
088 * <h5 class='figure'>Example</h5>
089 * <p class='bcode'>
090 *    <jc>// Set a default header on a specific REST method.</jc>
091 *    <jc>// Input parameter is the default header list builder with all annotations applied.</jc>
092 *    <ja>@RestInject</ja>(name=<js>"defaultRequestHeaders"</js>, methodScope=<js>"myRestMethod"</js>)
093 *    <jk>public</jk> HeaderList.Builder myRequestHeaders(HeaderList.Builder <jv>builder</jv>) {
094 *       <jk>return</jk> <jv>builder</jv>.set(ContentType.<jsf>TEXT_PLAIN</jsf>);
095 *    }
096 *
097 *    <jc>// Method that picks up default header defined above.</jc>
098 *    <ja>@RestGet</ja>
099 *    <jk>public</jk> Object myRestMethod(ContentType <jv>contentType</jv>) { ... }
100 * </p>
101 *
102 * <p>
103 *    This annotation can also be used to inject arbitrary beans into the bean store which allows them to be
104 *    passed as resolved parameters on {@link RestOp}-annotated methods.
105 * </p>
106 * <h5 class='figure'>Example</h5>
107 * <p class='bcode'>
108 *    <jc>// Custom beans injected into the bean store.</jc>
109 *    <ja>@RestInject</ja> MyBean <jv>myBean1</jv> = <jk>new</jk> MyBean();
110 *    <ja>@RestInject</ja>(<js>"myBean2"</js>) MyBean <jv>myBean2</jv> = <jk>new</jk> MyBean();
111 *
112 *    <jc>// Method that uses injected beans.</jc>
113 *    <ja>@RestGet</ja>
114 *    <jk>public</jk> Object doGet(MyBean <jv>myBean1</jv>, <ja>@Named</ja>(<js>"myBean2"</js>) MyBean <jv>myBean2</jv>) { ... }
115 * </p>
116 *
117 * <p>
118 *    This annotation can also be used on uninitialized fields.  When fields are uninitialized, they will
119 *    be set during initialization based on beans found in the bean store.
120 * </p>
121 * <h5 class='figure'>Example</h5>
122 * <p class='bcode'>
123 *    <jc>// Fields that get set during initialization based on beans found in the bean store.</jc>
124 *    <ja>@RestInject</ja> CallLogger <jf>callLogger</jf>;
125 *    <ja>@RestInject</ja> BeanStore <jf>beanStore</jf>;  <jc>// Note that BeanStore itself can be accessed this way.</jc>
126 * </p>
127 *
128 * <h5 class='section'>Notes:</h5><ul>
129 *    <li class='note'>Methods and fields can be static or non-static.
130 *    <li class='note'>Any injectable beans (including spring beans) can be passed as arguments into methods.
131 *    <li class='note'>Bean names are required when multiple beans of the same type exist in the bean store.
132 *    <li class='note'>By default, the injected bean scope is class-level (applies to the entire class).  The
133 *       {@link RestInject#methodScope()} annotation can be used to apply to method-level only (when applicable).
134 * </ul>
135 *
136 * <p>
137 * Any of the following types can be customized via injection:
138 * <table class='w800 styled'>
139 *    <tr><th>Bean class</td><th>Bean qualifying names</th><th>Scope</th></tr>
140 *    <tr><td>{@link BeanContext}<br>{@link org.apache.juneau.BeanContext.Builder}</td><td></td><td>class<br>method</td></tr>
141 *    <tr><td>{@link BeanStore}<br>{@link org.apache.juneau.cp.BeanStore.Builder}</td><td></td><td>class</td></tr>
142 *    <tr><td>{@link CallLogger}<br>{@link org.apache.juneau.rest.logger.CallLogger.Builder}</td><td></td><td>class</td></tr>
143 *    <tr><td>{@link Config}</td><td></td><td>class</td></tr>
144 *    <tr><td>{@link DebugEnablement}<br>{@link org.apache.juneau.rest.debug.DebugEnablement.Builder}</td><td></td><td>class</td></tr>
145 *    <tr><td>{@link EncoderSet}<br>{@link org.apache.juneau.encoders.EncoderSet.Builder}</td><td></td><td>class<br>method</td></tr>
146 *    <tr><td>{@link FileFinder}<br>{@link org.apache.juneau.cp.FileFinder.Builder}</td><td></td><td>class</td></tr>
147 *    <tr><td>{@link HeaderList}<br>{@link org.apache.juneau.http.header.HeaderList}</td><td><js>"defaultRequestHeaders"</js><br><js>"defaultResponseHeaders"</js></td><td>class<br>method</td></tr>
148 *    <tr><td>{@link HttpPartParser}<br>{@link org.apache.juneau.httppart.HttpPartParser.Creator}</td><td></td><td>class<br>method</td></tr>
149 *    <tr><td>{@link HttpPartSerializer}<br>{@link org.apache.juneau.httppart.HttpPartSerializer.Creator}</td><td></td><td>class<br>method</td></tr>
150 *    <tr><td>{@link JsonSchemaGenerator}<br>{@link org.apache.juneau.jsonschema.JsonSchemaGenerator.Builder}</td><td></td><td>class<br>method</td></tr>
151 *    <tr><td>{@link Logger}</td><td></td><td>class</td></tr>
152 *    <tr><td>{@link Messages}<br>{@link org.apache.juneau.cp.Messages.Builder}</td><td></td><td>class</td></tr>
153 *    <tr><td>{@link MethodExecStore}<br>{@link org.apache.juneau.rest.stats.MethodExecStore.Builder}</td><td></td><td>class</td></tr>
154 *    <tr><td>{@link MethodList}</td><td><js>"destroyMethods"</js><br><js>"endCallMethods"</js><br><js>"postCallMethods"</js><br><js>"postInitChildFirstMethods"</js><br><js>"postInitMethods"</js><br><js>"preCallMethods"</js><br><js>"startCallMethods"</js></td><td>class</td></tr>
155 *    <tr><td>{@link NamedAttributeMap}<br>{@link org.apache.juneau.rest.httppart.NamedAttributeMap}</td><td><js>"defaultRequestAttributes"</js></td><td>class<br>method</td></tr>
156 *    <tr><td>{@link ParserSet}<br>{@link org.apache.juneau.parser.ParserSet.Builder}</td><td></td><td>class<br>method</td></tr>
157 *    <tr><td>{@link PartList}<br>{@link org.apache.juneau.http.part.PartList}</td><td><js>"defaultRequestQueryData"</js><br><js>"defaultRequestFormData"</js></td><td>method</td></tr>
158 *    <tr><td>{@link ResponseProcessorList}<br>{@link org.apache.juneau.rest.processor.ResponseProcessorList.Builder}</td><td></td><td>class</td></tr>
159 *    <tr><td>{@link RestChildren}<br>{@link org.apache.juneau.rest.RestChildren.Builder}</td><td></td><td>class</td></tr>
160 *    <tr><td>{@link RestConverterList}<br>{@link org.apache.juneau.rest.converter.RestConverterList.Builder}</td><td></td><td>method</td></tr>
161 *    <tr><td>{@link RestGuardList}<br>{@link org.apache.juneau.rest.guard.RestGuardList.Builder}</td><td></td><td>method</td></tr>
162 *    <tr><td>{@link RestMatcherList}<br>{@link org.apache.juneau.rest.matcher.RestMatcherList.Builder}</td><td></td><td>method</td></tr>
163 *    <tr><td>{@link RestOpArgList}<br>{@link org.apache.juneau.rest.arg.RestOpArgList.Builder}</td><td></td><td>class</td></tr>
164 *    <tr><td>{@link RestOperations}<br>{@link org.apache.juneau.rest.RestOperations.Builder}</td><td></td><td>class</td></tr>
165 *    <tr><td>{@link SerializerSet}<br>{@link org.apache.juneau.serializer.SerializerSet.Builder}</td><td></td><td>class<br>method</td></tr>
166 *    <tr><td>{@link StaticFiles}<br>{@link org.apache.juneau.rest.staticfile.StaticFiles.Builder}</td><td></td><td>class</td></tr>
167 *    <tr><td>{@link SwaggerProvider}<br>{@link org.apache.juneau.rest.swagger.SwaggerProvider.Builder}</td><td></td><td>class</td></tr>
168 *    <tr><td>{@link ThrownStore}<br>{@link org.apache.juneau.rest.stats.ThrownStore.Builder}</td><td></td><td>class</td></tr>
169 *    <tr><td>{@link UrlPathMatcherList}</td><td></td><td>method</td></tr>
170 *    <tr><td>{@link VarList}</td><td></td><td>class</td></tr>
171 *    <tr><td>{@link VarResolver}<br>{@link org.apache.juneau.svl.VarResolver.Builder}</td><td></td><td>class</td></tr>
172 * </table>
173 */
174@Target({METHOD,FIELD})
175@Retention(RUNTIME)
176@Inherited
177public @interface RestInject {
178
179   /**
180    * The bean name to use to distinguish beans of the same type for different purposes.
181    *
182    * <p>
183    * For example, there are two {@link HeaderList} beans:  <js>"defaultRequestHeaders"</js> and <js>"defaultResponseHeaders"</js>.  This annotation
184    * would be used to differentiate between them.
185    *
186    * @return The bean name to use to distinguish beans of the same type for different purposes, or blank if bean type is unique.
187    */
188   String name() default "";
189
190
191   /**
192    * Same as {@link #name()}.
193    *
194    * @return The bean name to use to distinguish beans of the same type for different purposes, or blank if bean type is unique.
195    */
196   String value() default "";
197
198   /**
199    * The short names of the methods that this annotation applies to.
200    *
201    * <p>
202    * Can use <js>"*"</js> to apply to all methods.
203    *
204    * <p>
205    * Ignored for class-level scope.
206    *
207    * @return The short names of the methods that this annotation applies to, or empty if class-scope.
208    */
209   String[] methodScope() default {};
210}