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.annotation;
014
015import static java.lang.annotation.ElementType.*;
016import static java.lang.annotation.RetentionPolicy.*;
017
018import java.lang.annotation.*;
019
020import org.apache.juneau.swap.*;
021
022/**
023 * Associates {@link ObjectSwap} and {@link Surrogate} classes with POJOs and bean properties.
024 *
025 * <p>
026 * Can be used in the following locations:
027 * <ul>
028 *    <li>Classes.
029 *    <li>Bean getters/setters/fields.
030 *    <li><ja>@Rest</ja>-annotated classes and <ja>@RestOp</ja>-annotated methods when an {@link #on()} value is specified.
031 * </ul>
032
033 * <h5 class='section'>See Also:</h5><ul>
034 *    <li class='link'><a class="doclink" href="../../../../index.html#jm.SwapAnnotation">@Swap Annotation</a>
035
036 * </ul>
037 */
038@Documented
039@Target({TYPE,ANNOTATION_TYPE,FIELD,METHOD})
040@Retention(RUNTIME)
041@Inherited
042@Repeatable(SwapAnnotation.Array.class)
043@ContextApply(SwapAnnotation.Applier.class)
044public @interface Swap {
045
046   /**
047    * The {@link ObjectSwap} and {@link Surrogate} class.
048    *
049    * <p>
050    * A synonym for {@link #value()}.
051    *
052    * @return The annotation value.
053    */
054   Class<?> impl() default void.class;
055
056   /**
057    * Identifies the media types that this swap is applicable for.
058    *
059    * <p>
060    * In the following example, the swap is only invoked by the JSON serializer:
061    *
062    * <p class='bjava'>
063    *    <ja>@Swap</ja>(impl=ToStringSwap.<jk>class</jk>, mediaTypes=<js>"&#42;/json"</js>)
064    *    <jk>public class</jk> MyBean { ... }
065    *
066    *    <jk>public class</jk> ToStringSwap <jk>extends</jk> ObjectSwap&lt;Object,String&gt; {
067    *          <jk>public</jk> String swap(BeanSession <jv>session</jv>, Object <jv>value</jv>) <jk>throws</jk> Exception {
068    *             <jk>return</jk> <jv>value</jv>.toString();
069    *          }
070    *       }
071    * </p>
072    *
073    * <h5 class='section'>See Also:</h5><ul>
074    *    <li class='link'><a class="doclink" href="../../../../index.html#jm.PerMediaTypeSwaps">Per-media-type Swaps</a>
075    * </ul>
076    *
077    * @return The annotation value.
078    */
079   String[] mediaTypes() default {};
080
081   /**
082    * Dynamically apply this annotation to the specified classes/methods/fields.
083    *
084    * <p>
085    * Used in conjunction with {@link org.apache.juneau.BeanContext.Builder#applyAnnotations(Class...)} to dynamically apply an annotation to an existing class.
086    * It is ignored when the annotation is applied directly to classes.
087    *
088    * <h5 class='section'>Valid patterns:</h5>
089    * <ul class='spaced-list'>
090    *  <li>Classes:
091    *       <ul>
092    *          <li>Fully qualified:
093    *             <ul>
094    *                <li><js>"com.foo.MyClass"</js>
095    *             </ul>
096    *          <li>Fully qualified inner class:
097    *             <ul>
098    *                <li><js>"com.foo.MyClass$Inner1$Inner2"</js>
099    *             </ul>
100    *          <li>Simple:
101    *             <ul>
102    *                <li><js>"MyClass"</js>
103    *             </ul>
104    *          <li>Simple inner:
105    *             <ul>
106    *                <li><js>"MyClass$Inner1$Inner2"</js>
107    *                <li><js>"Inner1$Inner2"</js>
108    *                <li><js>"Inner2"</js>
109    *             </ul>
110    *       </ul>
111    *    <li>Methods:
112    *       <ul>
113    *          <li>Fully qualified with args:
114    *             <ul>
115    *                <li><js>"com.foo.MyClass.myMethod(String,int)"</js>
116    *                <li><js>"com.foo.MyClass.myMethod(java.lang.String,int)"</js>
117    *                <li><js>"com.foo.MyClass.myMethod()"</js>
118    *             </ul>
119    *          <li>Fully qualified:
120    *             <ul>
121    *                <li><js>"com.foo.MyClass.myMethod"</js>
122    *             </ul>
123    *          <li>Simple with args:
124    *             <ul>
125    *                <li><js>"MyClass.myMethod(String,int)"</js>
126    *                <li><js>"MyClass.myMethod(java.lang.String,int)"</js>
127    *                <li><js>"MyClass.myMethod()"</js>
128    *             </ul>
129    *          <li>Simple:
130    *             <ul>
131    *                <li><js>"MyClass.myMethod"</js>
132    *             </ul>
133    *          <li>Simple inner class:
134    *             <ul>
135    *                <li><js>"MyClass$Inner1$Inner2.myMethod"</js>
136    *                <li><js>"Inner1$Inner2.myMethod"</js>
137    *                <li><js>"Inner2.myMethod"</js>
138    *             </ul>
139    *       </ul>
140    *    <li>Fields:
141    *       <ul>
142    *          <li>Fully qualified:
143    *             <ul>
144    *                <li><js>"com.foo.MyClass.myField"</js>
145    *             </ul>
146    *          <li>Simple:
147    *             <ul>
148    *                <li><js>"MyClass.myField"</js>
149    *             </ul>
150    *          <li>Simple inner class:
151    *             <ul>
152    *                <li><js>"MyClass$Inner1$Inner2.myField"</js>
153    *                <li><js>"Inner1$Inner2.myField"</js>
154    *                <li><js>"Inner2.myField"</js>
155    *             </ul>
156    *       </ul>
157    *    <li>A comma-delimited list of anything on this list.
158    * </ul>
159    *
160    * <h5 class='section'>See Also:</h5><ul>
161    *    <li class='link'><a class="doclink" href="../../../../index.html#jm.DynamicallyAppliedAnnotations">Dynamically Applied Annotations</a>
162    * </ul>
163    *
164    * @return The annotation value.
165    */
166   String[] on() default {};
167
168   /**
169    * Dynamically apply this annotation to the specified classes.
170    *
171    * <p>
172    * Identical to {@link #on()} except allows you to specify class objects instead of a strings.
173    *
174    * <h5 class='section'>See Also:</h5><ul>
175    *    <li class='link'><a class="doclink" href="../../../../index.html#jm.DynamicallyAppliedAnnotations">Dynamically Applied Annotations</a>
176    * </ul>
177    *
178    * @return The annotation value.
179    */
180   Class<?>[] onClass() default {};
181
182   /**
183    * Identifies a template string along with this swap.
184    *
185    * <p>
186    * Template strings are arbitrary strings associated with swaps that help provide additional context information
187    * for the swap class.
188    * They're called 'templates' because their primary purpose is for providing template names, such as Apache FreeMarker
189    * template names.
190    *
191    * <p>
192    * The following is an example of a templated swap class used to serialize POJOs to HTML using FreeMarker:
193    *
194    * <p class='bjava'>
195    *    <jc>// Our templated swap class.</jc>
196    *    <jk>public class</jk> FreeMarkerSwap <jk>extends</jk> ObjectSwap&lt;Object,Reader&gt; {
197    *
198    *       <jk>public</jk> MediaType[] forMediaTypes() {
199    *          <jk>return</jk> MediaType.<jsm>forStrings</jsm>(<js>"&#42;/html"</js>);
200    *       }
201    *
202    *       <jk>public</jk> Reader swap(BeanSession <jv>session</jv>, Object <jv>value</jv>, String <jv>template</jv>) <jk>throws</jk> Exception {
203    *          <jk>return</jk> <jsm>getFreeMarkerReader</jsm>(<jv>template</jv>, <jv>value</jv>);  <jc>// Some method that creates raw HTML.</jc>
204    *       }
205    *    }
206    * </p>
207    * <p class='bjava'>
208    *    <ja>@Swap</ja>(impl=FreeMarkerSwap.<jk>class</jk>, template=<js>"MyPojo.div.ftl"</js>)
209    *    <jk>public class</jk> MyPojo {}
210    * </p>
211    *
212    * <h5 class='section'>See Also:</h5><ul>
213    *    <li class='link'><a class="doclink" href="../../../../index.html#jm.TemplatedSwaps">Templated Swaps</a>
214    * </ul>
215    *
216    * @return The annotation value.
217    */
218   String template() default "";
219
220   /**
221    * The {@link ObjectSwap} and {@link Surrogate} class.
222    *
223    * <p>
224    * A synonym for {@link #impl()}.
225    *
226    * @return The annotation value.
227    */
228   Class<?> value() default void.class;
229}