com.alibaba.spring.util.AnnotationUtils Maven / Gradle / Ivy
package com.alibaba.spring.util;
import org.springframework.core.env.Environment;
import org.springframework.core.env.PropertyResolver;
import java.lang.annotation.Annotation;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
import java.lang.reflect.Method;
import java.util.Collections;
import java.util.HashSet;
import java.util.LinkedHashMap;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
import java.util.Set;
import static java.lang.String.valueOf;
import static org.springframework.core.annotation.AnnotationUtils.findAnnotation;
import static org.springframework.core.annotation.AnnotationUtils.getAnnotationAttributes;
import static org.springframework.core.annotation.AnnotationUtils.getDefaultValue;
import static org.springframework.util.CollectionUtils.arrayToList;
import static org.springframework.util.ObjectUtils.nullSafeEquals;
import static org.springframework.util.StringUtils.trimWhitespace;
/**
* {@link Annotation} Utilities
*
* @author Mercy
* @see Annotation
* @since 2017.01.13
*/
public abstract class AnnotationUtils {
/**
* Is specified {@link Annotation} present on {@link Method}'s declaring class or parameters or itself.
*
* @param method {@link Method}
* @param annotationClass {@link Annotation} type
* @param {@link Annotation} type
* @return If present , return true
, or false
*/
public static boolean isPresent(Method method, Class annotationClass) {
Map> annotationsMap = findAnnotations(method, annotationClass);
return !annotationsMap.isEmpty();
}
/**
* Find specified {@link Annotation} type maps from {@link Method}
*
* @param method {@link Method}
* @param annotationClass {@link Annotation} type
* @param {@link Annotation} type
* @return {@link Annotation} type maps , the {@link ElementType} as key ,
* the list of {@link Annotation} as value.
* If {@link Annotation} was annotated on {@link Method}'s parameters{@link ElementType#PARAMETER} ,
* the associated {@link Annotation} list may contain multiple elements.
*/
public static Map> findAnnotations(Method method,
Class annotationClass) {
Retention retention = annotationClass.getAnnotation(Retention.class);
RetentionPolicy retentionPolicy = retention.value();
if (!RetentionPolicy.RUNTIME.equals(retentionPolicy)) {
return Collections.emptyMap();
}
Map> annotationsMap = new LinkedHashMap>();
Target target = annotationClass.getAnnotation(Target.class);
ElementType[] elementTypes = target.value();
for (ElementType elementType : elementTypes) {
List annotationsList = new LinkedList();
switch (elementType) {
case PARAMETER:
Annotation[][] parameterAnnotations = method.getParameterAnnotations();
for (Annotation[] annotations : parameterAnnotations) {
for (Annotation annotation : annotations) {
if (annotationClass.equals(annotation.annotationType())) {
annotationsList.add((A) annotation);
}
}
}
break;
case METHOD:
A annotation = findAnnotation(method, annotationClass);
if (annotation != null) {
annotationsList.add(annotation);
}
break;
case TYPE:
Class> beanType = method.getDeclaringClass();
A annotation2 = findAnnotation(beanType, annotationClass);
if (annotation2 != null) {
annotationsList.add(annotation2);
}
break;
}
if (!annotationsList.isEmpty()) {
annotationsMap.put(elementType, annotationsList);
}
}
return Collections.unmodifiableMap(annotationsMap);
}
/**
* Get the {@link Annotation} attributes
*
* @param annotation specified {@link Annotation}
* @param ignoreDefaultValue whether ignore default value or not
* @param ignoreAttributeNames the attribute names of annotation should be ignored
* @return non-null
* @since 1.0.2
*/
public static Map getAttributes(Annotation annotation, boolean ignoreDefaultValue,
String... ignoreAttributeNames) {
return getAttributes(annotation, null, ignoreDefaultValue, ignoreAttributeNames);
}
/**
* Get the {@link Annotation} attributes
*
* @param annotation specified {@link Annotation}
* @param propertyResolver {@link PropertyResolver} instance, e.g {@link Environment}
* @param ignoreDefaultValue whether ignore default value or not
* @param ignoreAttributeNames the attribute names of annotation should be ignored
* @return non-null
* @since 1.0.2
*/
public static Map getAttributes(Annotation annotation, PropertyResolver propertyResolver,
boolean ignoreDefaultValue, String... ignoreAttributeNames) {
Set ignoreAttributeNamesSet = new HashSet(arrayToList(ignoreAttributeNames));
Map attributes = getAnnotationAttributes(annotation);
Map actualAttributes = new LinkedHashMap();
for (Map.Entry entry : attributes.entrySet()) {
String attributeName = entry.getKey();
Object attributeValue = entry.getValue();
// ignore default attribute value
if (ignoreDefaultValue && nullSafeEquals(attributeValue, getDefaultValue(annotation, attributeName))) {
continue;
}
// ignore attribute name
if (ignoreAttributeNamesSet.contains(attributeName)) {
continue;
}
if (attributeValue instanceof String) {
attributeValue = resolvePlaceholders(valueOf(attributeValue), propertyResolver);
} else if (attributeValue instanceof String[]) {
String[] values = (String[]) attributeValue;
for (int i = 0; i < values.length; i++) {
values[i] = resolvePlaceholders(values[i], propertyResolver);
}
attributeValue = values;
}
actualAttributes.put(attributeName, attributeValue);
}
return actualAttributes;
}
private static String resolvePlaceholders(String attributeValue, PropertyResolver propertyResolver) {
String resolvedValue = attributeValue;
if (propertyResolver != null) {
resolvedValue = propertyResolver.resolvePlaceholders(resolvedValue);
resolvedValue = trimWhitespace(resolvedValue);
}
return resolvedValue;
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy