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