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.transform.*; 021 022/** 023 * Associates {@link PojoSwap} and {@link Surrogate} classes with POJOs and bean properties. 024 * 025 * <p> 026 * This annotation can be used in the following locations: 027 * <ul> 028 * <li>Classes. 029 * <li>Bean getters/setters/fields. 030 * <li>Inside the {@link Swaps @Swaps} annotation. 031 * </ul> 032 * 033 * <ul class='seealso'> 034 * <li class='link'>{@doc juneau-marshall.Transforms.SwapAnnotation} 035 * </ul> 036 */ 037@Documented 038@Target({TYPE,ANNOTATION_TYPE,FIELD,METHOD}) 039@Retention(RUNTIME) 040@Inherited 041public @interface Swap { 042 043 /** 044 * The {@link PojoSwap} and {@link Surrogate} class. 045 * 046 * <p> 047 * A synonym for {@link #value()}. 048 */ 049 Class<?> impl() default Null.class; 050 051 /** 052 * Identifies the media types that this swap is applicable for. 053 * 054 * <p> 055 * In the following example, the swap is only invoked by the JSON serializer: 056 * 057 * <p class='bcode w800'> 058 * <ja>@Swap</ja>(impl=ToStringSwap.<jk>class</jk>, mediaTypes=<js>"*/json"</js>) 059 * <jk>public class</jk> MyBean { ... } 060 * 061 * <jk>public class</jk> ToStringSwap <jk>extends</jk> PojoSwap<Object,String> { 062 * <jk>public</jk> String swap(BeanSession session, Object o) <jk>throws</jk> Exception { 063 * <jk>return</jk> o.toString(); 064 * } 065 * } 066 * </p> 067 * 068 * <ul class='seealso'> 069 * <li class='link'>{@doc juneau-marshall.Transforms.PerMediaTypePojoSwaps} 070 * </ul> 071 */ 072 String[] mediaTypes() default {}; 073 074 /** 075 * Dynamically apply this annotation to the specified classes/methods/fields. 076 * 077 * <p> 078 * Used in conjunction with the {@link BeanConfig#applySwap()}. 079 * It is ignored when the annotation is applied directly to classes. 080 * 081 * <h5 class='section'>Valid patterns:</h5> 082 * <ul class='spaced-list'> 083 * <li>Classes: 084 * <ul> 085 * <li>Fully qualified: 086 * <ul> 087 * <li><js>"com.foo.MyClass"</js> 088 * </ul> 089 * <li>Fully qualified inner class: 090 * <ul> 091 * <li><js>"com.foo.MyClass$Inner1$Inner2"</js> 092 * </ul> 093 * <li>Simple: 094 * <ul> 095 * <li><js>"MyClass"</js> 096 * </ul> 097 * <li>Simple inner: 098 * <ul> 099 * <li><js>"MyClass$Inner1$Inner2"</js> 100 * <li><js>"Inner1$Inner2"</js> 101 * <li><js>"Inner2"</js> 102 * </ul> 103 * </ul> 104 * <li>Methods: 105 * <ul> 106 * <li>Fully qualified with args: 107 * <ul> 108 * <li><js>"com.foo.MyClass.myMethod(String,int)"</js> 109 * <li><js>"com.foo.MyClass.myMethod(java.lang.String,int)"</js> 110 * <li><js>"com.foo.MyClass.myMethod()"</js> 111 * </ul> 112 * <li>Fully qualified: 113 * <ul> 114 * <li><js>"com.foo.MyClass.myMethod"</js> 115 * </ul> 116 * <li>Simple with args: 117 * <ul> 118 * <li><js>"MyClass.myMethod(String,int)"</js> 119 * <li><js>"MyClass.myMethod(java.lang.String,int)"</js> 120 * <li><js>"MyClass.myMethod()"</js> 121 * </ul> 122 * <li>Simple: 123 * <ul> 124 * <li><js>"MyClass.myMethod"</js> 125 * </ul> 126 * <li>Simple inner class: 127 * <ul> 128 * <li><js>"MyClass$Inner1$Inner2.myMethod"</js> 129 * <li><js>"Inner1$Inner2.myMethod"</js> 130 * <li><js>"Inner2.myMethod"</js> 131 * </ul> 132 * </ul> 133 * <li>Fields: 134 * <ul> 135 * <li>Fully qualified: 136 * <ul> 137 * <li><js>"com.foo.MyClass.myField"</js> 138 * </ul> 139 * <li>Simple: 140 * <ul> 141 * <li><js>"MyClass.myField"</js> 142 * </ul> 143 * <li>Simple inner class: 144 * <ul> 145 * <li><js>"MyClass$Inner1$Inner2.myField"</js> 146 * <li><js>"Inner1$Inner2.myField"</js> 147 * <li><js>"Inner2.myField"</js> 148 * </ul> 149 * </ul> 150 * <li>A comma-delimited list of anything on this list. 151 * </ul> 152 * 153 * <ul class='seealso'> 154 * <li class='link'>{@doc juneau-marshall.DynamicallyAppliedAnnotations} 155 * </ul> 156 */ 157 String on() default ""; 158 159 /** 160 * Identifies a template string along with this swap. 161 * 162 * <p> 163 * Template strings are arbitrary strings associated with swaps that help provide additional context information 164 * for the swap class. 165 * They're called 'templates' because their primary purpose is for providing template names, such as Apache FreeMarker 166 * template names. 167 * 168 * <p> 169 * The following is an example of a templated swap class used to serialize POJOs to HTML using FreeMarker: 170 * 171 * <p class='bcode w800'> 172 * <jc>// Our templated swap class.</jc> 173 * <jk>public class</jk> FreeMarkerSwap <jk>extends</jk> PojoSwap<Object,Reader> { 174 * 175 * <jk>public</jk> MediaType[] forMediaTypes() { 176 * <jk>return</jk> MediaType.<jsm>forStrings</jsm>(<js>"*/html"</js>); 177 * } 178 * 179 * <jk>public</jk> Reader swap(BeanSession session, Object o, String template) <jk>throws</jk> Exception { 180 * <jk>return</jk> getFreeMarkerReader(template, o); <jc>// Some method that creates raw HTML.</jc> 181 * } 182 * } 183 * </p> 184 * <p class='bcode w800'> 185 * <ja>@Swap</ja>(impl=FreeMarkerSwap.<jk>class</jk>, template=<js>"MyPojo.div.ftl"</js>) 186 * <jk>public class</jk> MyPojo {} 187 * </p> 188 * 189 * <ul class='seealso'> 190 * <li class='link'>{@doc juneau-marshall.Transforms.TemplatedSwaps} 191 * </ul> 192 */ 193 String template() default ""; 194 195 /** 196 * The {@link PojoSwap} and {@link Surrogate} class. 197 * 198 * <p> 199 * A synonym for {@link #impl()}. 200 */ 201 Class<?> value() default Null.class; 202}