org.mapstruct.ap.internal.util.MetaAnnotations Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of mapstruct-processor Show documentation
Show all versions of mapstruct-processor Show documentation
An annotation processor for generating type-safe bean mappers
/*
* Copyright MapStruct Authors.
*
* Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0
*/
package org.mapstruct.ap.internal.util;
import java.util.HashSet;
import java.util.LinkedHashSet;
import java.util.Set;
import javax.lang.model.element.AnnotationMirror;
import javax.lang.model.element.Element;
import javax.lang.model.element.ElementKind;
import javax.lang.model.element.TypeElement;
import org.mapstruct.tools.gem.Gem;
/**
* @author Filip Hrisafov
*/
public abstract class MetaAnnotations {
private static final String JAVA_LANG_ANNOTATION_PGK = "java.lang.annotation";
private final ElementUtils elementUtils;
private final String annotationFqn;
protected MetaAnnotations(ElementUtils elementUtils, String annotationFqn) {
this.elementUtils = elementUtils;
this.annotationFqn = annotationFqn;
}
/**
* Retrieves the processed annotations.
*
* @param source The source element of interest
* @return The processed annotations for the given element
*/
public Set getProcessedAnnotations(Element source) {
return getValues( source, source, new LinkedHashSet<>(), new HashSet<>() );
}
protected abstract G instanceOn(Element element);
protected abstract void addInstance(G gem, Element source, Set values);
/**
* Retrieves the processed annotations.
*
* @param source The source element of interest
* @param element Element of interest: method, or (meta) annotation
* @param values the set of values found so far
* @param handledElements The collection of already handled elements to handle recursion correctly.
* @return The processed annotations for the given element
*/
private Set getValues(Element source, Element element, Set values, Set handledElements) {
for ( AnnotationMirror annotationMirror : element.getAnnotationMirrors() ) {
Element annotationElement = annotationMirror.getAnnotationType().asElement();
if ( isAnnotation( annotationElement, annotationFqn ) ) {
G gem = instanceOn( element );
addInstance( gem, source, values );
}
else if ( isNotJavaAnnotation( element ) && !handledElements.contains( annotationElement ) ) {
handledElements.add( annotationElement );
getValues( source, annotationElement, values, handledElements );
}
}
return values;
}
private boolean isNotJavaAnnotation(Element element) {
if ( ElementKind.ANNOTATION_TYPE == element.getKind() ) {
return !elementUtils.getPackageOf( element ).getQualifiedName().contentEquals( JAVA_LANG_ANNOTATION_PGK );
}
return true;
}
private boolean isAnnotation(Element element, String annotationFqn) {
if ( ElementKind.ANNOTATION_TYPE == element.getKind() ) {
return ( (TypeElement) element ).getQualifiedName().contentEquals( annotationFqn );
}
return false;
}
}