I would like to transform java source code at compile time just before passing the source code to the compiler. In other word I would like
Perhaps reconsider Spoon? It is intuitive once you know what an abstract syntax tree is. You basically navigate, filter and replace nodes on the AST representing your code until you have your desired transformation.
If we have the following class:
public class Test {
Object method(){
return "bla bla bla";
}
}
a possible Spoon solution to your example would be:
Launcher spoon = new Launcher();
spoon.addInputResource("./src/main/java/Test.java");
spoon.buildModel();
CtClass ctClass = spoon.getModel().getRootPackage().getType("Test");
CtLiteral match = ctClass.filterChildren((CtLiteral l) -> l.getType().getSimpleName().equals("String") && l.getValue().equals("bla bla bla")).first();
Factory factory = spoon.getFactory();
match.replace(factory.createCodeSnippetExpression("new MyClass(\"bla\", 3)"));
System.out.println(ctClass);
The first four lines build the Spoon model of the input program and retrieve the class element of interest.
Next the literal to be modified is retrieved with a filter that returns the first and only literal of type name "String"
and value "bla bla bla"
.
Last the matched literal is replaced in the AST to the desired code snippet. The code snippet is automatically parsed from a string to a Spoon model using the code construction class Factory
.
When the class model is printed, the desired transformation is given:
public class Test {
java.lang.Object method() {
return new MyClass("bla", 3);
}
}
There is someone who already wrote a small C-like preprocessor ant plugin in python/jython. You can find it here. Note that I have never used it, but perhaps it can be a good starting point for your needs.
There is also a java-comment-preprocessor maven plugin (similar style) in google code that might also be a helpful starting point.
Good luck. Sounds like a fun challenge. Of course, keep in mind that obfuscation is just making it a little more challenging to extract the string, but still not impossible. If you really want to make it significantly more difficult, then you might want to look at encrypting your strings and/or using AOP.
I think you could try the same technique used in Project Lombok
It's approximately explained by the authors in this interview:
What's going on under the hood? I.e., how does an annotation result in the boilerplate ending up in the bytecode?
Reinier: The annotation processor API only lets you create new files, it does not let you modify the file that has the annotation inside of it. Which is what Lombok does, so Lombok does not use the annotation processor API.
Instead, Lombok uses the annotation processor API only as a mechanism to inject itself into the compilation process. All annotation processors are initialized early in the compilation process, and Lombok modifies javac when it is initialized as an annotation processor. We change only one thing: The AST (the raw source code, parsed into a tree form) is first handed off to Lombok, which generates whatever needs to be generated, before javac continues.
and in How does lombok work?
It's also possible to extend Project Lombok to your needs
If the C preprocessor would suffice, I did just manage to get it working with Eclipse in Windows. It only works on Juno though.
https://stackoverflow.com/a/10497206/1137626