Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Combine multiple arbitrary annotations in one

In my code, I'm going to have lots of getters like this with the same set of annotations (one for Hibernate and others for Jackson):

@Transient
@JsonSerialize(using = LocalDateTimeSerializer.class)
@JsonDeserialize(using = LocalDateTimeDeserializer.class)
@JsonFormat(shape = JsonFormat.Shape.STRING, pattern = BaseEntity.JSON_DATETIME_FORMAT)
public LocalDateTime getCreatedDateDT() {
    return DateTimeUtils.klabTimestampToLocalDateTime(getCreatedDate(), createdDateDT);
}

I want to minimize repetion by implementing my own annotation, which will mean all these four together, like this:

@TransientLocalDateTime
public LocalDateTime getCreatedDateDT() {
    return DateTimeUtils.klabTimestampToLocalDateTime(getCreatedDate(), createdDateDT);
}

How can I do it? Is this even possible?

UPDATE Thanks to Konstantin Yovkov, now I know, that I can combine all Jackson annotations in one, but that is because Jackson's annotation processor recognizes such a trick. I wonder if it is possible to make any annotation processor do that? It seems to me that it's not.

like image 915
Mikhail Batcer Avatar asked Feb 05 '16 12:02

Mikhail Batcer


1 Answers

Jackson provides a meta-annotation (annotation used for annotating another annotation), called @JacksonAnnotationsInside, which is a:

Meta-annotation (annotations used on other annotations) used for indicating that instead of using target annotation (annotation annotated with this annotation), Jackson should use meta-annotations it has.

This can be useful in creating "combo-annotations" by having a container annotation, which needs to be annotated with this annotation as well as all annotations it 'contains'.

So, you should create an annotation like this one:

@Target(value = { ElementType.TYPE, ElementType.METHOD,
                  ElementType.PARAMETER, ElementType.FIELD })
@Retention(RetentionPolicy.RUNTIME)
@JacksonAnnotationsInside // <-- this one is mandatory
@Transient
@JsonSerialize(using = LocalDateTimeSerializer.class)
@JsonDeserialize(using = LocalDateTimeDeserializer.class)
@JsonFormat(shape = JsonFormat.Shape.STRING, pattern = BaseEntity.JSON_DATETIME_FORMAT)
public @interface TransientLocalDateTime {    
}

and use is like:

@TransientLocalDateTime
public LocalDateTime getCreatedDateDT() {
    return DateTimeUtils.klabTimestampToLocalDateTime(getCreatedDate(), createdDateDT);
}
like image 162
Konstantin Yovkov Avatar answered Oct 04 '22 05:10

Konstantin Yovkov