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