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.camel.util; 018 019import java.lang.annotation.Annotation; 020import java.lang.reflect.AnnotatedElement; 021import java.lang.reflect.Field; 022import java.lang.reflect.Method; 023import java.util.ArrayList; 024import java.util.List; 025 026public final class AnnotationHelper { 027 028 /** 029 * Returns a list of methods which are annotated with the given annotation 030 * 031 * @param type the type to reflect on 032 * @param annotationType the annotation type 033 * @return a list of the methods found 034 */ 035 public static List<Method> findMethodsWithAnnotation( 036 Class<?> type, 037 Class<? extends Annotation> annotationType) { 038 return findMethodsWithAnnotation(type, annotationType, false); 039 } 040 041 /** 042 * Returns a list of methods which are annotated with the given annotation 043 * 044 * @param type the type to reflect on 045 * @param annotationType the annotation type 046 * @param checkMetaAnnotations check for meta annotations 047 * @return a list of the methods found 048 */ 049 public static List<Method> findMethodsWithAnnotation( 050 Class<?> type, 051 Class<? extends Annotation> annotationType, 052 boolean checkMetaAnnotations) { 053 List<Method> answer = new ArrayList<>(); 054 do { 055 Method[] methods = type.getDeclaredMethods(); 056 for (Method method : methods) { 057 if (hasAnnotation(method, annotationType, checkMetaAnnotations)) { 058 answer.add(method); 059 } 060 } 061 type = type.getSuperclass(); 062 } while (type != null); 063 return answer; 064 } 065 066 /** 067 * Checks if a Class or Method are annotated with the given annotation 068 * 069 * @param elem the Class or Method to reflect on 070 * @param annotationType the annotation type 071 * @param checkMetaAnnotations check for meta annotations 072 * @return true if annotations is present 073 */ 074 public static boolean hasAnnotation( 075 AnnotatedElement elem, Class<? extends Annotation> annotationType, 076 boolean checkMetaAnnotations) { 077 if (elem.isAnnotationPresent(annotationType)) { 078 return true; 079 } 080 if (checkMetaAnnotations) { 081 for (Annotation a : elem.getAnnotations()) { 082 for (Annotation meta : a.annotationType().getAnnotations()) { 083 // NOTE: we perform an equality check as, by design, this has 084 // to be also supported in OSGI environments, therefore, instance equality may differ. 085 if (meta.annotationType().getName().equals(annotationType.getName())) { // NOSONAR 086 return true; 087 } 088 } 089 } 090 } 091 return false; 092 } 093 094 /** 095 * Checks if the class has been annotated with the given annotation (FQN class name) and if present, then returns 096 * the value attribute. 097 * 098 * @param clazz the class 099 * @param fqnAnnotationName the FQN of the annotation 100 * @return null if not annotated, otherwise the value, an empty string means annotation but has no 101 * value 102 */ 103 public static String getAnnotationValue(Class<?> clazz, String fqnAnnotationName) { 104 for (Annotation ann : clazz.getAnnotations()) { 105 if (ann.annotationType().getName().equals(fqnAnnotationName)) { 106 String s = ann.toString(); 107 return StringHelper.between(s, "\"", "\""); 108 } 109 } 110 return null; 111 } 112 113 /** 114 * Checks if the class has been annotated with the given annotation (FQN class name). 115 * 116 * @param clazz the class 117 * @param fqnAnnotationName the FQN of the annotation 118 * @return true if annotated or false if not 119 */ 120 public static boolean hasAnnotation(Class<?> clazz, String fqnAnnotationName) { 121 for (Annotation ann : clazz.getAnnotations()) { 122 if (ann.annotationType().getName().equals(fqnAnnotationName)) { 123 return true; 124 } 125 } 126 return false; 127 } 128 129 /** 130 * Checks if the method has been annotated with the given annotation (FQN class name). 131 * 132 * @param method the method 133 * @param fqnAnnotationName the FQN of the annotation 134 * @return true if annotated or false if not 135 */ 136 public static boolean hasAnnotation(Method method, String fqnAnnotationName) { 137 for (Annotation ann : method.getAnnotations()) { 138 if (ann.annotationType().getName().equals(fqnAnnotationName)) { 139 return true; 140 } 141 } 142 return false; 143 } 144 145 /** 146 * Checks if the method has been annotated with the given annotation (FQN class name) and if present, then returns 147 * the value attribute. 148 * 149 * @param method the method 150 * @param fqnAnnotationName the FQN of the annotation 151 * @return null if not annotated, otherwise the value, an empty string means annotation but has no 152 * value 153 */ 154 public static String getAnnotationValue(Method method, String fqnAnnotationName) { 155 return (String) getAnnotationValue(method, fqnAnnotationName, "value"); 156 } 157 158 /** 159 * Checks if the method has been annotated with the given annotation (FQN class name) and if present, then returns 160 * the value attribute. 161 * 162 * @param method the field 163 * @param key the annotation key 164 * @param fqnAnnotationName the FQN of the annotation 165 * @return null if not annotated, otherwise the value, an empty string means annotation but has no 166 * value 167 */ 168 public static Object getAnnotationValue(Method method, String fqnAnnotationName, String key) { 169 for (Annotation ann : method.getAnnotations()) { 170 if (ann.annotationType().getName().equals(fqnAnnotationName)) { 171 try { 172 Method m = ann.getClass().getDeclaredMethod(key); 173 return m.invoke(ann); 174 } catch (Exception e) { 175 return null; 176 } 177 } 178 } 179 return null; 180 } 181 182 /** 183 * Checks if the field has been annotated with the given annotation (FQN class name). 184 * 185 * @param field the field 186 * @param fqnAnnotationName the FQN of the annotation 187 * @return true if annotated or false if not 188 */ 189 public static boolean hasAnnotation(Field field, String fqnAnnotationName) { 190 for (Annotation ann : field.getAnnotations()) { 191 if (ann.annotationType().getName().equals(fqnAnnotationName)) { 192 return true; 193 } 194 } 195 return false; 196 } 197 198 /** 199 * Checks if the field has been annotated with the given annotation (FQN class name) and if present, then returns 200 * the value attribute. 201 * 202 * @param field the field 203 * @param fqnAnnotationName the FQN of the annotation 204 * @return null if not annotated, otherwise the value, an empty string means annotation but has no 205 * value 206 */ 207 public static String getAnnotationValue(Field field, String fqnAnnotationName) { 208 return (String) getAnnotationValue(field, fqnAnnotationName, "value"); 209 } 210 211 /** 212 * Checks if the field has been annotated with the given annotation (FQN class name) and if present, then returns 213 * the value attribute. 214 * 215 * @param field the field 216 * @param key the annotation key 217 * @param fqnAnnotationName the FQN of the annotation 218 * @return null if not annotated, otherwise the value, an empty string means annotation but has no 219 * value 220 */ 221 public static Object getAnnotationValue(Field field, String fqnAnnotationName, String key) { 222 for (Annotation ann : field.getAnnotations()) { 223 if (ann.annotationType().getName().equals(fqnAnnotationName)) { 224 try { 225 Method m = ann.getClass().getDeclaredMethod(key); 226 return m.invoke(ann); 227 } catch (Exception e) { 228 return null; 229 } 230 } 231 } 232 return null; 233 } 234 235}