I just found out how to generate code using annotation processing
But as I understand these are just additional code files.
What i want to achieve is something like this (In a already existing file):
#basicMethod
public void executeStuff(String help, int me) {
mySystem.executor(help, me); // <- This should be generated by this annotation
}
Is there any way to achieve something like this?
Also, I am not sticking to Annotations. Any other way would also be helpful.
Related
I am trying to work with both swagger-codegen and springfox to gain time during webservice development.
I am facing an issue with an endpoint being created for my annotated interface classes as well as my controller implementations as you can see below:
I found a workaround by adding the tag where the controller should be (ex: #Api(tags={ "Player" })) in my controller but I am looking for a better one preventing this because if I am using code generation its to avoid this kind of situation where you have to add stuff in your code.
With swagger-codegen, I just have to write a RestController (PlayerApiImpl) like this:
#RestController
public class PlayerApiImpl implements PlayerApi {
#Override
public ResponseEntity<Player> playerIdGet(String id) {
PlayerDTO ret = service.getOne(Long.parseLong(id));
if (ret == null) {
throw new PlayerNotFoundException();
}
return ResponseEntity.ok(mapper.toModel(ret));
}
}
While everything is generated into an interface (here PlayerApi). So I would like to stay as simple as it is possible.
I decided to push my workaround a bit more and found this solution:
It's actualy possible de add the #Api annotation directly in the generated interface to prevent you to add it in your implementation. For that you need to work with mustache templates files that you can create in the directory where is located your swagger file.
It might not be the best solution, so if you have a better proposolal, feel free to comment.
I'm trying to add a hook after all the files are created by the Go client generator and I'm wondering where I can add this.
Right now, files are generated in this order (a) models (b) API paths (c) supporting files.
If I hook into AbstractGoCodegen's postProcessSupportingFileData function like so, myfunc() will get called before the supporting files like README.md and client.go are created, but I want the function be called afterwards.
#Override
public Map<String, Object> postProcessSupportingFileData(Map<String, Object> objs) {
generateYAMLSpecFile(objs);
objs = super.postProcessSupportingFileData(objs);
myfunc();
return objs;
}
I've also tried a few other other postProcessing* functions as shown in DefaultCodegen but they didn't work as desired.
How can I do this?
If you do not get the desired functionality from overriding the configuration methods, I suggest that you extend the DefaultGenerator class. These contain the actual generation methods such as generateSupportingFiles. You should be able to easily add your hook after this method has generated the supporting files.
Keep in mind that you might have to change a few modifiers from private to protected.
Our current path annotation omitted the 'v1' and we'd like to insert it. Since we cannot have more than one Path annotation, is there a way to add the v1 using a regular expression? I have seen this used for parameters, but not for constants in the endpoint.
So if my path annotation currently looks like this:
#Path("/rest/noun")
Can it be replaced with something like this?
#Path("/rest/noun|/rest/v1/noun")
Since some users are using the original path of /rest/noun, I want to offer the corrected one and the old one, not to break their current functionality. I want to offer both of these:
/rest/noun
/rest/v1/noun
If you want more than one path for same code of execution, you can create wrapper function calling the current function internally like below:
#Path("/rest/noun")
void currentfunction(){
//all functionality code here
}
#Path("/rest/v1/noun")
void newfunction(){
currentfunction();
}
Or you can also use:
#Path("/rest/{parameter: v1\\/noun|noun}")
void currentfunction(){
//all functionality code here
}
I am writing a java annotation processor for java 7 source code.
And surely, I can use javax.annotation.processing.filer to help me generate the file under project directory automatically.
ex: annotation is #becare
public interface test {
#becare
int compare(int a, int b);
}
my annotation processor's job is when it detects the given annotation #becare, it will generate the file for me.
My Question is that if I remove the annotation from the previous code snippet, can I let annotation processor to be aware that and delete the file it just created?
Or is there any workaround to help me achieve this ?
Thanks in advance.
When you create the generated file you declare that it's linked to your 'test' interface like this:
Elements eltUtils = processingEnv.getElementUtils();
filer.createSourceFile("testGenerated", eltUtils.getTypeElement("test"));
When the source is deleted, the processor will remove generated file like javadoc says:
If there are no originating elements, none need to be passed. This information may be used in an incremental environment to determine the need to rerun processors or remove generated files. Non-incremental environments may ignore the originating element information.
How do you check for Annotations when using IClassFile in Eclipse?
This doesnt seem to work classFile.getClass().isAnnotationPresent? Any help is appreciated.
The problem with using
for (final IClassFile classFile : classFiles) {
IAnnotation[] annotations = classFile.getType().getAnnotations();
Is that I have to get All the Packages, then get the Class Files in that package then get the Annotations. It will require 3 loops. Is there a way to minimize this?
I would say that the easiest way for you to find annotations is through a triple loop, but it might be slightly faster (assuming you are looking for a specific annotation) to use a 'SearchEngineinstead. Take a look at the source code for theorg.eclipse.jdt.internal.junit.launcher.JUnit4TestFinder` class. It looks for (source) classes annotated with #Test or #RunWith, which is similar to what you want to do, but for binary classes.
You would do something like this:
IJavaElement[] allPackagesToSearch = ...
SearchRequestor requestor = <implement the SearchRequestor abstract class and store all matches>
IJavaSearchScope scope= SearchEngine.createJavaSearchScope(binaryPackages, IJavaSearchScope.APPLICATION_LIBRARIES);
int matchRule= SearchPattern.R_EXACT_MATCH | SearchPattern.R_CASE_SENSITIVE;
SearchPattern runWithPattern= SearchPattern.createPattern("com.foo.MyAnnotation", IJavaSearchConstants.ANNOTATION_TYPE, IJavaSearchConstants.ANNOTATION_TYPE_REFERENCE, matchRule);
SearchParticipant[] searchParticipants= new SearchParticipant[] { SearchEngine.getDefaultSearchParticipant() };
new SearchEngine().search(annotationsPattern, searchParticipants, scope, requestor, new SubProgressMonitor(pm, 2));
It's a bit of a mouthful, and to figure out how this works, I'd recommend reading the JavaDoc for SearchEngine, SearchPattern, and SearchRequestor.
If you want to find all annotations, then change the match rule, and instead of "com.foo.MyAnnotation", use "*".