From 4516607284d7105b47ef4982e8fec026178d8ac4 Mon Sep 17 00:00:00 2001 From: Lukas Eder Date: Tue, 16 Jan 2024 10:41:57 +0100 Subject: [PATCH] [jOOQ/jOOQ#16083] jOOQ-gradle-plugin multi execution configuration shouldn't require an explicit default configuration This includes: - [jOOQ/jOOQ#16084] Wrong order of MiniJAXB.append() calls in jOOQ-codegen-gradle --- .../jooq/codegen/gradle/CodegenPlugin.java | 2 +- .../org/jooq/codegen/gradle/CodegenTask.java | 11 ++++-- .../codegen/gradle/NamedConfiguration.java | 16 +++++---- .../org/jooq/util/jaxb/tools/MiniJAXB.java | 35 +++++++++++++------ 4 files changed, 43 insertions(+), 21 deletions(-) diff --git a/jOOQ-codegen-gradle/src/main/java/org/jooq/codegen/gradle/CodegenPlugin.java b/jOOQ-codegen-gradle/src/main/java/org/jooq/codegen/gradle/CodegenPlugin.java index ff34e0c7da..b444c4f22f 100644 --- a/jOOQ-codegen-gradle/src/main/java/org/jooq/codegen/gradle/CodegenPlugin.java +++ b/jOOQ-codegen-gradle/src/main/java/org/jooq/codegen/gradle/CodegenPlugin.java @@ -79,7 +79,7 @@ public class CodegenPlugin implements Plugin { jooq.getExecutions().create("", configuration -> { configuration.unnamed = true; - configuration.configuration = NamedConfiguration.newConfiguration(); + configuration.configuration = NamedConfiguration.init(new org.jooq.meta.jaxb.Configuration()); }); List named = new ArrayList<>(); diff --git a/jOOQ-codegen-gradle/src/main/java/org/jooq/codegen/gradle/CodegenTask.java b/jOOQ-codegen-gradle/src/main/java/org/jooq/codegen/gradle/CodegenTask.java index fdf94371d5..b703426572 100644 --- a/jOOQ-codegen-gradle/src/main/java/org/jooq/codegen/gradle/CodegenTask.java +++ b/jOOQ-codegen-gradle/src/main/java/org/jooq/codegen/gradle/CodegenTask.java @@ -40,6 +40,7 @@ package org.jooq.codegen.gradle; import org.gradle.api.DefaultTask; import org.gradle.api.GradleException; import org.gradle.api.file.Directory; +import org.gradle.api.file.DirectoryProperty; import org.gradle.api.file.FileCollection; import org.gradle.api.file.ProjectLayout; import org.gradle.api.provider.Property; @@ -56,6 +57,7 @@ import java.io.File; import java.net.URL; import java.net.URLClassLoader; import java.util.ArrayList; +import java.util.Arrays; import java.util.List; import java.util.concurrent.atomic.AtomicBoolean; @@ -118,9 +120,12 @@ public class CodegenTask extends DefaultTask { return codegenClasspath; } - @OutputDirectory @Optional - public Property getOutputDirectory() { - return configuration.outputDirectory; + @OutputDirectories + public List getOutputDirectory() { + if (named.isEmpty() && configuration.outputDirectorySet) + return Arrays.asList(configuration.outputDirectory); + else + return Arrays.asList(); } private URLClassLoader getClassLoader() { diff --git a/jOOQ-codegen-gradle/src/main/java/org/jooq/codegen/gradle/NamedConfiguration.java b/jOOQ-codegen-gradle/src/main/java/org/jooq/codegen/gradle/NamedConfiguration.java index 5761db41d0..f395de57cf 100644 --- a/jOOQ-codegen-gradle/src/main/java/org/jooq/codegen/gradle/NamedConfiguration.java +++ b/jOOQ-codegen-gradle/src/main/java/org/jooq/codegen/gradle/NamedConfiguration.java @@ -40,6 +40,7 @@ package org.jooq.codegen.gradle; import org.gradle.api.Action; import org.gradle.api.Project; import org.gradle.api.file.Directory; +import org.gradle.api.file.DirectoryProperty; import org.gradle.api.file.ProjectLayout; import org.gradle.api.model.ObjectFactory; import org.gradle.api.provider.Property; @@ -66,7 +67,8 @@ public class NamedConfiguration { final String name; boolean unnamed; Configuration configuration; - Property outputDirectory; + DirectoryProperty outputDirectory; + boolean outputDirectorySet; @Inject public NamedConfiguration( @@ -80,12 +82,12 @@ public class NamedConfiguration { this.layout = layout; this.name = name; this.unnamed = false; - this.configuration = newConfiguration(); + this.configuration = init(new Configuration()); this.outputDirectory = objects.directoryProperty(); } - static final Configuration newConfiguration() { - return new Configuration() + static final Configuration init(Configuration configuration) { + return configuration .withGenerator(new Generator() .withTarget(new Target())); } @@ -100,9 +102,9 @@ public class NamedConfiguration { void configuration0(Configuration configuration) { if (!unnamed) - MiniJAXB.append(this.configuration, copy(project.getExtensions().getByType(CodegenPluginExtension.class).defaultConfiguration().configuration)); + this.configuration = MiniJAXB.append(copy(project.getExtensions().getByType(CodegenPluginExtension.class).defaultConfiguration().configuration), copy(this.configuration)); - MiniJAXB.append(this.configuration, configuration); + this.configuration = MiniJAXB.append(copy(configuration), copy(this.configuration)); } static Configuration copy(Configuration configuration) { @@ -111,6 +113,7 @@ public class NamedConfiguration { public void configuration(Action action) { ConfigurationExtension c = objects.newInstance(ConfigurationExtension.class, objects); + init(c); action.execute(c); configuration0(c); @@ -124,6 +127,7 @@ public class NamedConfiguration { configuration.getGenerator().getTarget().setDirectory("build/generated-sources/jooq"); outputDirectory.value(layout.getProjectDirectory().dir(target.getDirectory())); + outputDirectorySet = true; } boolean defaultTarget() { diff --git a/jOOQ/src/main/java/org/jooq/util/jaxb/tools/MiniJAXB.java b/jOOQ/src/main/java/org/jooq/util/jaxb/tools/MiniJAXB.java index 9fe2c77087..8644acb8eb 100644 --- a/jOOQ/src/main/java/org/jooq/util/jaxb/tools/MiniJAXB.java +++ b/jOOQ/src/main/java/org/jooq/util/jaxb/tools/MiniJAXB.java @@ -50,6 +50,7 @@ import java.io.Reader; import java.io.StringReader; import java.io.StringWriter; import java.io.Writer; +import java.lang.annotation.Annotation; import java.lang.reflect.Field; import java.lang.reflect.InvocationTargetException; import java.lang.reflect.Method; @@ -138,7 +139,7 @@ public final class MiniJAXB { public static void marshal(XMLAppendable object, Writer out) { try { XMLBuilder builder = XMLBuilder.formatting(); - XmlRootElement e = object.getClass().getAnnotation(XmlRootElement.class); + XmlRootElement e = getAnnotation(object.getClass(), XmlRootElement.class); if (e != null) { out.write("\n"); builder.append(e.name(), object); @@ -300,10 +301,10 @@ public final class MiniJAXB { List list = new ArrayList(asList(childElement.getTextContent().split(" +"))); Reflect.on(result).set(childName, Convert.convert(list, (Class) ((ParameterizedType) child.getGenericType()).getActualTypeArguments()[0])); } - else if (childType.getAnnotation(XmlEnum.class) != null) { + else if (getAnnotation(childType, XmlEnum.class) != null) { Reflect.on(result).set(childName, Reflect.onClass(childType).call("fromValue", textContent.trim())); } - else if (childType.getAnnotation(XmlType.class) != null) { + else if (getAnnotation(childType, XmlType.class) != null) { Object object = Reflect.on(childType).create().get(); Reflect.on(result).set(childName, object); @@ -324,7 +325,7 @@ public final class MiniJAXB { return; // [#13897] Distinguish between lists of xs:complexType and xs:simpleType - boolean isComplexType = type.getAnnotation(XmlType.class) != null; + boolean isComplexType = getAnnotation(type, XmlType.class) != null; NodeList list = element.getChildNodes(); for (int i = 0; i < list.getLength(); i++) { Node item = list.item(i); @@ -446,6 +447,7 @@ public final class MiniJAXB { private static String getNamespace(Class type) { if (type != null && type.getPackage() != null && type.getPackage().isAnnotationPresent(XmlSchema.class)) return type.getPackage().getAnnotation(XmlSchema.class).namespace(); + return null; } @@ -495,13 +497,7 @@ public final class MiniJAXB { // We're assuming that XJC generated objects are all in the same package Package pkg = firstClass.getPackage(); try { - - // [#12985] [#15974] [#15966] Gradle generates a subclass for our configuration extensions, which - // will accept an injected argument. We shouldn't use that subclass here. - Class defaultsClass = firstClass; - while (defaultsClass.getName().startsWith("org.jooq.codegen.gradle")) - defaultsClass = (Class) defaultsClass.getSuperclass(); - + Class defaultsClass = nonGradleExtensionClass(firstClass); T defaults = defaultsClass.getDeclaredConstructor().newInstance(); methodLoop: @@ -554,4 +550,21 @@ public final class MiniJAXB { return first; } + + /** + * [#12985] [#15974] [#15966] Gradle generates a subclass for our + * configuration extensions, which will accept an injected argument. We + * shouldn't use that subclass here. + */ + @SuppressWarnings("unchecked") + private static Class nonGradleExtensionClass(Class klass) { + while (klass.getName().startsWith("org.jooq.codegen.gradle")) + klass = (Class) klass.getSuperclass(); + + return klass; + } + + private static A getAnnotation(Class klass, Class annotation) { + return nonGradleExtensionClass(klass).getAnnotation(annotation); + } }