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; 014 015import static org.apache.juneau.internal.ConsumerUtils.*; 016 017import java.lang.annotation.*; 018import java.lang.reflect.*; 019import java.util.function.*; 020 021import org.apache.juneau.internal.*; 022 023/** 024 * Interface that provides the ability to look up annotations on classes/methods/constructors/fields. 025 * 026 * <h5 class='section'>See Also:</h5><ul> 027 * </ul> 028 */ 029public interface AnnotationProvider { 030 031 /** 032 * Disable annotation caching. 033 */ 034 static final boolean DISABLE_ANNOTATION_CACHING = Boolean.getBoolean("juneau.disableAnnotationCaching"); 035 036 /** 037 * Default metadata provider. 038 */ 039 @SuppressWarnings("unchecked") 040 public static final AnnotationProvider DEFAULT = new AnnotationProvider() { 041 042 private final TwoKeyConcurrentCache<Class<?>,Class<? extends Annotation>,Annotation[]> classAnnotationCache = new TwoKeyConcurrentCache<>(DISABLE_ANNOTATION_CACHING, (k1,k2) -> k1.getAnnotationsByType(k2)); 043 private final TwoKeyConcurrentCache<Class<?>,Class<? extends Annotation>,Annotation[]> declaredClassAnnotationCache = new TwoKeyConcurrentCache<>(DISABLE_ANNOTATION_CACHING, (k1,k2) -> k1.getDeclaredAnnotationsByType(k2)); 044 private final TwoKeyConcurrentCache<Method,Class<? extends Annotation>,Annotation[]> methodAnnotationCache = new TwoKeyConcurrentCache<>(DISABLE_ANNOTATION_CACHING, (k1,k2) -> k1.getAnnotationsByType(k2)); 045 private final TwoKeyConcurrentCache<Field,Class<? extends Annotation>,Annotation[]> fieldAnnotationCache = new TwoKeyConcurrentCache<>(DISABLE_ANNOTATION_CACHING, (k1,k2) -> k1.getAnnotationsByType(k2)); 046 private final TwoKeyConcurrentCache<Constructor<?>,Class<? extends Annotation>,Annotation[]> constructorAnnotationCache = new TwoKeyConcurrentCache<>(DISABLE_ANNOTATION_CACHING, (k1,k2) -> k1.getAnnotationsByType(k2)); 047 048 @Override /* MetaProvider */ 049 public <A extends Annotation> void forEachAnnotation(Class<A> type, Class<?> onClass, Predicate<A> filter, Consumer<A> action) { 050 if (type != null && onClass != null) 051 for (A a : annotations(type, onClass)) 052 consume(filter, action, a); 053 } 054 055 @Override /* MetaProvider */ 056 public <A extends Annotation> A firstAnnotation(Class<A> type, Class<?> onClass, Predicate<A> filter) { 057 if (type != null && onClass != null) 058 for (A a : annotations(type, onClass)) 059 if (test(filter, a)) 060 return a; 061 return null; 062 } 063 064 @Override /* MetaProvider */ 065 public <A extends Annotation> A lastAnnotation(Class<A> type, Class<?> onClass, Predicate<A> filter) { 066 A x = null; 067 if (type != null && onClass != null) 068 for (A a : annotations(type, onClass)) 069 if (test(filter, a)) 070 x = a; 071 return x; 072 } 073 074 @Override /* MetaProvider */ 075 public <A extends Annotation> void forEachDeclaredAnnotation(Class<A> type, Class<?> onClass, Predicate<A> filter, Consumer<A> action) { 076 if (type != null && onClass != null) 077 for (A a : declaredAnnotations(type, onClass)) 078 consume(filter, action, a); 079 } 080 081 @Override /* MetaProvider */ 082 public <A extends Annotation> A firstDeclaredAnnotation(Class<A> type, Class<?> onClass, Predicate<A> filter) { 083 if (type != null && onClass != null) 084 for (A a : declaredAnnotations(type, onClass)) 085 if (test(filter, a)) 086 return a; 087 return null; 088 } 089 090 @Override /* MetaProvider */ 091 public <A extends Annotation> A lastDeclaredAnnotation(Class<A> type, Class<?> onClass, Predicate<A> filter) { 092 A x = null; 093 if (type != null && onClass != null) 094 for (A a : declaredAnnotations(type, onClass)) 095 if (test(filter, a)) 096 x = a; 097 return x; 098 } 099 100 @Override /* MetaProvider */ 101 public <A extends Annotation> void forEachAnnotation(Class<A> type, Method onMethod, Predicate<A> filter, Consumer<A> action) { 102 if (type != null && onMethod != null) 103 for (A a : annotations(type, onMethod)) 104 consume(filter, action, a); 105 } 106 107 @Override /* MetaProvider */ 108 public <A extends Annotation> A firstAnnotation(Class<A> type, Method onMethod, Predicate<A> filter) { 109 if (type != null && onMethod != null) 110 for (A a : annotations(type, onMethod)) 111 if (test(filter, a)) 112 return a; 113 return null; 114 } 115 116 @Override /* MetaProvider */ 117 public <A extends Annotation> A lastAnnotation(Class<A> type, Method onMethod, Predicate<A> filter) { 118 A x = null; 119 if (type != null && onMethod != null) 120 for (A a : annotations(type, onMethod)) 121 if (test(filter, a)) 122 x = a; 123 return x; 124 } 125 126 @Override /* MetaProvider */ 127 public <A extends Annotation> void forEachAnnotation(Class<A> type, Field onField, Predicate<A> filter, Consumer<A> action) { 128 if (type != null && onField != null) 129 for (A a : annotations(type, onField)) 130 consume(filter, action, a); 131 } 132 133 @Override /* MetaProvider */ 134 public <A extends Annotation> A firstAnnotation(Class<A> type, Field onField, Predicate<A> filter) { 135 if (type != null && onField != null) 136 for (A a : annotations(type, onField)) 137 if (test(filter, a)) 138 return a; 139 return null; 140 } 141 142 @Override /* MetaProvider */ 143 public <A extends Annotation> A lastAnnotation(Class<A> type, Field onField, Predicate<A> filter) { 144 A x = null; 145 if (type != null && onField != null) 146 for (A a : annotations(type, onField)) 147 if (test(filter, a)) 148 x = a; 149 return x; 150 } 151 152 @Override /* MetaProvider */ 153 public <A extends Annotation> void forEachAnnotation(Class<A> type, Constructor<?> onConstructor, Predicate<A> filter, Consumer<A> action) { 154 if (type != null && onConstructor != null) 155 for (A a : annotations(type, onConstructor)) 156 consume(filter, action, a); 157 } 158 159 @Override /* MetaProvider */ 160 public <A extends Annotation> A firstAnnotation(Class<A> type, Constructor<?> onConstructor, Predicate<A> filter) { 161 if (type != null && onConstructor != null) 162 for (A a : annotations(type, onConstructor)) 163 if (test(filter, a)) 164 return a; 165 return null; 166 } 167 168 @Override /* MetaProvider */ 169 public <A extends Annotation> A lastAnnotation(Class<A> type, Constructor<?> onConstructor, Predicate<A> filter) { 170 A x = null; 171 if (type != null && onConstructor != null) 172 for (A a : annotations(type, onConstructor)) 173 if (test(filter, a)) 174 x = a; 175 return x; 176 } 177 178 private <A extends Annotation> A[] annotations(Class<A> type, Class<?> onClass) { 179 return (A[])classAnnotationCache.get(onClass, type); 180 } 181 182 private <A extends Annotation> A[] declaredAnnotations(Class<A> type, Class<?> onClass) { 183 return (A[])declaredClassAnnotationCache.get(onClass, type); 184 } 185 186 private <A extends Annotation> A[] annotations(Class<A> type, Method onMethod) { 187 return (A[])methodAnnotationCache.get(onMethod, type); 188 } 189 190 private <A extends Annotation> A[] annotations(Class<A> type, Field onField) { 191 return (A[])fieldAnnotationCache.get(onField, type); 192 } 193 194 private <A extends Annotation> A[] annotations(Class<A> type, Constructor<?> onConstructor) { 195 return (A[])constructorAnnotationCache.get(onConstructor, type); 196 } 197 }; 198 199 /** 200 * Performs an action on the matching annotations on the specified class. 201 * 202 * @param <A> The annotation type to find. 203 * @param type The annotation type to find. 204 * @param onClass The class to search on. 205 * @param filter A predicate to apply to the entries to determine if action should be performed. Can be <jk>null</jk>. 206 * @param action An action to perform on the entry. 207 */ 208 <A extends Annotation> void forEachAnnotation(Class<A> type, Class<?> onClass, Predicate<A> filter, Consumer<A> action); 209 210 /** 211 * Finds the first matching annotation on the specified class. 212 * 213 * @param <A> The annotation type to find. 214 * @param type The annotation type to find. 215 * @param onClass The class to search on. 216 * @param filter A predicate to apply to the entries to determine if value should be used. Can be <jk>null</jk>. 217 * @return The matched annotation, or <jk>null</jk> if not found. 218 */ 219 <A extends Annotation> A firstAnnotation(Class<A> type, Class<?> onClass, Predicate<A> filter); 220 221 /** 222 * Finds the last matching annotation on the specified class. 223 * 224 * @param <A> The annotation type to find. 225 * @param type The annotation type to find. 226 * @param onClass The class to search on. 227 * @param filter A predicate to apply to the entries to determine if value should be used. Can be <jk>null</jk>. 228 * @return The matched annotation, or <jk>null</jk> if not found. 229 */ 230 <A extends Annotation> A lastAnnotation(Class<A> type, Class<?> onClass, Predicate<A> filter); 231 232 /** 233 * Performs an action on the matching declared annotations on the specified class. 234 * 235 * @param <A> The annotation type to find. 236 * @param type The annotation type to find. 237 * @param onClass The class to search on. 238 * @param filter A predicate to apply to the entries to determine if action should be performed. Can be <jk>null</jk>. 239 * @param action An action to perform on the entry. 240 */ 241 <A extends Annotation> void forEachDeclaredAnnotation(Class<A> type, Class<?> onClass, Predicate<A> filter, Consumer<A> action); 242 243 /** 244 * Finds the first matching declared annotations on the specified class. 245 * 246 * @param <A> The annotation type to find. 247 * @param type The annotation type to find. 248 * @param onClass The class to search on. 249 * @param filter A predicate to apply to the entries to determine if value should be used. Can be <jk>null</jk>. 250 * @return The matched annotation, or <jk>null</jk> if no annotations matched. 251 */ 252 <A extends Annotation> A firstDeclaredAnnotation(Class<A> type, Class<?> onClass, Predicate<A> filter); 253 254 /** 255 * Finds the last matching declared annotations on the specified class. 256 * 257 * @param <A> The annotation type to find. 258 * @param type The annotation type to find. 259 * @param onClass The class to search on. 260 * @param filter A predicate to apply to the entries to determine if value should be used. Can be <jk>null</jk>. 261 * @return The matched annotation, or <jk>null</jk> if no annotations matched. 262 */ 263 <A extends Annotation> A lastDeclaredAnnotation(Class<A> type, Class<?> onClass, Predicate<A> filter); 264 265 /** 266 * Performs an action on the matching annotations on the specified method. 267 * 268 * @param <A> The annotation type to find. 269 * @param type The annotation type to find. 270 * @param onMethod The method to search on. 271 * @param filter A predicate to apply to the entries to determine if action should be performed. Can be <jk>null</jk>. 272 * @param action An action to perform on the entry. 273 */ 274 <A extends Annotation> void forEachAnnotation(Class<A> type, Method onMethod, Predicate<A> filter, Consumer<A> action); 275 276 /** 277 * Finds the first matching annotation on the specified method. 278 * 279 * @param <A> The annotation type to find. 280 * @param type The annotation type to find. 281 * @param onMethod The method to search on. 282 * @param filter A predicate to apply to the entries to determine if value should be used. Can be <jk>null</jk>. 283 * @return The matched annotation, or <jk>null</jk> if no annotations matched. 284 */ 285 <A extends Annotation> A firstAnnotation(Class<A> type, Method onMethod, Predicate<A> filter); 286 287 /** 288 * Finds the last matching annotation on the specified method. 289 * 290 * @param <A> The annotation type to find. 291 * @param type The annotation type to find. 292 * @param onMethod The method to search on. 293 * @param filter A predicate to apply to the entries to determine if value should be used. Can be <jk>null</jk>. 294 * @return The matched annotation, or <jk>null</jk> if no annotations matched. 295 */ 296 <A extends Annotation> A lastAnnotation(Class<A> type, Method onMethod, Predicate<A> filter); 297 298 /** 299 * Performs an action on the matching annotations on the specified field. 300 * 301 * @param <A> The annotation type to find. 302 * @param type The annotation type to find. 303 * @param onField The field to search on. 304 * @param filter A predicate to apply to the entries to determine if action should be performed. Can be <jk>null</jk>. 305 * @param action An action to perform on the entry. 306 */ 307 <A extends Annotation> void forEachAnnotation(Class<A> type, Field onField, Predicate<A> filter, Consumer<A> action); 308 309 /** 310 * Finds the first matching annotation on the specified field. 311 * 312 * @param <A> The annotation type to find. 313 * @param type The annotation type to find. 314 * @param onField The field to search on. 315 * @param filter A predicate to apply to the entries to determine if value should be used. Can be <jk>null</jk>. 316 * @return The matched annotation, or <jk>null</jk> if no annotations matched. 317 */ 318 <A extends Annotation> A firstAnnotation(Class<A> type, Field onField, Predicate<A> filter); 319 320 /** 321 * Finds the last matching annotation on the specified field. 322 * 323 * @param <A> The annotation type to find. 324 * @param type The annotation type to find. 325 * @param onField The field to search on. 326 * @param filter A predicate to apply to the entries to determine if value should be used. Can be <jk>null</jk>. 327 * @return The matched annotation, or <jk>null</jk> if no annotations matched. 328 */ 329 <A extends Annotation> A lastAnnotation(Class<A> type, Field onField, Predicate<A> filter); 330 331 /** 332 * Performs an action on the matching annotations on the specified constructor. 333 * 334 * @param <A> The annotation type to find. 335 * @param type The annotation type to find. 336 * @param onConstructor The constructor to search on. 337 * @param filter A predicate to apply to the entries to determine if action should be performed. Can be <jk>null</jk>. 338 * @param action An action to perform on the entry. 339 */ 340 <A extends Annotation> void forEachAnnotation(Class<A> type, Constructor<?> onConstructor, Predicate<A> filter, Consumer<A> action); 341 342 /** 343 * Finds the first matching annotation on the specified constructor. 344 * 345 * @param <A> The annotation type to find. 346 * @param type The annotation type to find. 347 * @param onConstructor The constructor to search on. 348 * @param filter A predicate to apply to the entries to determine if value should be used. Can be <jk>null</jk>. 349 * @return The matched annotation, or <jk>null</jk> if no annotations matched. 350 */ 351 <A extends Annotation> A firstAnnotation(Class<A> type, Constructor<?> onConstructor, Predicate<A> filter); 352 353 /** 354 * Finds the last matching annotation on the specified constructor. 355 * 356 * @param <A> The annotation type to find. 357 * @param type The annotation type to find. 358 * @param onConstructor The constructor to search on. 359 * @param filter A predicate to apply to the entries to determine if value should be used. Can be <jk>null</jk>. 360 * @return The matched annotation, or <jk>null</jk> if no annotations matched. 361 */ 362 <A extends Annotation> A lastAnnotation(Class<A> type, Constructor<?> onConstructor, Predicate<A> filter); 363}