У меня была проблема, когда мне нужно было получить доступ к некоторому исходному коду (коду инициализатора для не-String / не примитивной константы), и я получил ее, получив доступ к исходному коду через API дерева компиляторов .
Вот общий рецепт:
1. Создайте собственный TreePathScanner:
private static class CodeAnalyzerTreeScanner extends TreePathScanner<Object, Trees> {
private String fieldName;
private String fieldInitializer;
public void setFieldName(String fieldName) {
this.fieldName = fieldName;
}
public String getFieldInitializer() {
return this.fieldInitializer;
}
@Override
public Object visitVariable(VariableTree variableTree, Trees trees) {
if (variableTree.getName().toString().equals(this.fieldName)) {
this.fieldInitializer = variableTree.getInitializer().toString();
}
return super.visitVariable(variableTree, trees);
}
2. В вашем AbstractProcessor сохраните ссылку на текущее дерево компиляции, переопределив метод init:
@Override
public void init(ProcessingEnvironment pe) {
super.init(pe);
this.trees = Trees.instance(pe);
}
3. Получите исходный код инициализации для VariableElement (в вашем случае перечисление):
// assuming theClass is a javax.lang.model.element.Element reference
// assuming theField is a javax.lang.model.element.VariableElement reference
String fieldName = theField.getSimpleName().toString();
CodeAnalyzerTreeScanner codeScanner = new CodeAnalyzerTreeScanner();
TreePath tp = this.trees.getPath(theClass);
codeScanner.setFieldName(fieldName);
codeScanner.scan(tp, this.trees);
String fieldInitializer = codeScanner.getFieldInitializer();
И это все! В конце переменная fieldInitiliazer будет содержать точную строку (и) кода, используемого для инициализации моей константы. С некоторыми изменениями вы сможете использовать тот же рецепт для доступа к исходному коду других типов элементов в исходном дереве (т. Е. Методы, объявления пакетов и т. Д.)
Дополнительную информацию и примеры читайте в этой статье : Анализ исходного кода с использованием API Java 6 .