How to disable #Generated annotation in Immutable generated class? - java

I am using Immutables-value for defining my POJO. And when it generates the Immutable* class, it has the #Generated annotation at the top. Is there any way I could disable it?
I checked in their codebase:
https://github.com/immutables/immutables/blob/master/value-annotations/src/org/immutables/value/Generated.java#L22-L27
It is mentioned here that it can be disabled by :
Style#allowedClasspathAnnotations()
I used it on top of POJO interface like this:
#Value.Style(allowedClasspathAnnotations = {org.immutables.value.Generated.class})
But still I am getting the #Generated annotation on top of my generated class. Any idea how can I do this?

#Style's allowedClasspathAnnotations attribute whitelists the annotations you included there (Rather than blacklisting them). See here.
So if you want to only disable org.immutables.value.Generated you should instead do something like:
#Value.Style(allowedClasspathAnnotations = {
javax.annotation.concurrent.Immutable,
javax.annotation.ParametersAreNonnullByDefault,
javax.annotation.CheckReturnValue,
edu.umd.cs.findbugs.annotations.SuppressFBWarnings,
com.google.errorprone.annotations.Var,
com.google.errorprone.annotations.Immutable
})
To whitelist the annotations you want to keep.

Related

Swagger - misleading sample value for date-time field, how can I fix this?

In Swagger model / Example value, I see this sample value for a $date-time field.
"lastModifiedDate": "2020-07-09T12:50:48.461Z"
But I have defined this field like this
#JsonFormat(pattern = "yyyy-MM-dd'T'HH:mm:ss.SSSXXX", timezone="America/New_York")
private Date lastModifiedDate;
So the actual values returned by my API look like this:
"lastModifiedDate": "2020-07-09T07:44:35.366-04:00"
So I am not sure why swagger is not detecting this.
Probably because this JsonFormat is a Jackson annotation.
com.fasterxml.jackson.annotation.JsonFormat
So... do I need to add some additional Swagger annotation here?
I don't have a Swagger descriptor file (or don't have control over it),
I have just annotations in the Java code.
Can this be done via annotations?
I think that the annotation required for documenting your moddel is #ApiModelProperty, take a look on it http://docs.swagger.io/swagger-core/current/apidocs/io/swagger/annotations/ApiModel.html
hope it will be helpfull.

Spring validation: method parameter constraint not called

everyone.
So, I have a SpringBoot application with a controller that has several methods, taking the following POJO as a parameter:
package com.example.dto;
import lombok.Data;
#Data
public class MyEntity {
#NotNull
private String fieldA;
private String fieldB;
}
For one of the controller endpoints I would like to apply additional validation logic, so in the validation.xml I add the following:
<constraint-mappings>
<bean class="com.example.controller.SampleController" ignore-annotations="false">
<method name="doFoo">
<parameter type="com.example.dto.MyEntity">
<valid />
<constraint annotation="com.example.validation.ValidEntity" />
</parameter>
</method>
</bean>
</constraint-mappings>
com.example.validation.ValidEntity is the constraint annotation I would like to apply.
My problem is that this additional constraint is only invoked if #NotNull checks defined in MyEntity have passed successfully. If fieldA is null, ValidEntity constraint is ignored, and the client receives an imcomplete validation result. What am I missing?
I'm not entirely sure about this because I've never worked with the validation.xml file.
However, I would say that Spring is first creating the object and then applying the validations. The #NotNull validation is performed in the creation of the instance. This means that if that validation fails the construction will throw an exception and Spring won't even try to check your constraint (which makes sense in my opinion).
I think you can "fix" it by creating an annotation with your constraint and using it in your class. If I'm right, both annotations will be checked and the thrown exception will contain all errors.
It's just a guess. Let me know if it works.
I don't know if there is an easy way to configure the validator to aggregate constraint violations from both annotation and XML configurations when first or both fails.
As demonstrated by your code Hibernate Validator can work with mixed annotation and XML configurations, but the lack of documentation for that specific case is a hint that it is at least not recommended.
When XML configuration file is used, it takes precedence over annotations by default. ignore-annotations is used to overcome this (text highlight is mine):
Setting ignore-annotations to true means that constraint
annotations placed on the configured bean are ignored. The default for
this value is true. ignore-annotations is also available for the nodes
class, fields, getter, constructor, method, parameter, cross-parameter
and return-value. If not explicitly specified on these levels the
configured bean value applies.
Using Hibernate Validator to Cover Your Validation Needs article states that:
The default for a field is ignore-annotations=”false”. This means
that by default annotations for a field are stronger (this is of
course after you indicated that that the bean itself wont ignore
annotations). If you wont that the XML will be stronger than you have
to indicate that by ignore-annotations=”true”
It seems possible to disable annotation configuration for a specific field which is configured in XML.
Another solution to switch between annotation and XML configuration is to use Grouping constraints.
I'm not sure if anything of the above is of any use for you, but if it is possible I would probably switch to a single configuration (XML, assuming that annotation config comes from external library you cannot modify) and enforce it everywhere instead of relying on undocumented features.

How to negate #JsonView?

The following will include only fields that have the JsonView(View.MyView.class) annotation:
#JsonView(View.MyView.class)
#RequestMapping(value = "offer", method=RequestMethod.POST)
public ResponseEntity<MyResponse> offer(...) {}
Question: how can I negate it? Means: include any field except the ones having JsonView(View.MyView.class)? Especially without having to add another annotation on any of the remaining fields?
It's not possible. But by adding the following property, any fields not having a #JsonVniew annotation will be serialized:
spring.jackson.mapper.default-view-inclusion=true
As a result, only a #RequestMapping #JsonView will output only non-annotated fields plus the ones matching the view.
So if I want to exclude only some fields inside a specific view, I just have to give the to be excluded fields a different view that is not used in the #RequestMapping. Then they are ignored automatically.

How can I use my own annotation for Swagger?

How can I use my own annotation for building swagger ui page.
For example I defined annotation and use it:
#PUT
#MyOwnAnnotationForAdditionalPropInSwagger(value = "Some text")
#Path( "/{carId}" )
#Consumes(MediaType.APPLICATION_JSON)
#Produces(MediaType.APPLICATION_JSON)
#ApiOperation(
value = "Updates car info"
)
public Response patchItem(#ApiParam(value = "Fields to update") Car item) {
/*some code*/
}
After that probably I should extend some class from swagger-core and specify to scan my annotation (#MyOwnAnnotationForAdditionalPropInSwagger).
As result I want to see additional column in swagger ui with my text.
How I can realize it? What class I need to extend?
The swagger 2.0 supports custom fields, there was a Pull Request for this back in 2013 (https://github.com/swagger-api/swagger-node/pull/47).
While apparently it's easy to add the custom fields, since they are not present in the Swagger 2.0 spec, Swagger-UI won't display them by default.
For this to work you will have to change a couple of things.
Implement the desired annotation in your parser implementation (ie. swagger-core or swagger-php) if it doesn't exist.
Clone and modify swagger-ui to display your custom field as you wish.
Note that by doing this you will in fact violate the swagger json schema (https://github.com/swagger-api/swagger-spec/blob/master/schemas/v2.0/schema.json) and any third party validators you may use will fail.
I believe what you are trying to do ca be achieved extending the swagger core reader as described in swagger documentation. Here is an example in one of my projects.

Set annotation meta properties programmatically

Is it possible to set properties of annotation programmatically. So if I have :
#interface Author(
String name();
Date date ();
)
I want to be able to set the name property inside the code as if it is a regular class. Is this possible?
You can't use Date in an annotation
To access it at runtime, you need to add the #Retention(RetentionPolicy.RUNTIME) retention policy
The declaration for annotations uses {} for the annotation definition, not ()
No, you can't modify annotations during runtime using normal Java functionality
You may do this using a bytecode manipulator, like Javassist. But that is is not trivial.
Why do you want to do this during runtime? Possibly there are other better solutions to your problem.

Categories

Resources