From f0e6294339904930fcc044f5ed0a7370d09c5f5a Mon Sep 17 00:00:00 2001 From: Uragami Taichi Date: Wed, 2 Jun 2021 23:07:17 +0900 Subject: [PATCH] Add support for handling multiple AnnotateWith (#697) --- .../doma/internal/apt/annot/Annotations.java | 57 ++++++++++------- .../apt/generator/DaoImplGenerator.java | 2 +- .../doma/internal/apt/meta/dao/DaoMeta.java | 21 +++---- .../internal/apt/meta/dao/DaoMetaFactory.java | 8 +-- .../apt/processor/dao/DaoProcessorTest.java | 3 +- .../dao/MultipleAnnotateWithDao.java | 28 +++++++++ .../dao/MultipleAnnotationConfig1.java | 24 +++++++ .../dao/MultipleAnnotationConfig2.java | 24 +++++++ ...oProcessorTest_MultipleAnnotateWithDao.txt | 62 +++++++++++++++++++ 9 files changed, 188 insertions(+), 41 deletions(-) create mode 100644 doma-processor/src/test/java/org/seasar/doma/internal/apt/processor/dao/MultipleAnnotateWithDao.java create mode 100644 doma-processor/src/test/java/org/seasar/doma/internal/apt/processor/dao/MultipleAnnotationConfig1.java create mode 100644 doma-processor/src/test/java/org/seasar/doma/internal/apt/processor/dao/MultipleAnnotationConfig2.java create mode 100644 doma-processor/src/test/resources/org/seasar/doma/internal/apt/processor/dao/DaoProcessorTest_MultipleAnnotateWithDao.txt diff --git a/doma-processor/src/main/java/org/seasar/doma/internal/apt/annot/Annotations.java b/doma-processor/src/main/java/org/seasar/doma/internal/apt/annot/Annotations.java index 25e6c8849..5f75b4ee6 100644 --- a/doma-processor/src/main/java/org/seasar/doma/internal/apt/annot/Annotations.java +++ b/doma-processor/src/main/java/org/seasar/doma/internal/apt/annot/Annotations.java @@ -3,9 +3,11 @@ import static org.seasar.doma.internal.util.AssertionUtil.assertNotNull; import java.util.ArrayList; +import java.util.List; import java.util.Map; import java.util.function.BiFunction; import java.util.function.Function; +import java.util.stream.Collectors; import javax.lang.model.element.AnnotationMirror; import javax.lang.model.element.AnnotationValue; import javax.lang.model.element.Element; @@ -57,33 +59,42 @@ public AllArgsConstructorAnnot newAllArgsConstructorAnnot(TypeElement typeElemen typeElement, ctx.getOptions().getLombokAllArgsConstructor(), AllArgsConstructorAnnot::new); } - public AnnotateWithAnnot newAnnotateWithAnnot(TypeElement typeElement) { + public List newAnnotateWithAnnots(TypeElement typeElement) { assertNotNull(typeElement); - AnnotationMirror annotateWith = - ctx.getMoreElements().getAnnotationMirror(typeElement, AnnotateWith.class); - if (annotateWith == null) { - for (AnnotationMirror annotationMirror : typeElement.getAnnotationMirrors()) { - TypeElement ownerElement = - ctx.getMoreElements().toTypeElement(annotationMirror.getAnnotationType().asElement()); - if (ownerElement == null) { - continue; - } - annotateWith = ctx.getMoreElements().getAnnotationMirror(ownerElement, AnnotateWith.class); - if (annotateWith != null) { - break; - } - } - if (annotateWith == null) { - return null; + List annotateWiths = new ArrayList<>(); + { + AnnotationMirror annotateWith = + ctx.getMoreElements().getAnnotationMirror(typeElement, AnnotateWith.class); + if (annotateWith != null) { + annotateWiths.add(annotateWith); } } - Map values = ctx.getMoreElements().getValuesWithDefaults(annotateWith); - AnnotationValue annotations = values.get(AnnotateWithAnnot.ANNOTATIONS); - ArrayList annotationsValue = new ArrayList<>(); - for (AnnotationMirror annotationMirror : AnnotationValueUtil.toAnnotationList(annotations)) { - annotationsValue.add(newAnnotationAnnot(annotationMirror)); + for (AnnotationMirror annotationMirror : typeElement.getAnnotationMirrors()) { + TypeElement ownerElement = + ctx.getMoreElements().toTypeElement(annotationMirror.getAnnotationType().asElement()); + if (ownerElement == null) { + continue; + } + AnnotationMirror annotateWith = + ctx.getMoreElements().getAnnotationMirror(ownerElement, AnnotateWith.class); + if (annotateWith != null) { + annotateWiths.add(annotateWith); + } } - return new AnnotateWithAnnot(annotateWith, annotations, annotationsValue); + return annotateWiths.stream() + .map( + annotateWith -> { + Map values = + ctx.getMoreElements().getValuesWithDefaults(annotateWith); + AnnotationValue annotations = values.get(AnnotateWithAnnot.ANNOTATIONS); + ArrayList annotationsValue = new ArrayList<>(); + for (AnnotationMirror annotationMirror : + AnnotationValueUtil.toAnnotationList(annotations)) { + annotationsValue.add(newAnnotationAnnot(annotationMirror)); + } + return new AnnotateWithAnnot(annotateWith, annotations, annotationsValue); + }) + .collect(Collectors.toList()); } private AnnotationAnnot newAnnotationAnnot(AnnotationMirror annotationMirror) { diff --git a/doma-processor/src/main/java/org/seasar/doma/internal/apt/generator/DaoImplGenerator.java b/doma-processor/src/main/java/org/seasar/doma/internal/apt/generator/DaoImplGenerator.java index b1fe6a66a..5e504d5d4 100644 --- a/doma-processor/src/main/java/org/seasar/doma/internal/apt/generator/DaoImplGenerator.java +++ b/doma-processor/src/main/java/org/seasar/doma/internal/apt/generator/DaoImplGenerator.java @@ -133,7 +133,7 @@ private void printConstructors() { if (daoMeta.hasUserDefinedConfig()) { Code configCode = createConfigCode(); printNoArgConstructor(configCode); - if (daoMeta.getAnnotateWithAnnot() == null) { + if (daoMeta.getAnnotateWithAnnots().isEmpty()) { boolean required = areJdbcConstructorsRequired(); if (required) { printConnectionArgConstructor(configCode); diff --git a/doma-processor/src/main/java/org/seasar/doma/internal/apt/meta/dao/DaoMeta.java b/doma-processor/src/main/java/org/seasar/doma/internal/apt/meta/dao/DaoMeta.java index 905f426a0..a482a200d 100644 --- a/doma-processor/src/main/java/org/seasar/doma/internal/apt/meta/dao/DaoMeta.java +++ b/doma-processor/src/main/java/org/seasar/doma/internal/apt/meta/dao/DaoMeta.java @@ -21,7 +21,7 @@ public class DaoMeta implements TypeElementMeta { private final DaoAnnot daoAnnot; - private AnnotateWithAnnot annotateWithAnnot; + private List annotateWithAnnots = Collections.emptyList(); private TypeMirror type; @@ -90,23 +90,22 @@ public AccessLevel getAccessLevel() { return daoAnnot.getAccessLevelValue(); } - public AnnotateWithAnnot getAnnotateWithAnnot() { - return annotateWithAnnot; + public List getAnnotateWithAnnots() { + return annotateWithAnnots; } - public void setAnnotateWithAnnot(AnnotateWithAnnot annotateWithAnnot) { - this.annotateWithAnnot = annotateWithAnnot; + public void setAnnotateWithAnnots(List annotateWithAnnots) { + this.annotateWithAnnots = annotateWithAnnots; } public List getAnnotationMirrors(AnnotationTarget target) { assertNotNull(target); - if (annotateWithAnnot == null || annotateWithAnnot.getAnnotationsValue() == null) { - return Collections.emptyList(); - } List results = new ArrayList<>(); - for (AnnotationAnnot annotationAnnot : annotateWithAnnot.getAnnotationsValue()) { - if (target.name().contentEquals(annotationAnnot.getTargetValue().getSimpleName())) { - results.add(annotationAnnot); + for (AnnotateWithAnnot annotateWithAnnot : annotateWithAnnots) { + for (AnnotationAnnot annotationAnnot : annotateWithAnnot.getAnnotationsValue()) { + if (target.name().contentEquals(annotationAnnot.getTargetValue().getSimpleName())) { + results.add(annotationAnnot); + } } } return results; diff --git a/doma-processor/src/main/java/org/seasar/doma/internal/apt/meta/dao/DaoMetaFactory.java b/doma-processor/src/main/java/org/seasar/doma/internal/apt/meta/dao/DaoMetaFactory.java index d276b1fec..5ab1009cf 100644 --- a/doma-processor/src/main/java/org/seasar/doma/internal/apt/meta/dao/DaoMetaFactory.java +++ b/doma-processor/src/main/java/org/seasar/doma/internal/apt/meta/dao/DaoMetaFactory.java @@ -219,11 +219,9 @@ private void validateInterface(TypeElement interfaceElement, DaoMeta daoMeta) { } private void doAnnotateWith(DaoMeta daoMeta) { - AnnotateWithAnnot annotateWithAnnot = - ctx.getAnnotations().newAnnotateWithAnnot(daoMeta.getTypeElement()); - if (annotateWithAnnot != null) { - daoMeta.setAnnotateWithAnnot(annotateWithAnnot); - } + List annotateWithAnnots = + ctx.getAnnotations().newAnnotateWithAnnots(daoMeta.getTypeElement()); + daoMeta.setAnnotateWithAnnots(annotateWithAnnots); } private void doParentDao(DaoMeta daoMeta) { diff --git a/doma-processor/src/test/java/org/seasar/doma/internal/apt/processor/dao/DaoProcessorTest.java b/doma-processor/src/test/java/org/seasar/doma/internal/apt/processor/dao/DaoProcessorTest.java index 280bec659..29b0ee72d 100644 --- a/doma-processor/src/test/java/org/seasar/doma/internal/apt/processor/dao/DaoProcessorTest.java +++ b/doma-processor/src/test/java/org/seasar/doma/internal/apt/processor/dao/DaoProcessorTest.java @@ -129,7 +129,8 @@ public Stream provideTestTemplateInvocationContex invocationContext(OnlyDefaultMethodsExtendsDao.class), invocationContext( ApplicationScopedDao.class, - "-Adoma.cdi.ApplicationScoped=" + ApplicationScoped.class.getCanonicalName())); + "-Adoma.cdi.ApplicationScoped=" + ApplicationScoped.class.getCanonicalName()), + invocationContext(MultipleAnnotateWithDao.class)); } private TestTemplateInvocationContext invocationContext(Class clazz, String... options) { diff --git a/doma-processor/src/test/java/org/seasar/doma/internal/apt/processor/dao/MultipleAnnotateWithDao.java b/doma-processor/src/test/java/org/seasar/doma/internal/apt/processor/dao/MultipleAnnotateWithDao.java new file mode 100644 index 000000000..755ed3748 --- /dev/null +++ b/doma-processor/src/test/java/org/seasar/doma/internal/apt/processor/dao/MultipleAnnotateWithDao.java @@ -0,0 +1,28 @@ +package org.seasar.doma.internal.apt.processor.dao; + +import org.seasar.doma.AnnotateWith; +import org.seasar.doma.Annotation; +import org.seasar.doma.AnnotationTarget; +import org.seasar.doma.Dao; +import org.seasar.doma.Insert; +import org.seasar.doma.internal.apt.processor.entity.Emp; + +@Dao +@MultipleAnnotationConfig1 +@MultipleAnnotationConfig2 +@AnnotateWith( + annotations = { + @Annotation( + target = AnnotationTarget.CONSTRUCTOR_PARAMETER, + type = ConstructorParameterAnnotation.class, + elements = "aaa = 1, bbb = true"), + @Annotation( + target = AnnotationTarget.CONSTRUCTOR_PARAMETER, + type = ConstructorParameterAnnotation2.class, + elements = "aaa = 1, bbb = true") + }) +public interface MultipleAnnotateWithDao { + + @Insert + int insert(Emp emp); +} diff --git a/doma-processor/src/test/java/org/seasar/doma/internal/apt/processor/dao/MultipleAnnotationConfig1.java b/doma-processor/src/test/java/org/seasar/doma/internal/apt/processor/dao/MultipleAnnotationConfig1.java new file mode 100644 index 000000000..6dc4ae449 --- /dev/null +++ b/doma-processor/src/test/java/org/seasar/doma/internal/apt/processor/dao/MultipleAnnotationConfig1.java @@ -0,0 +1,24 @@ +package org.seasar.doma.internal.apt.processor.dao; + +import java.lang.annotation.ElementType; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import java.lang.annotation.Target; +import org.seasar.doma.AnnotateWith; +import org.seasar.doma.Annotation; +import org.seasar.doma.AnnotationTarget; + +@Target(ElementType.TYPE) +@Retention(RetentionPolicy.RUNTIME) +@AnnotateWith( + annotations = { + @Annotation( + target = AnnotationTarget.CLASS, + type = ClassAnnotation.class, + elements = "aaa = 1, bbb = true"), + @Annotation( + target = AnnotationTarget.CLASS, + type = ClassAnnotation2.class, + elements = "aaa = 1, bbb = true"), + }) +public @interface MultipleAnnotationConfig1 {} diff --git a/doma-processor/src/test/java/org/seasar/doma/internal/apt/processor/dao/MultipleAnnotationConfig2.java b/doma-processor/src/test/java/org/seasar/doma/internal/apt/processor/dao/MultipleAnnotationConfig2.java new file mode 100644 index 000000000..043cb53ae --- /dev/null +++ b/doma-processor/src/test/java/org/seasar/doma/internal/apt/processor/dao/MultipleAnnotationConfig2.java @@ -0,0 +1,24 @@ +package org.seasar.doma.internal.apt.processor.dao; + +import java.lang.annotation.ElementType; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import java.lang.annotation.Target; +import org.seasar.doma.AnnotateWith; +import org.seasar.doma.Annotation; +import org.seasar.doma.AnnotationTarget; + +@Target(ElementType.TYPE) +@Retention(RetentionPolicy.RUNTIME) +@AnnotateWith( + annotations = { + @Annotation( + target = AnnotationTarget.CONSTRUCTOR, + type = ConstructorAnnotation.class, + elements = "aaa = 1, bbb = true"), + @Annotation( + target = AnnotationTarget.CONSTRUCTOR, + type = ConstructorAnnotation2.class, + elements = "aaa = 1, bbb = true"), + }) +public @interface MultipleAnnotationConfig2 {} diff --git a/doma-processor/src/test/resources/org/seasar/doma/internal/apt/processor/dao/DaoProcessorTest_MultipleAnnotateWithDao.txt b/doma-processor/src/test/resources/org/seasar/doma/internal/apt/processor/dao/DaoProcessorTest_MultipleAnnotateWithDao.txt new file mode 100644 index 000000000..37ff0779f --- /dev/null +++ b/doma-processor/src/test/resources/org/seasar/doma/internal/apt/processor/dao/DaoProcessorTest_MultipleAnnotateWithDao.txt @@ -0,0 +1,62 @@ +package org.seasar.doma.internal.apt.processor.dao; + +/** */ +@org.seasar.doma.internal.apt.processor.dao.ClassAnnotation(aaa = 1, bbb = true) +@org.seasar.doma.internal.apt.processor.dao.ClassAnnotation2(aaa = 1, bbb = true) +@javax.annotation.Generated(value = { "Doma", "@VERSION@" }, date = "1970-01-01T09:00:00.000+0900") +@org.seasar.doma.DaoImplementation +public class MultipleAnnotateWithDaoImpl implements org.seasar.doma.internal.apt.processor.dao.MultipleAnnotateWithDao, org.seasar.doma.jdbc.ConfigProvider { + + static { + org.seasar.doma.internal.Artifact.validateVersion("@VERSION@"); + } + + private static final java.lang.reflect.Method __method0 = org.seasar.doma.internal.jdbc.dao.DaoImplSupport.getDeclaredMethod(org.seasar.doma.internal.apt.processor.dao.MultipleAnnotateWithDao.class, "insert", org.seasar.doma.internal.apt.processor.entity.Emp.class); + + private final org.seasar.doma.internal.jdbc.dao.DaoImplSupport __support; + + /** + * @param config the config + */ + @org.seasar.doma.internal.apt.processor.dao.ConstructorAnnotation(aaa = 1, bbb = true) + @org.seasar.doma.internal.apt.processor.dao.ConstructorAnnotation2(aaa = 1, bbb = true) + public MultipleAnnotateWithDaoImpl(@org.seasar.doma.internal.apt.processor.dao.ConstructorParameterAnnotation(aaa = 1, bbb = true) @org.seasar.doma.internal.apt.processor.dao.ConstructorParameterAnnotation2(aaa = 1, bbb = true) org.seasar.doma.jdbc.Config config) { + __support = new org.seasar.doma.internal.jdbc.dao.DaoImplSupport(config); + } + + @Override + public org.seasar.doma.jdbc.Config getConfig() { + return __support.getConfig(); + } + + @Override + public int insert(org.seasar.doma.internal.apt.processor.entity.Emp emp) { + __support.entering("org.seasar.doma.internal.apt.processor.dao.MultipleAnnotateWithDaoImpl", "insert", emp); + try { + if (emp == null) { + throw new org.seasar.doma.DomaNullPointerException("emp"); + } + org.seasar.doma.jdbc.query.AutoInsertQuery __query = __support.getQueryImplementors().createAutoInsertQuery(__method0, org.seasar.doma.internal.apt.processor.entity._Emp.getSingletonInternal()); + __query.setMethod(__method0); + __query.setConfig(__support.getConfig()); + __query.setEntity(emp); + __query.setCallerClassName("org.seasar.doma.internal.apt.processor.dao.MultipleAnnotateWithDaoImpl"); + __query.setCallerMethodName("insert"); + __query.setQueryTimeout(-1); + __query.setSqlLogType(org.seasar.doma.jdbc.SqlLogType.FORMATTED); + __query.setNullExcluded(false); + __query.setIncludedPropertyNames(); + __query.setExcludedPropertyNames(); + __query.prepare(); + org.seasar.doma.jdbc.command.InsertCommand __command = __support.getCommandImplementors().createInsertCommand(__method0, __query); + int __result = __command.execute(); + __query.complete(); + __support.exiting("org.seasar.doma.internal.apt.processor.dao.MultipleAnnotateWithDaoImpl", "insert", __result); + return __result; + } catch (java.lang.RuntimeException __e) { + __support.throwing("org.seasar.doma.internal.apt.processor.dao.MultipleAnnotateWithDaoImpl", "insert", __e); + throw __e; + } + } + +}