-
Notifications
You must be signed in to change notification settings - Fork 1.9k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Declarative contracts #1060
Declarative contracts #1060
Conversation
11c4402
to
bb9ab1f
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This class has become quite large. What are your thoughts on breaking out the Annotation Processors into their own classes and possibly their own package?
ow yes, as a mater of fact, annotation process will go to it's own module, since it will have dependencies to all contracts. |
abb6f7d
to
7a2ddff
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I have a couple questions regarding the set up. Can you help by providing some more background?
d09b9fe
to
2ea1698
Compare
2ea1698
to
bf50ce6
Compare
* {@link Contract} base implementation that works by declaring witch annotations should be | ||
* processed and how each annotation modifies {@link MethodMetadata} | ||
*/ | ||
public abstract class DeclarativeContract extends BaseContract { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
note to self:
Extract this class to a new source file before merging. Enough is enough =)
I'm still confused and I think your current approach relies on others having sufficient mental space to interpret what's going on. There are three areas where I'm still not able to fully understand:
This says to me that I want to skip processing but I'm doing my best to avoid a public void processAnnotationsOnClass(MethodMetadata data, Class<?> target) {
Arrays.stream(target.getAnnotations())
.forEach(annotation -> getProcessor(annotation)
.ifPresent(
annotationProcessor -> annotationProcessor.process(annotation, data)));
}
private Optional<AnnotationProcessor> getProcessor(Annotation annotation) {
return Optional.ofNullable(this.processors.get(annotation));
}
I'm still unclear on how this is intended to be used. If its to determine if the processor should be called, we should leave that decision up to processor implementations. Having the
I don't think ignoring is the right verb. I suspect what you are looking for is to identify which parameters are not annotated and how to deal with them. The current implementation relies on the result of protected void processAnnotationsOnParameter(MethodMetadata methodMetadata,
Parameter parameter, int index) {
Annotation[] annotations = parameter.getAnnotations();
if (annotations != null && annotations.length != 0) {
for (Annotation annotation : annotations) {
AnnotationProcessorContext context =
new AnnotationProcessorContext(methodMetadata, parameter, index);
this.getAnnotationProcessor(annotation)
.ifPresent(processor -> processor.process(annotation, context));
}
} else {
/* no annotations, special processing, like request options, etc... */
if (Request.Options.class.isAssignableFrom(parameter.getType())) {
/* process */
}
}
} I created a gist that demonstrates these thoughts and my approach. Now, I could be completely off here. If I am, please let me know. https://gist.github.com/kdavisk6/bb6db782c8fe5284ed0ea3ffb1a5d012 |
Ow, there is one left for
So, my goal for This translates into
This is used for JAXRS contract. On jaxrs you can inject things like the Now, if the contract didn't made any decision about a parameter, feign assumes that one is a BODY. That can either be due to no annotation or some annotation that contract don't care about.
|
Thanks for the explanation and now I understand your approach. I have some reservations about the ignoring approach, it still feels awkward, but it works and I don't want to hold this up any more. 👍 |
Ok, going to merge it as is. |
* Declarative contracts * Actually using the data structure to read declaritve contracts * Using declarative contract for jaxrs contracts * Make possible for contracts to declare parameters as ignored * Using predicate to decide if an AnnotationProcessor should be invoked * Restore environment variable for GITHUB_TOKEN
* Declarative contracts * Actually using the data structure to read declaritve contracts * Using declarative contract for jaxrs contracts * Make possible for contracts to declare parameters as ignored * Using predicate to decide if an AnnotationProcessor should be invoked * Restore environment variable for GITHUB_TOKEN
This is a preparation work for feign code generation that I'm working on this branch:
https://github.com/velo/feign/tree/apt-generator
With generated client, we will be able to generate clients that will work with graalVM and also don't have java 11 reflective warning. Fixing both:
#935
#944
The key work for the code generation is the new
DeclarativeContract
. Which would allow to reuse the annotation logic when generating client. So, same contract code used by feign reflectively would be used on APT code generation.The idea of this PR is to review the design of this new
DeclarativeContract