Reputation: 1316
I have annotation processor. I retrieve the list of variables of the class that was annotated with my annotation this way:
@Override
public boolean process(Set<? extends TypeElement> annotations, RoundEnvironment roundEnv) {
for (TypeElement annotation : annotations) {
Set<? extends Element> annotatedElements = roundEnv.getElementsAnnotatedWith(annotation);
for (Element el : annotatedElements) {
try {
generate(el);
} catch (IOException e) {
e.printStackTrace();
}
}
}
return true;
}
private void generate(Element annotatedElement) throws IOException {
TypeElement targetClass = (TypeElement) annotatedElement;
List<? extends Element> enclosedElements = targetClass.getEnclosedElements();
List<VariableElement> fields = new ArrayList<>(enclosedElements.size());
for (Element field : enclosedElements) {
if (field.getKind() == ElementKind.FIELD && !field.getModifiers().contains(Modifier.STATIC)) {
fields.add((VariableElement) field);
}
}
processFields(fields);
}
Now fields
List contains list of all variables. But i need to extract the TYPE of variables, so for example if class has
private String blabla
i want to getString
I am doing it following way:
void processFields(List<VariableElement> elements){
List<String> types =elements
.stream()
.map( e -> e.asType().toString())
.collect(Collectors.toList());
}
List types
now contains all types of variables. However, if i have class like this
@MyAnnotation
public class Test{
@NotBlank(message = "message")
private String name;
}
The type of the variable name
is not string, its
(@javax.validation.constraints.NotBlank(message="message") :: java.lang.String
How can i get just type without annotations then? Is there any way?
Thanks for help!
Upvotes: 1
Views: 911
Reputation: 2026
Add members and override init()
to get the instances of
Elements
and
Types.
...
import javax.lang.model.util.Elements;
import javax.lang.model.util.Types;
...
/** See {@link javax.annotation.processing.ProcessingEnvironment#getElementUtils()}. */
protected Elements elements = null;
/** See {@link javax.annotation.processing.ProcessingEnvironment#getTypeUtils()}. */
protected Types types = null;
...
@Override
public void init(ProcessingEnvironment processingEnv) {
elements = processingEnv.getElementUtils();
types = processingEnv.getTypeUtils();
}
...
FYI, you can simplify your generate(Element)
method:
...
import javax.lang.model.util.ElementFilter;
...
private void generate(Element annotatedElement) throws IOException {
List<VariableElement> fields =
ElementFilter.fieldsIn(Collections.singleton(annotatedElement)).stream()
.filter(t -> (! t.getModifiers().contains(Modifier.STATIC)))
.collect(Collectors.toList());
processFields(fields);
}
Your processFields(List<VariableElement>)
method could look something
like below. I made all the steps explicit but you can look at
TypeElement
and
Name
methods to determine which String you want.
void processFields(List<VariableElement> in) {
List<String> out =
in.stream()
.map(e -> e.asType()) /* javax.lang.model.type.TypeMirror */
.map(e -> types.asElement(e)) /* javax.lang.model.element.Element */
.map(e -> (TypeElement) e) /* javax.lang.model.element.TypeElement */
.map(e -> e.getQualifiedName()) /* javax.lang.model.element.Name */
.map(e -> e.toString())
.collect(Collectors.toList());
}
Upvotes: 2