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