fix #123 allow to specify extra annotations on repositories/methods
[yosql.git] / yosql-models / yosql-models-configuration / src / main / java / wtf / metio / yosql / models / configuration / Annotation.java
blob0a90802d370566cc3850f5d54c71361154f5470c
1 /*
2 * This file is part of yosql. It is subject to the license terms in the LICENSE file found in the top-level
3 * directory of this distribution and at https://creativecommons.org/publicdomain/zero/1.0/. No part of yosql,
4 * including this file, may be copied, modified, propagated, or distributed except according to the terms contained
5 * in the LICENSE file.
6 */
7 package wtf.metio.yosql.models.configuration;
9 import com.fasterxml.jackson.databind.annotation.JsonDeserialize;
10 import com.fasterxml.jackson.databind.annotation.JsonSerialize;
11 import org.immutables.value.Value;
12 import wtf.metio.yosql.internals.jdk.Buckets;
14 import java.util.List;
15 import java.util.stream.Collectors;
16 import java.util.stream.Stream;
18 /**
19 * Configuration for an extra annotation that is to be placed on a constructor or method in generated code.
21 @Value.Immutable
22 @JsonSerialize(
23 as = ImmutableAnnotation.class
25 @JsonDeserialize(
26 as = ImmutableAnnotation.class
28 public interface Annotation {
30 //region builders
32 static ImmutableAnnotation.TypeBuildStage builder() {
33 return ImmutableAnnotation.builder();
36 static ImmutableAnnotation copyOf(final Annotation annotation) {
37 return ImmutableAnnotation.copyOf(annotation);
40 //endregion
42 //region utils
44 static List<Annotation> mergeAnnotations(
45 final List<Annotation> first,
46 final List<Annotation> second) {
47 if (first == null || first.isEmpty()) {
48 return second;
50 return Stream.concat(copyAttributes(first, second), copyAttributes(second, first))
51 .filter(Buckets.distinctByKey(Annotation::type))
52 .collect(Collectors.toList());
55 private static Stream<ImmutableAnnotation> copyAttributes(
56 final List<Annotation> first,
57 final List<Annotation> second) {
58 return first.stream()
59 .map(annotation -> second.stream()
60 .filter(other -> annotation.type().equals(other.type()))
61 .findFirst()
62 .map(other -> Annotation.copyOf(annotation)
63 .withMembers(mergeMembers(annotation.members(), other.members())))
64 .orElseGet(() -> Annotation.copyOf(annotation)));
67 private static List<AnnotationMember> mergeMembers(
68 final List<AnnotationMember> first,
69 final List<AnnotationMember> second) {
70 if (first == null || first.isEmpty()) {
71 return second;
73 return Stream.concat(first.stream(), second.stream())
74 .filter(Buckets.distinctByKey(AnnotationMember::key))
75 .collect(Collectors.toList());
78 //endregion
80 /**
81 * @return The fully-qualified type name of this annotation.
83 String type();
85 /**
86 * @return The members of this annotation.
88 List<AnnotationMember> members();