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}