mirror of https://github.com/apache/maven.git
Enhance DiIndexProcessor
Sort and *update* the file (in case of a partial build)
This commit is contained in:
parent
0c7e73335d
commit
bb99857f34
|
@ -29,67 +29,122 @@ import javax.tools.Diagnostic;
|
|||
import javax.tools.FileObject;
|
||||
import javax.tools.StandardLocation;
|
||||
|
||||
import java.io.BufferedReader;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStreamReader;
|
||||
import java.io.PrintWriter;
|
||||
import java.io.StringWriter;
|
||||
import java.io.Writer;
|
||||
import java.util.HashSet;
|
||||
import java.util.Set;
|
||||
import java.util.TreeSet;
|
||||
|
||||
import org.apache.maven.api.di.Named;
|
||||
|
||||
// Auto-register the annotation processor
|
||||
@SupportedAnnotationTypes("org.apache.maven.api.di.Named")
|
||||
@SupportedSourceVersion(SourceVersion.RELEASE_17)
|
||||
public class DiIndexProcessor extends AbstractProcessor {
|
||||
|
||||
private final Set<String> processedClasses = new HashSet<>();
|
||||
|
||||
@Override
|
||||
public boolean process(Set<? extends TypeElement> annotations, RoundEnvironment roundEnv) {
|
||||
// Collect the fully qualified names of classes annotated with @Named
|
||||
StringBuilder builder = new StringBuilder();
|
||||
|
||||
processingEnv
|
||||
.getMessager()
|
||||
.printMessage(
|
||||
Diagnostic.Kind.NOTE,
|
||||
"Processing " + roundEnv.getRootElements().size() + " classes");
|
||||
logMessage(
|
||||
Diagnostic.Kind.NOTE, "Processing " + roundEnv.getRootElements().size() + " classes");
|
||||
|
||||
for (Element element : roundEnv.getElementsAnnotatedWith(Named.class)) {
|
||||
if (element instanceof TypeElement typeElement) {
|
||||
// Get the fully qualified class name
|
||||
String className = typeElement.getQualifiedName().toString();
|
||||
String className = getFullClassName(typeElement);
|
||||
processedClasses.add(className);
|
||||
}
|
||||
}
|
||||
|
||||
// Handle inner classes by checking if the enclosing element is a class or interface
|
||||
if (roundEnv.processingOver()) {
|
||||
try {
|
||||
updateFileIfChanged();
|
||||
} catch (Exception e) {
|
||||
logError("Error updating file", e);
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
private String getFullClassName(TypeElement typeElement) {
|
||||
String className = typeElement.getQualifiedName().toString();
|
||||
Element enclosingElement = typeElement.getEnclosingElement();
|
||||
if (enclosingElement instanceof TypeElement) {
|
||||
// It's an inner class, replace the last dot with a '$'
|
||||
String enclosingClassName =
|
||||
((TypeElement) enclosingElement).getQualifiedName().toString();
|
||||
className = enclosingClassName + "$" + typeElement.getSimpleName();
|
||||
}
|
||||
|
||||
builder.append(className).append("\n");
|
||||
}
|
||||
return className;
|
||||
}
|
||||
|
||||
if (!builder.isEmpty()) { // Check if the StringBuilder is non-empty
|
||||
private void updateFileIfChanged() throws IOException {
|
||||
String path = "META-INF/maven/org.apache.maven.api.di.Inject";
|
||||
Set<String> existingClasses = new TreeSet<>(); // Using TreeSet for natural ordering
|
||||
String existingContent = "";
|
||||
|
||||
// Try to read existing content
|
||||
try {
|
||||
writeFile(builder.toString());
|
||||
FileObject inputFile = processingEnv.getFiler().getResource(StandardLocation.CLASS_OUTPUT, "", path);
|
||||
try (BufferedReader reader = new BufferedReader(new InputStreamReader(inputFile.openInputStream()))) {
|
||||
String line;
|
||||
StringBuilder contentBuilder = new StringBuilder();
|
||||
while ((line = reader.readLine()) != null) {
|
||||
if (!line.trim().startsWith("#")) {
|
||||
existingClasses.add(line.trim());
|
||||
}
|
||||
contentBuilder.append(line).append("\n");
|
||||
}
|
||||
existingContent = contentBuilder.toString();
|
||||
}
|
||||
} catch (IOException e) {
|
||||
processingEnv
|
||||
.getMessager()
|
||||
.printMessage(Diagnostic.Kind.ERROR, "Error writing file: " + e.getMessage());
|
||||
logMessage(Diagnostic.Kind.NOTE, "Unable to read existing file. Proceeding with empty content.");
|
||||
}
|
||||
|
||||
Set<String> allClasses = new TreeSet<>(existingClasses); // Using TreeSet for natural ordering
|
||||
allClasses.addAll(processedClasses);
|
||||
|
||||
StringBuilder newContentBuilder = new StringBuilder();
|
||||
for (String className : allClasses) {
|
||||
newContentBuilder.append(className).append("\n");
|
||||
}
|
||||
String newContent = newContentBuilder.toString();
|
||||
|
||||
if (!newContent.equals(existingContent)) {
|
||||
logMessage(Diagnostic.Kind.NOTE, "Content has changed. Updating file.");
|
||||
try {
|
||||
FileObject outputFile =
|
||||
processingEnv.getFiler().createResource(StandardLocation.CLASS_OUTPUT, "", path);
|
||||
try (Writer writer = outputFile.openWriter()) {
|
||||
writer.write(newContent);
|
||||
}
|
||||
} catch (IOException e) {
|
||||
logError("Failed to write to file", e);
|
||||
throw e; // Re-throw to ensure the compilation fails
|
||||
}
|
||||
} else {
|
||||
logMessage(Diagnostic.Kind.NOTE, "Content unchanged. Skipping file update.");
|
||||
}
|
||||
}
|
||||
|
||||
return true; // Indicate that annotations are claimed by this processor
|
||||
private void logMessage(Diagnostic.Kind kind, String message) {
|
||||
processingEnv.getMessager().printMessage(kind, message);
|
||||
}
|
||||
|
||||
private void writeFile(String content) throws IOException {
|
||||
// Create the file META-INF/maven/org.apache.maven.api.di.Inject
|
||||
FileObject fileObject = processingEnv
|
||||
.getFiler()
|
||||
.createResource(StandardLocation.CLASS_OUTPUT, "", "META-INF/maven/org.apache.maven.api.di.Inject");
|
||||
private void logError(String message, Exception e) {
|
||||
StringWriter sw = new StringWriter();
|
||||
PrintWriter pw = new PrintWriter(sw);
|
||||
e.printStackTrace(pw);
|
||||
String stackTrace = sw.toString();
|
||||
|
||||
try (Writer writer = fileObject.openWriter()) {
|
||||
writer.write(content);
|
||||
}
|
||||
String fullMessage = message + "\n" + "Exception: "
|
||||
+ e.getClass().getName() + "\n" + "Message: "
|
||||
+ e.getMessage() + "\n" + "Stack trace:\n"
|
||||
+ stackTrace;
|
||||
|
||||
processingEnv.getMessager().printMessage(Diagnostic.Kind.ERROR, fullMessage);
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue