JavaModelToString.java
/*
* SPDX-FileCopyrightText: 2025 kaumei.io
* SPDX-License-Identifier: Apache-2.0
*/
package io.kaumei.jdbc.anno.ctx;
import javax.lang.model.AnnotatedConstruct;
import javax.lang.model.element.ExecutableElement;
import javax.lang.model.element.RecordComponentElement;
import javax.lang.model.element.TypeElement;
import javax.lang.model.element.VariableElement;
import javax.lang.model.type.*;
import java.util.List;
public final class JavaModelToString {
private JavaModelToString() {
}
// ------------------------------------------------------------------------
public static String typeElement(TypeElement element) {
var sb = new StringBuilder();
typeElement(sb, element);
return sb.toString();
}
private static void typeElement(StringBuilder sb, TypeElement element) {
annotatedConstruct(sb, element);
if (!sb.isEmpty()) {
sb.append(' ');
}
sb.append(element.getQualifiedName());
}
// ------------------------------------------------------------------------
public static String recordComponentElement(RecordComponentElement element) {
var sb = new StringBuilder();
annotatedConstruct(sb, element);
if (!sb.isEmpty()) {
sb.append(' ');
}
sb.append(typeMirror(element.asType()));
sb.append(' ').append(element.getSimpleName());
return sb.toString();
}
// ------------------------------------------------------------------------
public static String variableElement(VariableElement element) {
var sb = new StringBuilder();
variableElement(sb, element);
return sb.toString();
}
private static void variableElement(StringBuilder sb, VariableElement element) {
annotatedConstruct(sb, element);
if (!sb.isEmpty()) {
sb.append(' ');
}
sb.append(typeMirror(element.asType()));
sb.append(' ').append(element.getSimpleName());
}
// ------------------------------------------------------------------------
public static String executableElement(ExecutableElement element) {
var sb = new StringBuilder();
executableElement(sb, element);
return sb.toString();
}
private static void executableElement(StringBuilder sb, ExecutableElement method) {
annotatedConstruct(sb, method);
if (!sb.isEmpty()) {
sb.append(' ');
}
for (var modifier : method.getModifiers()) {
sb.append(modifier).append(' ');
}
if (!method.getTypeParameters().isEmpty()) {
sb.append('<');
for (int i = 0; i < method.getTypeParameters().size(); i++) {
if (i > 0) {
sb.append(',');
}
sb.append(method.getTypeParameters().get(i));
}
sb.append("> ");
}
sb.append(typeMirror(method.getReturnType()));
sb.append(' ').append(method.getSimpleName()).append('(');
for (int i = 0; i < method.getParameters().size(); i++) {
if (i > 0) {
sb.append(',');
}
sb.append(variableElement(method.getParameters().get(i)));
}
sb.append(')');
}
private static void annotatedConstruct(StringBuilder sb, AnnotatedConstruct tm) {
boolean space = false;
for (var a : tm.getAnnotationMirrors()) {
if (space) {
sb.append(' ');
} else {
space = true;
}
sb.append(a);
}
}
// ------------------------------------------------------------------------
public static String typeMirror(TypeMirror tm) {
return tm.toString();
}
// ------------------------------------------------------------------------
public static String searchKey(TypeMirror tm) {
var sb = new StringBuilder();
searchKey(sb, tm);
return sb.toString();
}
private static void searchKey(StringBuilder sb, TypeMirror tm) {
switch (tm.getKind()) {
case DECLARED:
searchKeyDeclaredType(sb, (DeclaredType) tm);
break;
case TYPEVAR:
sb.append(((TypeVariable) tm).asElement().getSimpleName());
break;
case ARRAY:
searchKey(sb, ((ArrayType) tm).getComponentType());
sb.append("[]");
break;
case WILDCARD:
searchKeyWildcard(sb, (WildcardType) tm);
break;
default:
sb.append(tm.getKind().name().toLowerCase()); // primitives, void etc.
}
}
private static void searchKeyDeclaredType(StringBuilder sb, DeclaredType dt) {
TypeElement type = (TypeElement) dt.asElement();
sb.append(type.getQualifiedName());
List<? extends TypeMirror> args = dt.getTypeArguments();
if (!args.isEmpty()) {
sb.append('<');
for (int i = 0; i < args.size(); i++) {
if (i > 0) {
sb.append(",");
}
searchKey(sb, args.get(i));
}
sb.append('>');
}
}
private static void searchKeyWildcard(StringBuilder sb, WildcardType wt) {
if (wt.getExtendsBound() != null) {
sb.append("? extends ");
searchKey(sb, wt.getExtendsBound());
} else if (wt.getSuperBound() != null) {
sb.append("? super ");
searchKey(sb, wt.getSuperBound());
} else {
sb.append('?');
}
}
}