From 85c4f6be40e1347fd07089b3763d3ea8c73ba602 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Franz=20Wilhelmst=C3=B6tter?= Date: Wed, 15 Nov 2023 23:19:51 +0100 Subject: [PATCH 01/14] Update version number. --- buildSrc/src/main/kotlin/Env.kt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/buildSrc/src/main/kotlin/Env.kt b/buildSrc/src/main/kotlin/Env.kt index 8d5c307..1a2d691 100644 --- a/buildSrc/src/main/kotlin/Env.kt +++ b/buildSrc/src/main/kotlin/Env.kt @@ -52,7 +52,7 @@ object Env { * Information about the library and author. */ object FacileJDBC { - const val VERSION = "2.1.0" + const val VERSION = "3.0.0-SNAPSHOT" const val ID = "facilejdbc" const val NAME = "facilejdbc" const val GROUP = "io.jenetics" From 0d214b4a50c36a8e8ec372a8e6a8cb1bb18396dd Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Franz=20Wilhelmst=C3=B6tter?= Date: Mon, 4 Aug 2025 19:34:02 +0200 Subject: [PATCH 02/14] Improve Javadoc. MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Franz Wilhelmstötter --- .../java/io/jenetics/facilejdbc/Lifecycle.java | 18 +++++++++--------- .../io/jenetics/facilejdbc/ParamValues.java | 2 +- .../io/jenetics/facilejdbc/PreparedQuery.java | 2 +- .../java/io/jenetics/facilejdbc/Query.java | 2 +- .../java/io/jenetics/facilejdbc/Records.java | 8 ++++---- .../io/jenetics/facilejdbc/Transaction.java | 2 +- .../io/jenetics/facilejdbc/Transactional.java | 8 ++++---- .../facilejdbc/function/package-info.java | 2 +- .../io/jenetics/facilejdbc/package-info.java | 2 +- .../jenetics/facilejdbc/spi/SqlTypeMapper.java | 1 - 10 files changed, 23 insertions(+), 24 deletions(-) diff --git a/facilejdbc/src/main/java/io/jenetics/facilejdbc/Lifecycle.java b/facilejdbc/src/main/java/io/jenetics/facilejdbc/Lifecycle.java index 19c45fb..cd921c6 100644 --- a/facilejdbc/src/main/java/io/jenetics/facilejdbc/Lifecycle.java +++ b/facilejdbc/src/main/java/io/jenetics/facilejdbc/Lifecycle.java @@ -46,7 +46,7 @@ final class Lifecycle { /** * Runnable task/method, which might throw an exception {@code E}. * - * @param the exception which might be thrown + * @param the exception, which might be thrown */ @FunctionalInterface public interface ThrowingRunnable { @@ -183,7 +183,7 @@ default void silentClose(final Throwable previousError) { /** * Create a new {@code ExtendedCloseable} object with the given initial - * release methods. The given list of objects are closed in + * release methods. The given list of objects is closed in * reversed order. * * @see #of(ThrowingRunnable...) @@ -206,7 +206,7 @@ default void silentClose(final Throwable previousError) { /** * Create a new {@code ExtendedCloseable} object with the given initial - * release methods. The given list of objects are closed in + * release methods. The given list of objects is closed in * reversed order. * * @see #of(Collection) @@ -230,7 +230,7 @@ default void silentClose(final Throwable previousError) { * This class represents a closeable value. It is useful in cases * where the object value doesn't implement the {@link AutoCloseable} * interface but needs some cleanup work to do after usage. In the following - * example the create {@code file} is automatically deleted when leaving the + * example the created {@code file} is automatically deleted when leaving the * {@code try} block. * *
{@code
@@ -286,7 +286,7 @@ public String toString() {
 
 		/**
 		 * Applies the give {@code block} to the already created closeable value.
-		 * If the {@code block} throws an exception, the  resource value is
+		 * If the {@code block} throws an exception, the resource value is
 		 * released, by calling the defined release method. The typical
 		 * use case for this method is when additional initialization of the
 		 * value is needed.
@@ -372,7 +372,7 @@ public static  Value of(
 		 *
 		 * @param builder the builder method
 		 * @param  the value type of the created closeable value
-		 * @param  the exception type which might be thrown while building
+		 * @param  the exception type, which might be thrown while building
 		 *             the value
 		 * @param  the exception type which might be thrown when releasing
 		 *              the returned closeable value
@@ -408,10 +408,10 @@ public static  Value of(
 	}
 
 	/**
-	 * This class allows to collect one or more {@link AutoCloseable} objects
+	 * This class allows collecting one or more {@link AutoCloseable} objects
 	 * into one. The registered closeable objects are closed in reverse order.
 	 * 

- * Using the {@code Resources} class can simplify the the creation of + * Using the {@code Resources} class can simplify the creation of * dependent input streams, where it might be otherwise necessary to create * nested {@code try-with-resources} blocks. * @@ -470,7 +470,7 @@ public Resources() { * resources. * * @param resource the new resource to register - * @param release the method, which releases the the acquired + * @param release the method, which releases the acquired * resource * @param the resource type * @return the registered resource diff --git a/facilejdbc/src/main/java/io/jenetics/facilejdbc/ParamValues.java b/facilejdbc/src/main/java/io/jenetics/facilejdbc/ParamValues.java index d2901da..0c953bb 100644 --- a/facilejdbc/src/main/java/io/jenetics/facilejdbc/ParamValues.java +++ b/facilejdbc/src/main/java/io/jenetics/facilejdbc/ParamValues.java @@ -26,7 +26,7 @@ import java.util.List; /** - * This represents a whole Sql row (parameter set). Instead of representing the + * This represents a whole SQL row (parameter set). Instead of representing the * row directly, a row is defined it's insertion strategy. * * @see SingleParam diff --git a/facilejdbc/src/main/java/io/jenetics/facilejdbc/PreparedQuery.java b/facilejdbc/src/main/java/io/jenetics/facilejdbc/PreparedQuery.java index 981107f..bfd227f 100644 --- a/facilejdbc/src/main/java/io/jenetics/facilejdbc/PreparedQuery.java +++ b/facilejdbc/src/main/java/io/jenetics/facilejdbc/PreparedQuery.java @@ -28,7 +28,7 @@ /** * A prepared query has a {@link PreparedStatement} attached and lets you do - * batch inserts in a convenient way. + * batch inserts conveniently. * * @author Franz Wilhelmstötter * @version 2.1 diff --git a/facilejdbc/src/main/java/io/jenetics/facilejdbc/Query.java b/facilejdbc/src/main/java/io/jenetics/facilejdbc/Query.java index b26c6da..7d29386 100644 --- a/facilejdbc/src/main/java/io/jenetics/facilejdbc/Query.java +++ b/facilejdbc/src/main/java/io/jenetics/facilejdbc/Query.java @@ -527,7 +527,7 @@ private static Optional readId( /** * Executes the SQL statement in a {@link PreparedStatement} object, which - * must be an SQL {@code INSERT}. It returns, the optionally generated, key + * must be an SQL {@code INSERT}. It returns the optionally generated, key * for the inserted row. * * @see PreparedStatement#executeUpdate() diff --git a/facilejdbc/src/main/java/io/jenetics/facilejdbc/Records.java b/facilejdbc/src/main/java/io/jenetics/facilejdbc/Records.java index efc8559..8c927c2 100644 --- a/facilejdbc/src/main/java/io/jenetics/facilejdbc/Records.java +++ b/facilejdbc/src/main/java/io/jenetics/facilejdbc/Records.java @@ -98,7 +98,7 @@ private Records() { * @param type the record type to deconstruct * @param toColumnName function for mapping the record component to the * column names of the DB - * @param fields The fields which overrides/extends the + * @param fields The fields that override/extend the * automatically extracted fields from the record. It also allows * defining additional column values, derived from the given record * values. @@ -178,7 +178,7 @@ private static Dctor.Field toFiled( * @param type the record type to deconstruct * @param toColumnName function for mapping the record component to the * column names of the DB - * @param fields The fields which overrides/extends the + * @param fields The fields that override/extend the * automatically extracted fields from the record. It also allows * defining additional column values, derived from the given record * values. @@ -225,7 +225,7 @@ public static Dctor dctor( * @see Dctor#of(Class, Dctor.Field[]) * * @param type the record type to deconstruct - * @param fields The fields which overrides/extends the + * @param fields The fields that override/extend the * automatically extracted fields from the record. It also allows * defining additional column values, derived from the given record * values. @@ -243,7 +243,7 @@ public static Dctor dctor( } /** - * Converts to given a record component to a column name in + * Converts to give a record component to a column name in * snake_case. * * @see #toSnakeCase(String) diff --git a/facilejdbc/src/main/java/io/jenetics/facilejdbc/Transaction.java b/facilejdbc/src/main/java/io/jenetics/facilejdbc/Transaction.java index d71fc27..a7d0c92 100644 --- a/facilejdbc/src/main/java/io/jenetics/facilejdbc/Transaction.java +++ b/facilejdbc/src/main/java/io/jenetics/facilejdbc/Transaction.java @@ -119,7 +119,7 @@ default void accept(final SqlConsumer block) * }

* * @apiNote - * This method implements the transactional default behaviour ot the + * This method implements the transactional default behavior of the * {@link Transaction} implementation, returned by the * {@link Transactional#transaction()} interface. * diff --git a/facilejdbc/src/main/java/io/jenetics/facilejdbc/Transactional.java b/facilejdbc/src/main/java/io/jenetics/facilejdbc/Transactional.java index 30a7def..c49bb76 100644 --- a/facilejdbc/src/main/java/io/jenetics/facilejdbc/Transactional.java +++ b/facilejdbc/src/main/java/io/jenetics/facilejdbc/Transactional.java @@ -114,7 +114,7 @@ public interface Transactional { /** - * Return the DB connection. If you obtain a new connection, you are + * Return the DB connection. If you get a new connection, you are * responsible for closing it after usage. This is done ideally in a * resource-try block. * @@ -128,17 +128,17 @@ public interface Transactional { * * You are usually using the {@link #transaction()} method for getting an * instance of the {@link Transaction} interface, which is then using this - * method for obtaining the needed connections. + * method for getting the necessary connections. * * @see #transaction() * * @return the DB connection - * @throws SQLException if obtaining a DB connection fails + * @throws SQLException if getting a DB connection fails */ Connection connection() throws SQLException; /** - * Return a Transaction object, which obtains the connection, + * Return a Transaction object, which gets the connection, * needed for executing a query, from the {@link #connection()} factory * method. The transactional behavior is defined by the * {@link #txm(Connection, SqlSupplier)} method of {@code this} interface. diff --git a/facilejdbc/src/main/java/io/jenetics/facilejdbc/function/package-info.java b/facilejdbc/src/main/java/io/jenetics/facilejdbc/function/package-info.java index 2e1d1c1..574b68b 100644 --- a/facilejdbc/src/main/java/io/jenetics/facilejdbc/function/package-info.java +++ b/facilejdbc/src/main/java/io/jenetics/facilejdbc/function/package-info.java @@ -19,7 +19,7 @@ */ /** - * Contains all needed functional interfaces, which may throw a + * Contains all necessary functional interfaces, which may throw a * {@link java.sql.SQLException}. * * @author Franz Wilhelmstötter diff --git a/facilejdbc/src/main/java/io/jenetics/facilejdbc/package-info.java b/facilejdbc/src/main/java/io/jenetics/facilejdbc/package-info.java index 1db88e2..873c5bb 100644 --- a/facilejdbc/src/main/java/io/jenetics/facilejdbc/package-info.java +++ b/facilejdbc/src/main/java/io/jenetics/facilejdbc/package-info.java @@ -19,7 +19,7 @@ */ /** - * This is the base package of the JDBC wrapper and contains all needed + * This is the base package of the JDBC wrapper and contains all necessary * interfaces and the {@link io.jenetics.facilejdbc.Query} class. An overview * of the purpose and functionality of the FacileJDBC library can be * found here. diff --git a/facilejdbc/src/main/java/io/jenetics/facilejdbc/spi/SqlTypeMapper.java b/facilejdbc/src/main/java/io/jenetics/facilejdbc/spi/SqlTypeMapper.java index 389a488..a9de073 100644 --- a/facilejdbc/src/main/java/io/jenetics/facilejdbc/spi/SqlTypeMapper.java +++ b/facilejdbc/src/main/java/io/jenetics/facilejdbc/spi/SqlTypeMapper.java @@ -22,7 +22,6 @@ /** * The purpose of this SPI is to map simple domain values into the * proper type of the used DB. This may lead to a more readable insertion code. - * * Usually, it is not possible to insert an {@code URI} field directly into the * DB. You have to convert it into a string object first. *
{@code

From 3cda7d7c19bc093f559119402bf6b899f6332d8b Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Franz=20Wilhelmst=C3=B6tter?=
 
Date: Mon, 4 Aug 2025 20:45:19 +0200
Subject: [PATCH 03/14] #61: Update build system.
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

Signed-off-by: Franz Wilhelmstötter 
---
 build.gradle.kts                              | 258 +++--
 buildSrc/build.gradle.kts                     |  13 +-
 buildSrc/lib/java2html.jar                    | Bin 192952 -> 0 bytes
 .../resources/javadoc/java.se/element-list    |   4 +-
 buildSrc/resources/javadoc/stylesheet.css     | 881 ------------------
 .../java/io/jenetics/gradle/Colorizer.java    | 365 --------
 .../io/jenetics/gradle/ColorizerTask.java     |  63 --
 .../java/io/jenetics/gradle/package-info.java |  26 -
 facilejdbc/build.gradle.kts                   |   6 +-
 gradle.properties                             |   1 +
 gradle/libs.versions.toml                     |  91 +-
 gradle/wrapper/gradle-wrapper.properties      |   2 +-
 gradlew                                       |  41 +-
 gradlew.bat                                   |  15 +-
 14 files changed, 242 insertions(+), 1524 deletions(-)
 delete mode 100644 buildSrc/lib/java2html.jar
 delete mode 100644 buildSrc/resources/javadoc/stylesheet.css
 delete mode 100644 buildSrc/src/main/java/io/jenetics/gradle/Colorizer.java
 delete mode 100644 buildSrc/src/main/java/io/jenetics/gradle/ColorizerTask.java
 delete mode 100644 buildSrc/src/main/java/io/jenetics/gradle/package-info.java
 create mode 100644 gradle.properties

diff --git a/build.gradle.kts b/build.gradle.kts
index d25d455..dd91b92 100644
--- a/build.gradle.kts
+++ b/build.gradle.kts
@@ -1,5 +1,5 @@
 /*
- * Facile JDBC Library (@__identifier__@).
+ * Java Genetic Algorithm Library (@__identifier__@).
  * Copyright (c) @__year__@ Franz Wilhelmstötter
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
@@ -18,27 +18,28 @@
  *    Franz Wilhelmstötter (franz.wilhelmstoetter@gmail.com)
  */
 
+import org.apache.tools.ant.filters.ReplaceTokens
 
 /**
  * @author Franz Wilhelmstötter
- * @since 1.0
- * @version 1.2
+ * @since 1.2
+ * @version 3.0
  */
-
 plugins {
 	base
 	alias(libs.plugins.jmh)
 }
 
-rootProject.version = FacileJDBC.VERSION
+rootProject.version = providers.gradleProperty("facilejdbc.version").get()
+
 
 tasks.named("wrapper") {
-	version = "8.4"
+	gradleVersion = "8.14"
 	distributionType = Wrapper.DistributionType.ALL
 }
 
 /**
- * Project configuration *before* the projects has been evaluated.
+ * Project configuration *before* the projects have been evaluated.
  */
 allprojects {
 	group =  FacileJDBC.GROUP
@@ -53,41 +54,63 @@ allprojects {
 	}
 
 	configurations.all {
-		resolutionStrategy.failOnVersionConflict()
+		resolutionStrategy.preferProjectModules()
 	}
 }
 
-/**
- * Project configuration *after* the projects has been evaluated.
- */
-gradle.projectsEvaluated {
-	subprojects {
-		val project = this
+subprojects {
+	val project = this
 
-		tasks.withType {
-			options.compilerArgs.add("-Xlint:" + xlint())
-		}
+	tasks.withType {
+		useTestNG()
+	}
 
-		plugins.withType {
-			configure {
-				sourceCompatibility = JavaVersion.VERSION_17
-				targetCompatibility = JavaVersion.VERSION_17
-			}
+	plugins.withType {
 
-			configure {
-				modularity.inferModulePath.set(true)
-			}
+		configure {
+			modularity.inferModulePath = true
+
+			sourceCompatibility = JavaVersion.VERSION_21
+			targetCompatibility = JavaVersion.VERSION_21
 
-			setupJava(project)
-			setupTestReporting(project)
-			setupJavadoc(project)
+			toolchain {
+				languageVersion = JavaLanguageVersion.of(21)
+			}
 		}
 
+		setupJava(project)
+		setupTestReporting(project)
+	}
+
+	tasks.withType {
+		modularity.inferModulePath = true
+
+		options.compilerArgs.add("-Xlint:${xlint()}")
+	}
+
+}
+
+gradle.projectsEvaluated {
+	subprojects {
 		if (plugins.hasPlugin("maven-publish")) {
 			setupPublishing(project)
 		}
-	}
 
+		// Enforcing the library version defined in the version catalogs.
+		val catalogs = extensions.getByType()
+		val libraries = catalogs.catalogNames
+			.map { catalogs.named(it) }
+			.flatMap { catalog -> catalog.libraryAliases.map { alias -> Pair(catalog, alias) } }
+			.map { it.first.findLibrary(it.second).get().get() }
+			.filter { it.version != null }
+			.map { it.toString() }
+			.toTypedArray()
+
+		configurations.all {
+			resolutionStrategy.preferProjectModules()
+			resolutionStrategy.force(*libraries)
+		}
+	}
 }
 
 /**
@@ -96,11 +119,11 @@ gradle.projectsEvaluated {
 fun setupJava(project: Project) {
 	val attr = mutableMapOf(
 		"Implementation-Title" to project.name,
-		"Implementation-Version" to FacileJDBC.VERSION,
+		"Implementation-Version" to project.version,
 		"Implementation-URL" to FacileJDBC.URL,
 		"Implementation-Vendor" to FacileJDBC.NAME,
 		"ProjectName" to FacileJDBC.NAME,
-		"Version" to FacileJDBC.VERSION,
+		"Version" to project.version,
 		"Maintainer" to FacileJDBC.AUTHOR,
 		"Project" to project.name,
 		"Project-Version" to project.version,
@@ -122,6 +145,31 @@ fun setupJava(project: Project) {
 			attributes(attr)
 		}
 	}
+
+	project.tasks.withType {
+		val doclet = options as StandardJavadocDocletOptions
+		doclet.addBooleanOption("Xdoclint:accessibility,html,reference,syntax", true)
+		doclet.addStringOption("-show-module-contents", "api")
+		doclet.addStringOption("-show-packages", "exported")
+		doclet.version(true)
+		doclet.docEncoding = "UTF-8"
+		doclet.charSet = "UTF-8"
+		doclet.linkSource(true)
+		doclet.linksOffline(
+			"https://docs.oracle.com/en/java/javase/21/docs/api/",
+			"${project.rootDir}/buildSrc/resources/javadoc/java.se"
+		)
+		doclet.windowTitle = "Jenetics ${project.version}"
+		doclet.docTitle = "

Jenetics ${project.version}

" + doclet.bottom = "© ${Env.COPYRIGHT_YEAR} Franz Wilhelmstötter  (${Env.BUILD_DATE})" + + doclet.addStringOption("docfilessubdirs") + doclet.tags = listOf( + "apiNote:a:API Note:", + "implSpec:a:Implementation Requirements:", + "implNote:a:Implementation Note:" + ) + } } /** @@ -131,7 +179,7 @@ fun setupTestReporting(project: Project) { project.apply(plugin = "jacoco") project.configure { - toolVersion = "0.8.11" + toolVersion = libs.jacoco.agent.get().version.toString() } project.tasks { @@ -146,115 +194,46 @@ fun setupTestReporting(project: Project) { } named("test") { - useTestNG() finalizedBy("jacocoTestReport") } } } -/** - * Setup of the projects Javadoc. - */ -fun setupJavadoc(project: Project) { - project.tasks.withType { - val doclet = options as StandardJavadocDocletOptions - doclet.addBooleanOption("Xdoclint:accessibility,html,reference,syntax", true) - - exclude("**/internal/**") - - doclet.memberLevel = JavadocMemberLevel.PROTECTED - doclet.version(true) - doclet.docEncoding = "UTF-8" - doclet.charSet = "UTF-8" - doclet.linkSource(true) - doclet.linksOffline( - "https://docs.oracle.com/en/java/javase/17/docs/api/", - "${project.rootDir}/buildSrc/resources/javadoc/java.se" - ) - doclet.windowTitle = "FacileJDBC ${project.version}" - doclet.docTitle = "

FacileJDBC ${project.version}

" - doclet.bottom = "© ${Env.COPYRIGHT_YEAR} Franz Wilhelmstötter  (${Env.BUILD_DATE})" - doclet.stylesheetFile = project.file("${project.rootDir}/buildSrc/resources/javadoc/stylesheet.css") - - doclet.tags = listOf( - "apiNote:a:API Note:", - "implSpec:a:Implementation Requirements:", - "implNote:a:Implementation Note:" +fun snippetPaths(project: Project): String? { + return File("${project.projectDir}/src/main/java").walk() + .filter { file -> file.isDirectory && file.endsWith("snippet-files") } + .joinToString( + transform = { file -> file.absolutePath }, + separator = File.pathSeparator ) - - doLast { - project.copy { - from("src/main/java") { - include("io/**/doc-files/*.*") - } - includeEmptyDirs = false - into(destinationDir!!) - } - } - } - - val javadoc = project.tasks.findByName("javadoc") as Javadoc? - if (javadoc != null) { - project.tasks.register("colorizer") { - directory = javadoc.destinationDir!! - } - - project.tasks.register("java2html") { - doLast { - project.javaexec { - mainClass.set("de.java2html.Java2Html") - args = listOf( - "-srcdir", "src/main/java", - "-targetdir", "${javadoc.destinationDir}/src-html" - ) - classpath = files("${project.rootDir}/buildSrc/lib/java2html.jar") - } - } - } - - javadoc.doLast { - val colorizer = project.tasks.findByName("colorizer") - colorizer?.actions?.forEach { - it.execute(colorizer) - } - - - val java2html = project.tasks.findByName("java2html") - java2html?.actions?.forEach { - it.execute(java2html) - } - } - } + .ifEmpty { null } } /** * The Java compiler XLint flags. */ fun xlint(): String { - // See https://docs.oracle.com/javase/9/tools/javac.htm#JSWOR627 + // See https://docs.oracle.com/en/java/javase/17/docs/specs/man/javac.html return listOf( - "auxiliaryclass", "cast", + "auxiliaryclass", "classfile", "dep-ann", "deprecation", "divzero", "empty", - "exports", "finally", - "module", - "opens", "overrides", "rawtypes", "removal", - "serial", + // "serial" -- Creates unnecessary warnings., "static", "try", "unchecked" ).joinToString(separator = ",") } -val identifier = "${FacileJDBC.ID}-${FacileJDBC.VERSION}" +val identifier = "${FacileJDBC.ID}-${providers.gradleProperty("facilejdbc.version").get()}" /** * Setup of the Maven publishing. @@ -267,26 +246,29 @@ fun setupPublishing(project: Project) { project.tasks.named("sourcesJar") { filter( - org.apache.tools.ant.filters.ReplaceTokens::class, "tokens" to mapOf( - "__identifier__" to identifier, - "__year__" to Env.COPYRIGHT_YEAR - ) + ReplaceTokens::class, "tokens" to mapOf( + "__identifier__" to identifier, + "__year__" to Env.COPYRIGHT_YEAR + ) ) } project.tasks.named("javadocJar") { filter( - org.apache.tools.ant.filters.ReplaceTokens::class, "tokens" to mapOf( - "__identifier__" to identifier, - "__year__" to Env.COPYRIGHT_YEAR - ) + ReplaceTokens::class, "tokens" to mapOf( + "__identifier__" to identifier, + "__year__" to Env.COPYRIGHT_YEAR + ) ) } project.configure { publications { create("mavenJava") { - artifactId = FacileJDBC.ID + suppressPomMetadataWarningsFor("testFixturesApiElements") + suppressPomMetadataWarningsFor("testFixturesRuntimeElements") + + artifactId = project.name from(project.components["java"]) versionMapping { usage("java-api") { @@ -326,24 +308,23 @@ fun setupPublishing(project: Project) { } repositories { maven { - url = if (version.toString().endsWith("SNAPSHOT")) { - uri(Maven.SNAPSHOT_URL) - } else { - uri(Maven.RELEASE_URL) - } + url = if (version.toString().endsWith("SNAPSHOT")) + uri(layout.buildDirectory.dir("repos/releases")) + else + uri(layout.buildDirectory.dir("repos/snapshots")) + } + } - credentials { - username = if (extra.properties["nexus_username"] != null) { - extra.properties["nexus_username"] as String - } else { - "nexus_username" - } - password = if (extra.properties["nexus_password"] != null) { - extra.properties["nexus_password"] as String - } else { - "nexus_password" - } - } + // Exclude test fixtures from publication, as we use them only internally + plugins.withId("org.gradle.java-test-fixtures") { + val component = components["java"] as AdhocComponentWithVariants + component.withVariantsFromConfiguration(configurations["testFixturesApiElements"]) { skip() } + component.withVariantsFromConfiguration(configurations["testFixturesRuntimeElements"]) { skip() } + + // Workaround to not publish test fixtures sources added by com.vanniktech.maven.publish plugin + // TODO: Remove as soon as https://github.com/vanniktech/gradle-maven-publish-plugin/issues/779 closed + afterEvaluate { + component.withVariantsFromConfiguration(configurations["testFixturesSourcesElements"]) { skip() } } } } @@ -355,4 +336,3 @@ fun setupPublishing(project: Project) { } } - diff --git a/buildSrc/build.gradle.kts b/buildSrc/build.gradle.kts index 823d73e..d2eb006 100644 --- a/buildSrc/build.gradle.kts +++ b/buildSrc/build.gradle.kts @@ -23,24 +23,13 @@ import org.jetbrains.kotlin.gradle.tasks.KotlinCompile /** * @author Franz Wilhelmstötter * @since 1.2 - * @version 1.2 + * @version 3.0 */ plugins { - `java-gradle-plugin` `kotlin-dsl` - } repositories { mavenLocal() gradlePluginPortal() } - -tasks.withType().configureEach { - kotlinOptions.jvmTarget = "17" -} - -configure { - sourceCompatibility = JavaVersion.VERSION_17 - targetCompatibility = JavaVersion.VERSION_17 -} diff --git a/buildSrc/lib/java2html.jar b/buildSrc/lib/java2html.jar deleted file mode 100644 index 3d813ba3001f2bdf205a85a5db11c144ef1dd6bc..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 192952 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
ky^(w_!G3O@-9TDj_pC`mdr(L16(na59 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%0AIy@c=Cw&noRz=k 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 code, -:not(h1, h2, h3, h4, h5, h6) > tt { - font-size:14px; - padding-top:4px; - margin-top:8px; - line-height:1.4em; -} -dt code { - font-family:'DejaVu Sans Mono', monospace; - font-size:14px; - padding-top:4px; -} -.summary-table dt code { - font-family:'DejaVu Sans Mono', monospace; - font-size:14px; - vertical-align:top; - padding-top:4px; -} -sup { - font-size:8px; -} -button { - font-family: 'DejaVu Sans', Arial, Helvetica, sans-serif; - font-size: 14px; -} -/* - * Styles for HTML generated by javadoc. - * - * These are style classes that are used by the standard doclet to generate HTML documentation. - */ - -/* - * Styles for document title and copyright. - */ -.clear { - clear:both; - height:0; - overflow:hidden; -} -.about-language { - float:right; - padding:0 21px 8px 8px; - font-size:11px; - margin-top:-9px; - height:2.9em; -} -.legal-copy { - margin-left:.5em; -} -.tab { - background-color:#0066FF; - color:#ffffff; - padding:8px; - width:5em; - font-weight:bold; -} -/* - * Styles for navigation bar. - */ -@media screen { - .flex-box { - position:fixed; - display:flex; - flex-direction:column; - height: 100%; - width: 100%; - } - .flex-header { - flex: 0 0 auto; - } - .flex-content { - flex: 1 1 auto; - overflow-y: auto; - } -} -.top-nav { - background-color:#4D7A97; - color:#FFFFFF; - float:left; - padding:0; - width:100%; - clear:right; - min-height:2.8em; - padding-top:10px; - overflow:hidden; - font-size:12px; -} -.sub-nav { - background-color:#dee3e9; - float:left; - width:100%; - overflow:hidden; - font-size:12px; -} -.sub-nav div { - clear:left; - float:left; - padding:0 0 5px 6px; - text-transform:uppercase; -} -.sub-nav .nav-list { - padding-top:5px; -} -ul.nav-list { - display:block; - margin:0 25px 0 0; - padding:0; -} -ul.sub-nav-list { - float:left; - margin:0 25px 0 0; - padding:0; -} -ul.nav-list li { - list-style:none; - float:left; - padding: 5px 6px; - text-transform:uppercase; -} -.sub-nav .nav-list-search { - float:right; - margin:0 0 0 0; - padding:5px 6px; - clear:none; -} -.nav-list-search label { - position:relative; - right:-16px; -} -ul.sub-nav-list li { - list-style:none; - float:left; - padding-top:10px; -} -.top-nav a:link, .top-nav a:active, .top-nav a:visited { - color:#FFFFFF; - text-decoration:none; - text-transform:uppercase; -} -.top-nav a:hover { - text-decoration:none; - color:#bb7a2a; - text-transform:uppercase; -} -.nav-bar-cell1-rev { - background-color:#F8981D; - color:#253441; - margin: auto 5px; -} -.skip-nav { - position:absolute; - top:auto; - left:-9999px; - overflow:hidden; -} -/* - * Hide navigation links and search box in print layout - */ -@media print { - ul.nav-list, div.sub-nav { - display:none; - } -} -/* - * Styles for page header and footer. - */ -.title { - color:#2c4557; - margin:10px 0; -} -.sub-title { - margin:5px 0 0 0; -} -.header ul { - margin:0 0 15px 0; - padding:0; -} -.header ul li, .footer ul li { - list-style:none; - font-size:13px; -} -/* - * Styles for headings. - */ -body.class-declaration-page .summary h2, -body.class-declaration-page .details h2, -body.class-use-page h2, -body.module-declaration-page .block-list h2 { - font-style: italic; - padding:0; - margin:15px 0; -} -body.class-declaration-page .summary h3, -body.class-declaration-page .details h3, -body.class-declaration-page .summary .inherited-list h2 { - background-color:#dee3e9; - border:1px solid #d0d9e0; - margin:0 0 6px -8px; - padding:7px 5px; -} -/* - * Styles for page layout containers. - */ -main { - clear:both; - padding:10px 20px; - position:relative; -} -dl.notes > dt { - font-family: 'DejaVu Sans', Arial, Helvetica, sans-serif; - font-size:12px; - font-weight:bold; - margin:10px 0 0 0; - color:#4E4E4E; -} -dl.notes > dd { - margin:5px 10px 10px 0; - font-size:14px; - font-family:'DejaVu Serif', Georgia, "Times New Roman", Times, serif; -} -dl.name-value > dt { - margin-left:1px; - font-size:1.1em; - display:inline; - font-weight:bold; -} -dl.name-value > dd { - margin:0 0 0 1px; - font-size:1.1em; - display:inline; -} -/* - * Styles for lists. - */ -li.circle { - list-style:circle; -} -ul.horizontal li { - display:inline; - font-size:0.9em; -} -div.inheritance { - margin:0; - padding:0; -} -div.inheritance div.inheritance { - margin-left:2em; -} -ul.block-list, -ul.details-list, -ul.member-list, -ul.summary-list { - margin:10px 0 10px 0; - padding:0; -} -ul.block-list > li, -ul.details-list > li, -ul.member-list > li, -ul.summary-list > li { - list-style:none; - margin-bottom:15px; - line-height:1.4; -} -.summary-table dl, .summary-table dl dt, .summary-table dl dd { - margin-top:0; - margin-bottom:1px; -} -ul.see-list, ul.see-list-long { - padding-left: 0; - list-style: none; -} -ul.see-list li { - display: inline; -} -ul.see-list li:not(:last-child):after, -ul.see-list-long li:not(:last-child):after { - content: ", "; - white-space: pre-wrap; -} -/* - * Styles for tables. - */ -.summary-table, .details-table { - width:100%; - border-spacing:0; - border-left:1px solid #EEE; - border-right:1px solid #EEE; - border-bottom:1px solid #EEE; - padding:0; -} -.caption { - position:relative; - text-align:left; - background-repeat:no-repeat; - color:#253441; - font-weight:bold; - clear:none; - overflow:hidden; - padding:0; - padding-top:10px; - padding-left:1px; - margin:0; - white-space:pre; -} -.caption a:link, .caption a:visited { - color:#1f389c; -} -.caption a:hover, -.caption a:active { - color:#FFFFFF; -} -.caption span { - white-space:nowrap; - padding-top:5px; - padding-left:12px; - padding-right:12px; - padding-bottom:7px; - display:inline-block; - float:left; - background-color:#F8981D; - border: none; - height:16px; -} -div.table-tabs { - padding:10px 0 0 1px; - margin:0; -} -div.table-tabs > button { - border: none; - cursor: pointer; - padding: 5px 12px 7px 12px; - font-weight: bold; - margin-right: 3px; -} -div.table-tabs > button.active-table-tab { - background: #F8981D; - color: #253441; -} -div.table-tabs > button.table-tab { - background: #4D7A97; - color: #FFFFFF; -} -.two-column-summary { - display: grid; - grid-template-columns: minmax(15%, max-content) minmax(15%, auto); -} -.three-column-summary { - display: grid; - grid-template-columns: minmax(10%, max-content) minmax(15%, max-content) minmax(15%, auto); -} -.four-column-summary { - display: grid; - grid-template-columns: minmax(10%, max-content) minmax(10%, max-content) minmax(10%, max-content) minmax(10%, auto); -} -@media screen and (max-width: 600px) { - .two-column-summary { - display: grid; - grid-template-columns: 1fr; - } -} -@media screen and (max-width: 800px) { - .three-column-summary { - display: grid; - grid-template-columns: minmax(10%, max-content) minmax(25%, auto); - } - .three-column-summary .col-last { - grid-column-end: span 2; - } -} -@media screen and (max-width: 1000px) { - .four-column-summary { - display: grid; - grid-template-columns: minmax(15%, max-content) minmax(15%, auto); - } -} -.summary-table > div, .details-table > div { - text-align:left; - padding: 8px 3px 3px 7px; -} -.col-first, .col-second, .col-last, .col-constructor-name, .col-summary-item-name { - vertical-align:top; - padding-right:0; - padding-top:8px; - padding-bottom:3px; -} -.table-header { - background:#dee3e9; - font-weight: bold; -} -.col-first, .col-first { - font-size:13px; -} -.col-second, .col-second, .col-last, .col-constructor-name, .col-summary-item-name, .col-last { - font-size:13px; -} -.col-first, .col-second, .col-constructor-name { - vertical-align:top; - overflow: auto; -} -.col-last { - white-space:normal; -} -.col-first a:link, .col-first a:visited, -.col-second a:link, .col-second a:visited, -.col-first a:link, .col-first a:visited, -.col-second a:link, .col-second a:visited, -.col-constructor-name a:link, .col-constructor-name a:visited, -.col-summary-item-name a:link, .col-summary-item-name a:visited, -.constant-values-container a:link, .constant-values-container a:visited, -.all-classes-container a:link, .all-classes-container a:visited, -.all-packages-container a:link, .all-packages-container a:visited { - font-weight:bold; -} -.table-sub-heading-color { - background-color:#EEEEFF; -} -.even-row-color, .even-row-color .table-header { - background-color:#FFFFFF; -} -.odd-row-color, .odd-row-color .table-header { - background-color:#EEEEEF; -} -/* - * Styles for contents. - */ -.deprecated-content { - margin:0; - padding:10px 0; -} -div.block { - font-size:14px; - font-family:'DejaVu Serif', Georgia, "Times New Roman", Times, serif; -} -.col-last div { - padding-top:0; -} -.col-last a { - padding-bottom:3px; -} -.module-signature, -.package-signature, -.type-signature, -.member-signature { - font-family:'DejaVu Sans Mono', monospace; - font-size:14px; - margin:14px 0; - white-space: pre-wrap; -} -.module-signature, -.package-signature, -.type-signature { - margin-top: 0; -} -.member-signature .type-parameters-long, -.member-signature .parameters, -.member-signature .exceptions { - display: inline-block; - vertical-align: top; - white-space: pre; -} -.member-signature .type-parameters { - white-space: normal; -} -/* - * Styles for formatting effect. - */ -.source-line-no { - color:green; - padding:0 30px 0 0; -} -h1.hidden { - visibility:hidden; - overflow:hidden; - font-size:10px; -} -.block { - display:block; - margin:0 10px 5px 0; - color:#474747; -} -.deprecated-label, .descfrm-type-label, .implementation-label, .member-name-label, .member-name-link, -.module-label-in-package, .module-label-in-type, .override-specify-label, .package-label-in-type, -.package-hierarchy-label, .type-name-label, .type-name-link, .search-tag-link, .preview-label { - font-weight:bold; -} -.deprecation-comment, .help-footnote, .preview-comment { - font-style:italic; -} -.deprecation-block { - font-size:14px; - font-family:'DejaVu Serif', Georgia, "Times New Roman", Times, serif; - border-style:solid; - border-width:thin; - border-radius:10px; - padding:10px; - margin-bottom:10px; - margin-right:10px; - display:inline-block; -} -.preview-block { - font-size:14px; - font-family:'DejaVu Serif', Georgia, "Times New Roman", Times, serif; - border-style:solid; - border-width:thin; - border-radius:10px; - padding:10px; - margin-bottom:10px; - margin-right:10px; - display:inline-block; -} -div.block div.deprecation-comment { - font-style:normal; -} -/* - * Styles specific to HTML5 elements. - */ -main, nav, header, footer, section { - display:block; -} -/* - * Styles for javadoc search. - */ -.ui-autocomplete-category { - font-weight:bold; - font-size:15px; - padding:7px 0 7px 3px; - background-color:#4D7A97; - color:#FFFFFF; -} -.result-item { - font-size:13px; -} -.ui-autocomplete { - max-height:85%; - max-width:65%; - overflow-y:scroll; - overflow-x:scroll; - white-space:nowrap; - box-shadow: 0 3px 6px rgba(0,0,0,0.16), 0 3px 6px rgba(0,0,0,0.23); -} -ul.ui-autocomplete { - position:fixed; - z-index:999999; -} -ul.ui-autocomplete li { - float:left; - clear:both; - width:100%; -} -.result-highlight { - font-weight:bold; -} -#search-input { - background-image:url('resources/glass.png'); - background-size:13px; - background-repeat:no-repeat; - background-position:2px 3px; - padding-left:20px; - position:relative; - right:-18px; - width:400px; -} -#reset-button { - background-color: rgb(255,255,255); - background-image:url('resources/x.png'); - background-position:center; - background-repeat:no-repeat; - background-size:12px; - border:0 none; - width:16px; - height:16px; - position:relative; - left:-4px; - top:-4px; - font-size:0px; -} -.watermark { - color:#545454; -} -.search-tag-desc-result { - font-style:italic; - font-size:11px; -} -.search-tag-holder-result { - font-style:italic; - font-size:12px; -} -.search-tag-result:target { - background-color:yellow; -} -.module-graph span { - display:none; - position:absolute; -} -.module-graph:hover span { - display:block; - margin: -100px 0 0 100px; - z-index: 1; -} -.inherited-list { - margin: 10px 0 10px 0; -} -section.class-description { - line-height: 1.4; -} -.summary section[class$="-summary"], .details section[class$="-details"], -.class-uses .detail, .serialized-class-details { - padding: 0px 20px 5px 10px; - border: 1px solid #ededed; - background-color: #f8f8f8; -} -.inherited-list, section[class$="-details"] .detail { - padding:0 0 5px 8px; - background-color:#ffffff; - border:none; -} -.vertical-separator { - padding: 0 5px; -} -ul.help-section-list { - margin: 0; -} -ul.help-subtoc > li { - display: inline-block; - padding-right: 5px; - font-size: smaller; -} -ul.help-subtoc > li::before { - content: "\2022" ; - padding-right:2px; -} -span.help-note { - font-style: italic; -} -/* - * Indicator icon for external links. - */ -main a[href*="://"]::after { - content:""; - display:inline-block; - background-image:url('data:image/svg+xml; utf8, \ - \ - \ - '); - background-size:100% 100%; - width:7px; - height:7px; - margin-left:2px; - margin-bottom:4px; -} -main a[href*="://"]:hover::after, -main a[href*="://"]:focus::after { - background-image:url('data:image/svg+xml; utf8, \ - \ - \ - '); -} - -/* - * Styles for user-provided tables. - * - * borderless: - * No borders, vertical margins, styled caption. - * This style is provided for use with existing doc comments. - * In general, borderless tables should not be used for layout purposes. - * - * plain: - * Plain borders around table and cells, vertical margins, styled caption. - * Best for small tables or for complex tables for tables with cells that span - * rows and columns, when the "striped" style does not work well. - * - * striped: - * Borders around the table and vertical borders between cells, striped rows, - * vertical margins, styled caption. - * Best for tables that have a header row, and a body containing a series of simple rows. - */ - -table.borderless, -table.plain, -table.striped { - margin-top: 10px; - margin-bottom: 10px; -} -table.borderless > caption, -table.plain > caption, -table.striped > caption { - font-weight: bold; - font-size: smaller; -} -table.borderless th, table.borderless td, -table.plain th, table.plain td, -table.striped th, table.striped td { - padding: 2px 5px; -} -table.borderless, -table.borderless > thead > tr > th, table.borderless > tbody > tr > th, table.borderless > tr > th, -table.borderless > thead > tr > td, table.borderless > tbody > tr > td, table.borderless > tr > td { - border: none; -} -table.borderless > thead > tr, table.borderless > tbody > tr, table.borderless > tr { - background-color: transparent; -} -table.plain { - border-collapse: collapse; - border: 1px solid black; -} -table.plain > thead > tr, table.plain > tbody tr, table.plain > tr { - background-color: transparent; -} -table.plain > thead > tr > th, table.plain > tbody > tr > th, table.plain > tr > th, -table.plain > thead > tr > td, table.plain > tbody > tr > td, table.plain > tr > td { - border: 1px solid black; -} -table.striped { - border-collapse: collapse; - border: 1px solid black; -} -table.striped > thead { - background-color: #E3E3E3; -} -table.striped > thead > tr > th, table.striped > thead > tr > td { - border: 1px solid black; -} -table.striped > tbody > tr:nth-child(even) { - background-color: #EEE -} -table.striped > tbody > tr:nth-child(odd) { - background-color: #FFF -} -table.striped > tbody > tr > th, table.striped > tbody > tr > td { - border-left: 1px solid black; - border-right: 1px solid black; -} -table.striped > tbody > tr > th { - font-weight: normal; -} -/** - * Tweak font sizes and paddings for small screens. - */ -@media screen and (max-width: 1050px) { - #search-input { - width: 300px; - } -} -@media screen and (max-width: 800px) { - #search-input { - width: 200px; - } - .top-nav, - .bottom-nav { - font-size: 11px; - padding-top: 6px; - } - .sub-nav { - font-size: 11px; - } - .about-language { - padding-right: 16px; - } - ul.nav-list li, - .sub-nav .nav-list-search { - padding: 6px; - } - ul.sub-nav-list li { - padding-top: 5px; - } - main { - padding: 10px; - } - .summary section[class$="-summary"], .details section[class$="-details"], - .class-uses .detail, .serialized-class-details { - padding: 0 8px 5px 8px; - } - body { - -webkit-text-size-adjust: none; - } -} -@media screen and (max-width: 500px) { - #search-input { - width: 150px; - } - .top-nav, - .bottom-nav { - font-size: 10px; - } - .sub-nav { - font-size: 10px; - } - .about-language { - font-size: 10px; - padding-right: 12px; - } -} diff --git a/buildSrc/src/main/java/io/jenetics/gradle/Colorizer.java b/buildSrc/src/main/java/io/jenetics/gradle/Colorizer.java deleted file mode 100644 index 886d7ff..0000000 --- a/buildSrc/src/main/java/io/jenetics/gradle/Colorizer.java +++ /dev/null @@ -1,365 +0,0 @@ -/* - * Facile JDBC Library (@__identifier__@). - * Copyright (c) @__year__@ Franz Wilhelmstötter - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * - * Author: - * Franz Wilhelmstötter (franz.wilhelmstoetter@gmail.com) - */ -package io.jenetics.gradle; - -import static java.lang.String.format; -import static java.nio.charset.StandardCharsets.UTF_8; -import static java.util.Objects.requireNonNull; - -import java.io.BufferedReader; -import java.io.File; -import java.io.FileInputStream; -import java.io.FileOutputStream; -import java.io.IOException; -import java.io.InputStreamReader; -import java.io.OutputStreamWriter; -import java.nio.charset.Charset; -import java.nio.file.FileVisitResult; -import java.nio.file.Files; -import java.nio.file.Path; -import java.nio.file.SimpleFileVisitor; -import java.nio.file.attribute.BasicFileAttributes; -import java.util.Set; - -/** - * @author Franz Wilhelmstötter - * @since 1.0 - * @version 6.1 - */ -public final class Colorizer extends SimpleFileVisitor { - - private static final Charset CHARSET = UTF_8; - - // Original start tag:
{@code
-	private static final String START_TAG = "
";
-
-	// Original end tag: }
- private static final String END_TAG = "
"; - - private File _baseDir; - - private int _processed = 0; - private int _modified = 0; - - public Colorizer(final File baseDir) { - _baseDir = requireNonNull(baseDir, "Base dir must not be null."); - } - - public Colorizer() { - this(new File(".")); - } - - public void setBaseDir(final File baseDir) { - _baseDir = requireNonNull(baseDir, "Base dir must not be null."); - } - - public File getBaseDir() { - return _baseDir; - } - - public int getProcessed() { - return _processed; - } - - public int getModified() { - return _modified; - } - - public void colorize() throws IOException { - Files.walkFileTree(_baseDir.toPath(), this); - } - - @Override - public FileVisitResult visitFile( - final Path file, - final BasicFileAttributes attrs - ) { - if (file.toString().endsWith(".html")) { - try { - colorize(file); - } catch (IOException e) { - System.out.println("Error while processing file: " + file); - return FileVisitResult.TERMINATE; - } - } - - return FileVisitResult.CONTINUE; - } - - private void colorize(final Path file) throws IOException { - ++_processed; - - try (FileInputStream fis = new FileInputStream(file.toFile()); - InputStreamReader isr = new InputStreamReader(fis, CHARSET); - BufferedReader in = new BufferedReader(isr)) - { - final StringBuilder out = new StringBuilder(10000); - State state = State.DATA; - boolean modified = false; - - for (int ch = in.read(); ch != -1; ch = in.read()) { - out.append((char)ch); - - if (state == State.CODE_TAG) { - modified = true; - } - - state = state.apply((char)ch, out); - } - - if (modified) { - ++_modified; - try (FileOutputStream fout = new FileOutputStream(file.toFile()); - OutputStreamWriter writer = new OutputStreamWriter(fout, CHARSET)) - { - writer.write(out.toString()); - } - } - } - } - - /** - * Represents the current 'Colorizer' state. - * - * @author Franz Wilhelmstötter - * @since 1.0 - * @version 1.4 - */ - private enum State { - - DATA { - @Override - public State apply(final char ch, final StringBuilder out) { - State state = this; - if ((ch == '>') && - (out.length() >= START_TAG.length()) && - out.substring(out.length() - START_TAG.length()) - .equalsIgnoreCase(START_TAG)) - { - out.setLength(out.length() - START_TAG.length()); - out.append("
"); - state = SKIP_NEWLINE; - } - - return state; - } - }, - - SKIP_NEWLINE { - @Override - public State apply(final char ch, final StringBuilder out) { - State state = this; - if (ch == '\n') { - out.setLength(out.length() - 1); - state = CODE_TAG; - } - return state; - } - }, - - CODE_TAG { - @Override - public State apply(final char ch, final StringBuilder out) { - State state = this; - if (Character.isJavaIdentifierPart(ch)) { - state = IDENTIFIER; - state._start = out.length() - 1; - } else if (ch == '"') { - state = STRING_LITERAL; - out.insert( - out.length() - 1, - "" - ); - } else if ((ch == '/') && (out.charAt(out.length() - 2) == '/')) { - state = COMMENT; - out.insert( - out.length() - 2, - "" - ); - } else if ((ch == '@') && - (out.charAt(out.length() - 2) == '\\') && - (out.charAt(out.length() - 3) != '\\')) - { - state = ANNOTATION; - out.deleteCharAt(out.length() - 2); - out.insert( - out.length() - 1, - "" - ); - } - - return state; - } - }, - - IDENTIFIER { - @Override - public State apply(final char ch, final StringBuilder out) { - State state = this; - if ((ch == '>') && - out.substring(out.length() - END_TAG.length()) - .equalsIgnoreCase(END_TAG)) - { - int index = out.lastIndexOf("\n"); - out.setLength(index); - out.append("
"); - state = DATA; - } else if (!Character.isJavaIdentifierPart(ch)) { - final String name = out.substring(_start, out.length() - 1); - if (IDENTIFIERS.contains(name)) { - out.insert(_start + name.length(), ""); - out.insert( - _start, - "" - ); - } - state = CODE_TAG; - } - - return state; - } - }, - - ANNOTATION { - @Override - public State apply(final char ch, final StringBuilder out) { - State state = this; - if (!Character.isJavaIdentifierPart(ch)) { - out.insert(out.length() - 1, ""); - state = CODE_TAG; - } - return state; - } - }, - - STRING_LITERAL { - @Override - public State apply(final char ch, final StringBuilder out) { - State state = this; - if ((ch == '"') && (out.charAt(out.length() - 2) != '\\')) { - out.append(""); - state = CODE_TAG; - } - return state; - } - }, - - COMMENT { - @Override - public State apply(final char ch, final StringBuilder out) { - State state = this; - if ((ch == '\n') || (ch == '\r')) { - out.insert(out.length() - 1, ""); - state = CODE_TAG; - } - return state; - } - }; - - int _start = -1; - - public abstract State apply(final char read, final StringBuilder doc); - - private static final String ANNOTATION_COLOR = "#808080"; - private static final String KEYWORD_COLOR = "#7F0055"; - private static final String COMMENT_COLOR = "#3F7F5F"; - private static final String STRING_COLOR = "#0000FF"; - - private static final Set IDENTIFIERS = Set.of( - "abstract", - "assert", - "boolean", - "break", - "byte", - "case", - "catch", - "char", - "class", - "const", - "continue", - "default", - "do", - "double", - "else", - "enum", - "extends", - "final", - "finally", - "float", - "for", - "goto", - "if", - "implements", - "import", - "instanceof", - "int", - "interface", - "long", - "native", - "null", - "new", - "package", - "private", - "protected", - "public", - "record", - "return", - "short", - "static", - "strictfp", - "super", - "switch", - "synchronized", - "this", - "throw", - "throws", - "transient", - "try", - "var", - "void", - "volatile", - "while" - ); - } - - - public static void main(final String[] args) { - final File dir = new File(args[0]); - if (!dir.isDirectory()) { - System.err.println(args[0] + " is not a directory."); - System.exit(1); - } - - try { - final Colorizer colorizer = new Colorizer(dir); - colorizer.colorize(); - - System.out.println(format( - "Colorizer processed %d files and modified %d.", - colorizer.getProcessed(), - colorizer.getModified() - )); - } catch (IOException e) { - System.err.println("Error while processing files: " + e); - System.exit(1); - } - } - -} diff --git a/buildSrc/src/main/java/io/jenetics/gradle/ColorizerTask.java b/buildSrc/src/main/java/io/jenetics/gradle/ColorizerTask.java deleted file mode 100644 index 4465d61..0000000 --- a/buildSrc/src/main/java/io/jenetics/gradle/ColorizerTask.java +++ /dev/null @@ -1,63 +0,0 @@ -/* - * Facile JDBC Library (@__identifier__@). - * Copyright (c) @__year__@ Franz Wilhelmstötter - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * - * Author: - * Franz Wilhelmstötter (franz.wilhelmstoetter@gmail.com) - */ -package io.jenetics.gradle; - -import java.io.File; -import java.io.IOException; - -import org.gradle.api.DefaultTask; -import org.gradle.api.tasks.InputFile; -import org.gradle.api.tasks.TaskAction; -import org.gradle.api.tasks.TaskExecutionException; - -/** - * @author Franz Wilhelmstötter - * @since 1.4 - * @version 6.1 - */ -public class ColorizerTask extends DefaultTask { - - private File _directory; - - @InputFile - public File getDirectory() { - return _directory; - } - - public void setDirectory(final File directory) { - _directory = directory; - } - - @TaskAction - public void colorize() { - try { - final Colorizer colorizer = new Colorizer(_directory); - colorizer.colorize(); - - getLogger().lifecycle( - "Colorizer processed {} files and modified {}.", - colorizer.getProcessed(), colorizer.getModified() - ); - } catch (final IOException e) { - throw new TaskExecutionException(this, e); - } - } - -} diff --git a/buildSrc/src/main/java/io/jenetics/gradle/package-info.java b/buildSrc/src/main/java/io/jenetics/gradle/package-info.java deleted file mode 100644 index 6fb14f1..0000000 --- a/buildSrc/src/main/java/io/jenetics/gradle/package-info.java +++ /dev/null @@ -1,26 +0,0 @@ -/* - * Java Genetic Algorithm Library (@__identifier__@). - * Copyright (c) @__year__@ Franz Wilhelmstötter - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * - * Author: - * Franz Wilhelmstötter (franz.wilhelmstoetter@gmail.com) - */ - -/** - * @author Franz Wilhelmstötter - * @since 1.4 - * @version 1.4 - */ -package io.jenetics.gradle; diff --git a/facilejdbc/build.gradle.kts b/facilejdbc/build.gradle.kts index 7500039..e683e5d 100644 --- a/facilejdbc/build.gradle.kts +++ b/facilejdbc/build.gradle.kts @@ -25,8 +25,8 @@ */ plugins { + java `java-library` - idea `maven-publish` } @@ -35,8 +35,8 @@ description = "FacileJDBC Library" extra["moduleName"] = "io.jenetics.facilejdbc" dependencies { - testImplementation(libs.testng) - testImplementation(libs.assertj) + testImplementation(libs.assertj.core) testImplementation(libs.hsqldb) testImplementation(libs.javafaker) + testImplementation(libs.testng) } diff --git a/gradle.properties b/gradle.properties new file mode 100644 index 0000000..78bf12f --- /dev/null +++ b/gradle.properties @@ -0,0 +1 @@ +facilejdbc.version = 3.0.0-SNAPSHOT diff --git a/gradle/libs.versions.toml b/gradle/libs.versions.toml index 2dcc5d8..6c5f28b 100644 --- a/gradle/libs.versions.toml +++ b/gradle/libs.versions.toml @@ -1,15 +1,82 @@ -[plugins] +[versions] +assertj = "3.27.3" +codemodel = "4.0.5" +commons-csv = "1.14.1" +commons-math4-legacy = "4.0-beta1" +commons-numbers-combinatorics = "1.2" +commons-numbers-core = "1.2" +commons-numbers-gamma = "1.2" +commons-numbers-rootfinder = "1.2" +commons-rng-sampling = "1.6" +commons-rng-simple = "1.6" +commons-statistics-descriptive = "1.1" +commons-statistics-distribution = "1.1" +equalsverifier = "4.0.7" +guava = "33.4.8-jre" +jackson = "2.19.2" +jackson-databind-nullable = "0.2.6" +jackson-datatype-jsr310 = "2.19.2" +jacoco-agent = "0.8.13" +jakarta-annotation-api = "3.0.0" +jakarta-validation-api = "3.1.1" +javacsv = "2.0" +jexl = "3.5.0" +jmh = "0.7.3" +jpx = "3.2.1" +mvel = "2.5.2.Final" +nashorn = "15.6" +openapi-generator = "7.14.0" +opencsv = "5.12.0" +prngine = "2.0.0" +reactor-core = "3.7.8" +rxjava = "2.2.21" +supercsv = "2.4.0" +swagger-models = "2.2.35" +swagger-parser = "2.1.31" +testng = "7.11.0" +javafaker = "1.0.2" +version-catalog-update = "1.0.0" +hsqldb = "2.7.2" -jmh = { id = "me.champeau.jmh", version = "0.7.2" } +[plugins] +jmh = { id = "me.champeau.jmh", version.ref = "jmh" } +openapi-generator = { id = "org.openapi.generator", version.ref = "openapi-generator" } +version-catalog-update = { id = "nl.littlerobots.version-catalog-update", version.ref = "version-catalog-update" } [libraries] - -assertj = "org.assertj:assertj-core:3.24.2" -commons-math = "org.apache.commons:commons-math3:3.6.1" -equalsverifier = "nl.jqno.equalsverifier:equalsverifier:3.15.3" -guava = "com.google.guava:guava:32.1.3-jre" -hsqldb = "org.hsqldb:hsqldb:2.7.2" -javafaker = "com.github.javafaker:javafaker:1.0.2" -prngine = "io.jenetics:prngine:2.0.0" -rxjava = "io.reactivex.rxjava2:rxjava:2.2.21" -testng = "org.testng:testng:7.8.0" +assertj-core = { module = "org.assertj:assertj-core", version.ref = "assertj" } +codemodel = { module = "org.glassfish.jaxb:codemodel", version.ref = "codemodel" } +commons-csv = { module = "org.apache.commons:commons-csv", version.ref = "commons-csv" } +commons-math4-legacy = { module = "org.apache.commons:commons-math4-legacy", version.ref = "commons-math4-legacy" } +commons-numbers-combinatorics = { module = "org.apache.commons:commons-numbers-combinatorics", version.ref = "commons-numbers-combinatorics" } +commons-numbers-core = { module = "org.apache.commons:commons-numbers-core", version.ref = "commons-numbers-core" } +commons-numbers-gamma = { module = "org.apache.commons:commons-numbers-gamma", version.ref = "commons-numbers-gamma" } +commons-numbers-rootfinder = { module = "org.apache.commons:commons-numbers-rootfinder", version.ref = "commons-numbers-rootfinder" } +commons-rng-sampling = { module = "org.apache.commons:commons-rng-sampling", version.ref = "commons-rng-sampling" } +commons-rng-simple = { module = "org.apache.commons:commons-rng-simple", version.ref = "commons-rng-simple" } +commons-statistics-descriptive = { module = "org.apache.commons:commons-statistics-descriptive", version.ref = "commons-statistics-descriptive" } +commons-statistics-distribution = { module = "org.apache.commons:commons-statistics-distribution", version.ref = "commons-statistics-distribution" } +equalsverifier = { module = "nl.jqno.equalsverifier:equalsverifier", version.ref = "equalsverifier" } +guava = { module = "com.google.guava:guava", version.ref = "guava" } +jackson-annotations = { module = "com.fasterxml.jackson.core:jackson-annotations", version.ref = "jackson" } +jackson-databind = { module = "com.fasterxml.jackson.core:jackson-databind", version.ref = "jackson" } +jackson-databind-nullable = { module = "org.openapitools:jackson-databind-nullable", version.ref = "jackson-databind-nullable" } +jackson-datatype-jsr310 = { module = "com.fasterxml.jackson.datatype:jackson-datatype-jsr310", version.ref = "jackson-datatype-jsr310" } +jacoco-agent = { module = "org.jacoco:org.jacoco.agent", version.ref = "jacoco-agent" } +jakarta-annotation-api = { module = "jakarta.annotation:jakarta.annotation-api", version.ref = "jakarta-annotation-api" } +jakarta-validation-api = { module = "jakarta.validation:jakarta.validation-api", version.ref = "jakarta-validation-api" } +javacsv = { module = "net.sourceforge.javacsv:javacsv", version.ref = "javacsv" } +jexl = { module = "org.apache.commons:commons-jexl3", version.ref = "jexl" } +jpx = { module = "io.jenetics:jpx", version.ref = "jpx" } +mvel = { module = "org.mvel:mvel2", version.ref = "mvel" } +nashorn-core = { module = "org.openjdk.nashorn:nashorn-core", version.ref = "nashorn" } +opencsv = { module = "com.opencsv:opencsv", version.ref = "opencsv" } +prngine = { module = "io.jenetics:prngine", version.ref = "prngine" } +reactor-core = { module = "io.projectreactor:reactor-core", version.ref = "reactor-core" } +rxjava = { module = "io.reactivex.rxjava2:rxjava", version.ref = "rxjava" } +supercsv = { module = "net.sf.supercsv:super-csv", version.ref = "supercsv" } +swagger-models = { module = "io.swagger.core.v3:swagger-models", version.ref = "swagger-models" } +swagger-parser = { module = "io.swagger.parser.v3:swagger-parser", version.ref = "swagger-parser" } +testng = { module = "org.testng:testng", version.ref = "testng" } +hsqldb = { module = "org.hsqldb:hsqldb", version.ref = "hsqldb" } +javafaker = { module = "com.github.javafaker:javafaker", version.ref = "javafaker" } \ No newline at end of file diff --git a/gradle/wrapper/gradle-wrapper.properties b/gradle/wrapper/gradle-wrapper.properties index 8838ba9..6514f91 100644 --- a/gradle/wrapper/gradle-wrapper.properties +++ b/gradle/wrapper/gradle-wrapper.properties @@ -1,6 +1,6 @@ distributionBase=GRADLE_USER_HOME distributionPath=wrapper/dists -distributionUrl=https\://services.gradle.org/distributions/gradle-8.4-all.zip +distributionUrl=https\://services.gradle.org/distributions/gradle-8.14-all.zip networkTimeout=10000 validateDistributionUrl=true zipStoreBase=GRADLE_USER_HOME diff --git a/gradlew b/gradlew index 1b6c787..1aa94a4 100755 --- a/gradlew +++ b/gradlew @@ -55,7 +55,7 @@ # Darwin, MinGW, and NonStop. # # (3) This script is generated from the Groovy template -# https://github.com/gradle/gradle/blob/master/subprojects/plugins/src/main/resources/org/gradle/api/internal/plugins/unixStartScript.txt +# https://github.com/gradle/gradle/blob/HEAD/subprojects/plugins/src/main/resources/org/gradle/api/internal/plugins/unixStartScript.txt # within the Gradle project. # # You can find Gradle at https://github.com/gradle/gradle/. @@ -80,13 +80,11 @@ do esac done -APP_HOME=$( cd "${APP_HOME:-./}" && pwd -P ) || exit - -APP_NAME="Gradle" +# This is normally unused +# shellcheck disable=SC2034 APP_BASE_NAME=${0##*/} - -# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. -DEFAULT_JVM_OPTS='"-Xmx64m" "-Xms64m"' +# Discard cd standard output in case $CDPATH is set (https://github.com/gradle/gradle/issues/25036) +APP_HOME=$( cd "${APP_HOME:-./}" > /dev/null && pwd -P ) || exit # Use the maximum available, or set MAX_FD != -1 to use that value. MAX_FD=maximum @@ -133,22 +131,29 @@ location of your Java installation." fi else JAVACMD=java - which java >/dev/null 2>&1 || die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. + if ! command -v java >/dev/null 2>&1 + then + die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. Please set the JAVA_HOME variable in your environment to match the location of your Java installation." + fi fi # Increase the maximum file descriptors if we can. if ! "$cygwin" && ! "$darwin" && ! "$nonstop" ; then case $MAX_FD in #( max*) + # In POSIX sh, ulimit -H is undefined. That's why the result is checked to see if it worked. + # shellcheck disable=SC2039,SC3045 MAX_FD=$( ulimit -H -n ) || warn "Could not query maximum file descriptor limit" esac case $MAX_FD in #( '' | soft) :;; #( *) + # In POSIX sh, ulimit -n is undefined. That's why the result is checked to see if it worked. + # shellcheck disable=SC2039,SC3045 ulimit -n "$MAX_FD" || warn "Could not set maximum file descriptor limit to $MAX_FD" esac @@ -193,11 +198,15 @@ if "$cygwin" || "$msys" ; then done fi -# Collect all arguments for the java command; -# * $DEFAULT_JVM_OPTS, $JAVA_OPTS, and $GRADLE_OPTS can contain fragments of -# shell script including quotes and variable substitutions, so put them in -# double quotes to make sure that they get re-expanded; and -# * put everything else in single quotes, so that it's not re-expanded. + +# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. +DEFAULT_JVM_OPTS='"-Xmx64m" "-Xms64m"' + +# Collect all arguments for the java command: +# * DEFAULT_JVM_OPTS, JAVA_OPTS, JAVA_OPTS, and optsEnvironmentVar are not allowed to contain shell fragments, +# and any embedded shellness will be escaped. +# * For example: A user cannot expect ${Hostname} to be expanded, as it is an environment variable and will be +# treated as '${Hostname}' itself on the command line. set -- \ "-Dorg.gradle.appname=$APP_BASE_NAME" \ @@ -205,6 +214,12 @@ set -- \ org.gradle.wrapper.GradleWrapperMain \ "$@" +# Stop when "xargs" is not available. +if ! command -v xargs >/dev/null 2>&1 +then + die "xargs is not available" +fi + # Use "xargs" to parse quoted args. # # With -n1 it outputs one arg per line, with the quotes and backslashes removed. diff --git a/gradlew.bat b/gradlew.bat index ac1b06f..6689b85 100644 --- a/gradlew.bat +++ b/gradlew.bat @@ -14,7 +14,7 @@ @rem limitations under the License. @rem -@if "%DEBUG%" == "" @echo off +@if "%DEBUG%"=="" @echo off @rem ########################################################################## @rem @rem Gradle startup script for Windows @@ -25,7 +25,8 @@ if "%OS%"=="Windows_NT" setlocal set DIRNAME=%~dp0 -if "%DIRNAME%" == "" set DIRNAME=. +if "%DIRNAME%"=="" set DIRNAME=. +@rem This is normally unused set APP_BASE_NAME=%~n0 set APP_HOME=%DIRNAME% @@ -40,7 +41,7 @@ if defined JAVA_HOME goto findJavaFromJavaHome set JAVA_EXE=java.exe %JAVA_EXE% -version >NUL 2>&1 -if "%ERRORLEVEL%" == "0" goto execute +if %ERRORLEVEL% equ 0 goto execute echo. echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. @@ -75,13 +76,15 @@ set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar :end @rem End local scope for the variables with windows NT shell -if "%ERRORLEVEL%"=="0" goto mainEnd +if %ERRORLEVEL% equ 0 goto mainEnd :fail rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of rem the _cmd.exe /c_ return code! -if not "" == "%GRADLE_EXIT_CONSOLE%" exit 1 -exit /b 1 +set EXIT_CODE=%ERRORLEVEL% +if %EXIT_CODE% equ 0 set EXIT_CODE=1 +if not ""=="%GRADLE_EXIT_CONSOLE%" exit %EXIT_CODE% +exit /b %EXIT_CODE% :mainEnd if "%OS%"=="Windows_NT" endlocal From 166832fbc2883c3ae2f513a42e8262ec37199209 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Franz=20Wilhelmst=C3=B6tter?= Date: Mon, 4 Aug 2025 21:11:05 +0200 Subject: [PATCH 04/14] Update gradle.yml #61: Update build pipeline --- .github/workflows/gradle.yml | 19 ++++++++++++------- 1 file changed, 12 insertions(+), 7 deletions(-) diff --git a/.github/workflows/gradle.yml b/.github/workflows/gradle.yml index c408714..70101fc 100644 --- a/.github/workflows/gradle.yml +++ b/.github/workflows/gradle.yml @@ -13,14 +13,19 @@ on: jobs: build: - runs-on: ubuntu-latest + runs-on: ${{ matrix.os }} + strategy: + matrix: + os: [ ubuntu-latest, macos-latest ] + java-version: [ 21, 24 ] steps: - - uses: actions/checkout@v2 + - uses: actions/checkout@v4 - - name: Set up JDK 17 - uses: actions/setup-java@v2 + - name: Set up JDK ${{ matrix.java-version }} on ${{ matrix.os }} + uses: actions/setup-java@v4 with: - java-version: '17' - distribution: 'adopt' + java-version: ${{ matrix.java-version }} + distribution: 'zulu' + cache: 'gradle' - name: Build with Gradle - run: ./gradlew build + run: ./gradlew build --stacktrace --info From 3da3786152ad4f8a1a423a4498083e25f81c40a3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Franz=20Wilhelmst=C3=B6tter?= Date: Mon, 4 Aug 2025 21:12:46 +0200 Subject: [PATCH 05/14] #61: Update build scripts. MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Franz Wilhelmstötter --- build.gradle.kts | 2 +- buildSrc/build.gradle.kts | 2 -- 2 files changed, 1 insertion(+), 3 deletions(-) diff --git a/build.gradle.kts b/build.gradle.kts index dd91b92..9535504 100644 --- a/build.gradle.kts +++ b/build.gradle.kts @@ -1,5 +1,5 @@ /* - * Java Genetic Algorithm Library (@__identifier__@). + * Facile JDBC Library (@__identifier__@). * Copyright (c) @__year__@ Franz Wilhelmstötter * * Licensed under the Apache License, Version 2.0 (the "License"); diff --git a/buildSrc/build.gradle.kts b/buildSrc/build.gradle.kts index d2eb006..b9c3d70 100644 --- a/buildSrc/build.gradle.kts +++ b/buildSrc/build.gradle.kts @@ -1,5 +1,3 @@ -import org.jetbrains.kotlin.gradle.tasks.KotlinCompile - /* * Facile JDBC Library (@__identifier__@). * Copyright (c) @__year__@ Franz Wilhelmstötter From cdedaa0f19f30bf5da40da4b4e9ba68aac92c028 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Franz=20Wilhelmst=C3=B6tter?= Date: Mon, 4 Aug 2025 21:15:22 +0200 Subject: [PATCH 06/14] #61: Fix compiler warning. MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Franz Wilhelmstötter --- facilejdbc/src/main/java/io/jenetics/facilejdbc/Lifecycle.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/facilejdbc/src/main/java/io/jenetics/facilejdbc/Lifecycle.java b/facilejdbc/src/main/java/io/jenetics/facilejdbc/Lifecycle.java index cd921c6..e8f732b 100644 --- a/facilejdbc/src/main/java/io/jenetics/facilejdbc/Lifecycle.java +++ b/facilejdbc/src/main/java/io/jenetics/facilejdbc/Lifecycle.java @@ -579,7 +579,7 @@ static Throwable invokeAll0( } else { try { method.accept(object); - } catch (VirtualMachineError|ThreadDeath|LinkageError e) { + } catch (VirtualMachineError|LinkageError e) { throw e; } catch (Throwable e) { error = e; From dad41e01331f84d1f1d194cdb286286cc5b7161f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Franz=20Wilhelmst=C3=B6tter?= Date: Mon, 4 Aug 2025 21:19:14 +0200 Subject: [PATCH 07/14] #61: Simplify build MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Franz Wilhelmstötter --- build.gradle.kts | 3 +-- buildSrc/src/main/kotlin/Env.kt | 1 - 2 files changed, 1 insertion(+), 3 deletions(-) diff --git a/build.gradle.kts b/build.gradle.kts index 9535504..09bbd89 100644 --- a/build.gradle.kts +++ b/build.gradle.kts @@ -32,7 +32,6 @@ plugins { rootProject.version = providers.gradleProperty("facilejdbc.version").get() - tasks.named("wrapper") { gradleVersion = "8.14" distributionType = Wrapper.DistributionType.ALL @@ -43,7 +42,7 @@ tasks.named("wrapper") { */ allprojects { group = FacileJDBC.GROUP - version = FacileJDBC.VERSION + version = rootProject.version repositories { flatDir { diff --git a/buildSrc/src/main/kotlin/Env.kt b/buildSrc/src/main/kotlin/Env.kt index 1a2d691..5154568 100644 --- a/buildSrc/src/main/kotlin/Env.kt +++ b/buildSrc/src/main/kotlin/Env.kt @@ -52,7 +52,6 @@ object Env { * Information about the library and author. */ object FacileJDBC { - const val VERSION = "3.0.0-SNAPSHOT" const val ID = "facilejdbc" const val NAME = "facilejdbc" const val GROUP = "io.jenetics" From 05a4b7ab063deeb2a582143f7e063771b4f84dcf Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Franz=20Wilhelmst=C3=B6tter?= Date: Mon, 4 Aug 2025 21:28:05 +0200 Subject: [PATCH 08/14] #61: Upgrade dependencies. MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Franz Wilhelmstötter --- build.gradle.kts | 1 + gradle/libs.versions.toml | 8 ++++---- 2 files changed, 5 insertions(+), 4 deletions(-) diff --git a/build.gradle.kts b/build.gradle.kts index 09bbd89..7ed93a5 100644 --- a/build.gradle.kts +++ b/build.gradle.kts @@ -27,6 +27,7 @@ import org.apache.tools.ant.filters.ReplaceTokens */ plugins { base + alias(libs.plugins.version.catalog.update) alias(libs.plugins.jmh) } diff --git a/gradle/libs.versions.toml b/gradle/libs.versions.toml index 6c5f28b..ba5e240 100644 --- a/gradle/libs.versions.toml +++ b/gradle/libs.versions.toml @@ -13,6 +13,7 @@ commons-statistics-descriptive = "1.1" commons-statistics-distribution = "1.1" equalsverifier = "4.0.7" guava = "33.4.8-jre" +hsqldb = "2.7.4" jackson = "2.19.2" jackson-databind-nullable = "0.2.6" jackson-datatype-jsr310 = "2.19.2" @@ -20,6 +21,7 @@ jacoco-agent = "0.8.13" jakarta-annotation-api = "3.0.0" jakarta-validation-api = "3.1.1" javacsv = "2.0" +javafaker = "1.0.2" jexl = "3.5.0" jmh = "0.7.3" jpx = "3.2.1" @@ -34,9 +36,7 @@ supercsv = "2.4.0" swagger-models = "2.2.35" swagger-parser = "2.1.31" testng = "7.11.0" -javafaker = "1.0.2" version-catalog-update = "1.0.0" -hsqldb = "2.7.2" [plugins] jmh = { id = "me.champeau.jmh", version.ref = "jmh" } @@ -58,6 +58,7 @@ commons-statistics-descriptive = { module = "org.apache.commons:commons-statisti commons-statistics-distribution = { module = "org.apache.commons:commons-statistics-distribution", version.ref = "commons-statistics-distribution" } equalsverifier = { module = "nl.jqno.equalsverifier:equalsverifier", version.ref = "equalsverifier" } guava = { module = "com.google.guava:guava", version.ref = "guava" } +hsqldb = { module = "org.hsqldb:hsqldb", version.ref = "hsqldb" } jackson-annotations = { module = "com.fasterxml.jackson.core:jackson-annotations", version.ref = "jackson" } jackson-databind = { module = "com.fasterxml.jackson.core:jackson-databind", version.ref = "jackson" } jackson-databind-nullable = { module = "org.openapitools:jackson-databind-nullable", version.ref = "jackson-databind-nullable" } @@ -66,6 +67,7 @@ jacoco-agent = { module = "org.jacoco:org.jacoco.agent", version.ref = "jacoco-a jakarta-annotation-api = { module = "jakarta.annotation:jakarta.annotation-api", version.ref = "jakarta-annotation-api" } jakarta-validation-api = { module = "jakarta.validation:jakarta.validation-api", version.ref = "jakarta-validation-api" } javacsv = { module = "net.sourceforge.javacsv:javacsv", version.ref = "javacsv" } +javafaker = { module = "com.github.javafaker:javafaker", version.ref = "javafaker" } jexl = { module = "org.apache.commons:commons-jexl3", version.ref = "jexl" } jpx = { module = "io.jenetics:jpx", version.ref = "jpx" } mvel = { module = "org.mvel:mvel2", version.ref = "mvel" } @@ -78,5 +80,3 @@ supercsv = { module = "net.sf.supercsv:super-csv", version.ref = "supercsv" } swagger-models = { module = "io.swagger.core.v3:swagger-models", version.ref = "swagger-models" } swagger-parser = { module = "io.swagger.parser.v3:swagger-parser", version.ref = "swagger-parser" } testng = { module = "org.testng:testng", version.ref = "testng" } -hsqldb = { module = "org.hsqldb:hsqldb", version.ref = "hsqldb" } -javafaker = { module = "com.github.javafaker:javafaker", version.ref = "javafaker" } \ No newline at end of file From b22a4e5860da62dd880cb0ea4bec2cf0fb241398 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Franz=20Wilhelmst=C3=B6tter?= Date: Mon, 4 Aug 2025 21:34:10 +0200 Subject: [PATCH 09/14] #61: Simplify build MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Franz Wilhelmstötter --- build.gradle.kts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/build.gradle.kts b/build.gradle.kts index 7ed93a5..75fbd90 100644 --- a/build.gradle.kts +++ b/build.gradle.kts @@ -309,9 +309,9 @@ fun setupPublishing(project: Project) { repositories { maven { url = if (version.toString().endsWith("SNAPSHOT")) - uri(layout.buildDirectory.dir("repos/releases")) - else uri(layout.buildDirectory.dir("repos/snapshots")) + else + uri(layout.buildDirectory.dir("repos/releases")) } } From 72bc6a2acc93fad38cef8123693d0cee3a67af9f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Franz=20Wilhelmst=C3=B6tter?= Date: Mon, 4 Aug 2025 22:09:51 +0200 Subject: [PATCH 10/14] #58: Convert examples to code snippets. MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Franz Wilhelmstötter --- .../java/io/jenetics/facilejdbc/Batch.java | 9 ++-- .../java/io/jenetics/facilejdbc/Dctor.java | 13 +++-- .../io/jenetics/facilejdbc/Lifecycle.java | 25 ++++----- .../io/jenetics/facilejdbc/MultiParam.java | 5 +- .../java/io/jenetics/facilejdbc/Param.java | 38 ++++++------- .../java/io/jenetics/facilejdbc/Query.java | 32 +++++------ .../java/io/jenetics/facilejdbc/Records.java | 49 ++++++++--------- .../jenetics/facilejdbc/ResultSetParser.java | 10 ++-- .../io/jenetics/facilejdbc/RowParser.java | 54 ++++++++----------- .../io/jenetics/facilejdbc/SingleParam.java | 5 +- .../main/java/io/jenetics/facilejdbc/Sql.java | 9 ++-- .../io/jenetics/facilejdbc/Transaction.java | 37 ++++++------- .../io/jenetics/facilejdbc/Transactional.java | 49 ++++++++--------- .../facilejdbc/function/SqlSupplier.java | 1 - .../facilejdbc/spi/SqlTypeMapper.java | 26 ++++----- 15 files changed, 157 insertions(+), 205 deletions(-) diff --git a/facilejdbc/src/main/java/io/jenetics/facilejdbc/Batch.java b/facilejdbc/src/main/java/io/jenetics/facilejdbc/Batch.java index a735e47..76638ee 100644 --- a/facilejdbc/src/main/java/io/jenetics/facilejdbc/Batch.java +++ b/facilejdbc/src/main/java/io/jenetics/facilejdbc/Batch.java @@ -32,12 +32,11 @@ * essentially an {@link Iterable} of records or row-creation functions. The * available factory functions make it easy to create a batch from a given * list of records or parameters. - * - *
{@code
- * final List persons = ...;
- * final Dctor dctor = ...;
+ * {@snippet lang="java":
+ * final List persons = null; // @replace substring='null' replacement="..."
+ * final Dctor dctor = null; // @replace substring='null' replacement="..."
  * final Batch batch = Batch.of(persons, dctor);
- * }
+ * } * * @author Franz Wilhelmstötter * @version 1.0 diff --git a/facilejdbc/src/main/java/io/jenetics/facilejdbc/Dctor.java b/facilejdbc/src/main/java/io/jenetics/facilejdbc/Dctor.java index 408cf97..0df4c22 100644 --- a/facilejdbc/src/main/java/io/jenetics/facilejdbc/Dctor.java +++ b/facilejdbc/src/main/java/io/jenetics/facilejdbc/Dctor.java @@ -38,19 +38,19 @@ * This interface is responsible for deconstructing a given record, of * type {@code T}, to a DB-row ({@link ParamValues}). * - *
{@code
+ * {@snippet lang="java":
  * final Dctor dctor = Dctor.of(
  *     Dctor.field("title", Book::title),
  *     Dctor.field("isbn", Book::isbn),
  *     Dctor.field("published_at", Book::publishedAt),
  *     Dctor.field("pages", Book::pages)
  * );
- * }
+ * } * * If the {@code Book} class is a record, you can just write - *
{@code
+ * {@snippet lang="java":
  * final Dctor dctor = Dctor.of(Book.class);
- * }
+ * } * * @apiNote * A {@code Dctor} (deconstructor) is responsible for splitting a given record @@ -199,8 +199,7 @@ static Dctor of(final Field... fields) { /** * Create a new deconstructor for the given record type. - * - *
{@code
+	 * {@snippet lang="java":
 	 * // Matching column names, with book columns:
 	 * // [title, author, isbn, pages, published_at]
 	 * final Dctor dctor = Dctor.of(Book.class);
@@ -219,7 +218,7 @@ static  Dctor of(final Field... fields) {
 	 *     field("pages", book -> book.pages()*3),
 	 *     field("title_hash", book -> book.title().hashCode())
 	 * );
-	 * }
+ * } * * @see Records#dctor(Class, Field[]) * diff --git a/facilejdbc/src/main/java/io/jenetics/facilejdbc/Lifecycle.java b/facilejdbc/src/main/java/io/jenetics/facilejdbc/Lifecycle.java index e8f732b..a3c223c 100644 --- a/facilejdbc/src/main/java/io/jenetics/facilejdbc/Lifecycle.java +++ b/facilejdbc/src/main/java/io/jenetics/facilejdbc/Lifecycle.java @@ -232,8 +232,7 @@ default void silentClose(final Throwable previousError) { * interface but needs some cleanup work to do after usage. In the following * example the created {@code file} is automatically deleted when leaving the * {@code try} block. - * - *
{@code
+	 * {@snippet lang="java":
 	 * // Create the closeable file.
 	 * final Value file = Value.of(
 	 *     Files.createFile(Path.of("some_file")),
@@ -246,7 +245,7 @@ default void silentClose(final Throwable previousError) {
 	 *     final var writtenText = Files.readString(file.get());
 	 *     assert "foo".equals(writtenText);
 	 * }
-	 * }
+ * } * * @see #of(Object, ThrowingConsumer) * @see #build(ThrowingFunction) @@ -290,8 +289,7 @@ public String toString() { * released, by calling the defined release method. The typical * use case for this method is when additional initialization of the * value is needed. - * - *
{@code
+		 * {@snippet lang="java":
 		 * final var file = CloseableValue.of(
 		 *     Files.createFile(Path.of("some_file")),
 		 *     Files::deleteIfExists
@@ -303,7 +301,7 @@ public String toString() {
 		 * try (file) {
 		 *     // Do something with temp file.
 		 * }
-		 * }
+ * } * * @param the exception type * @param block the codec block which is applied to the value @@ -352,8 +350,7 @@ public static Value of( * in the case of an error. If the value could be created, the * caller is responsible for closing the opened resources by * calling the {@link Value#close()} method. - * - *
{@code
+		 * {@snippet lang="java":
 		 * final Value, IOException> result = Value.build(resources -> {
 		 *     final var fin = resources.add(new FileInputStream(file.toFile()), Closeable::close);
 		 *     final var bin = resources.add(new BufferedInputStream(fin), Closeable::close);
@@ -366,7 +363,7 @@ public static  Value of(
 		 * try (result) {
 		 *     result.get().forEach(System.out::println);
 		 * }
-		 * }
+ * } * * @see Resources * @@ -414,8 +411,7 @@ public static Value of( * Using the {@code Resources} class can simplify the creation of * dependent input streams, where it might be otherwise necessary to create * nested {@code try-with-resources} blocks. - * - *
{@code
+	 * {@snippet lang="java":
 	 * try (var resources = new Resources()) {
 	 *     final var fin = resources.add(new FileInputStream(file), Closeable::close);
 	 *     if (fin.read() != -1) {
@@ -424,7 +420,7 @@ public static  Value of(
 	 *     final var oin = resources.add(new ObjectInputStream(fin), Closeable::close);
 	 *     // ...
 	 * }
-	 * }
+ * } * * @see Value#build(ThrowingFunction) * @@ -509,15 +505,14 @@ private Lifecycle() { * of the method invocations throws an exception. The first exception thrown * is rethrown after invoking the method on the remaining objects, all other * exceptions are swallowed. - * - *
{@code
+	 * {@snippet lang="java":
 	 * final var streams = new ArrayList();
 	 * streams.add(new FileInputStream(file1));
 	 * streams.add(new FileInputStream(file2));
 	 * streams.add(new FileInputStream(file3));
 	 * // ...
 	 * invokeAll(Closeable::close, streams);
-	 * }
+ * } * * @param the closeable object type * @param the exception type diff --git a/facilejdbc/src/main/java/io/jenetics/facilejdbc/MultiParam.java b/facilejdbc/src/main/java/io/jenetics/facilejdbc/MultiParam.java index 937bf80..5fc3ec2 100644 --- a/facilejdbc/src/main/java/io/jenetics/facilejdbc/MultiParam.java +++ b/facilejdbc/src/main/java/io/jenetics/facilejdbc/MultiParam.java @@ -28,10 +28,9 @@ * Represents a query parameter with name and one or more values. * The parameter values are evaluated lazily. But it is also possible to create * {@code MultiParam} objects with eagerly evaluated values. - * - *
{@code
+ * {@snippet lang="java":
  * SELECT_QUERY.on(Param.values("ids", 1, 2, 3, 4))
- * }
+ * } * * @see SingleParam * @see SingleParam#values(String, Iterable) diff --git a/facilejdbc/src/main/java/io/jenetics/facilejdbc/Param.java b/facilejdbc/src/main/java/io/jenetics/facilejdbc/Param.java index 8a5a8ed..b1dc2b9 100644 --- a/facilejdbc/src/main/java/io/jenetics/facilejdbc/Param.java +++ b/facilejdbc/src/main/java/io/jenetics/facilejdbc/Param.java @@ -34,18 +34,18 @@ * class. *

* Creating single-valued parameters: - *

{@code
+ * {@snippet lang="java":
  * INSERT_QUERY.on(
  *     Param.value("forename", "Werner"),
  *     Param.value("birthday", LocalDate.now()),
  *     Param.value("email", "some.email@gmail.com"))
- * }
+ * } * * Creating multivalued parameters: - *
{@code
+ * {@snippet lang="java":
  * Query.of("SELECT * FROM table WHERE id = IN(:ids);")
  *     .on(Param.values("ids", 1, 2, 3, 4))
- * }
+ * } * * @see SingleParam * @see MultiParam @@ -70,12 +70,11 @@ public sealed interface Param permits SingleParam, MultiParam { /** * Create a new query parameter object for the given {@code name} and * {@code value}. - * - *
{@code
+	 * {@snippet lang="java":
 	 * final var result = Query.of("SELECT * FROM table WHERE id = :id;")
 	 *     .on(Param.value("id", 43245)
 	 *     .as(PARSER.singleOpt(), conn);
-	 * }
+ * } * * @param name the parameter name * @param value the parameter values, which may be {@code null} @@ -93,12 +92,11 @@ static SingleParam value(final String name, final Object value) { /** * Create a new (multi) query parameter object for the given {@code name} * and the given {@code values}. - * - *
{@code
+	 * {@snippet lang="java":
 	 * final var result = Query.of("SELECT * FROM table WHERE id = IN(:ids);")
 	 *     .on(Param.values("ids", List.of(43245, 434, 23, 987, 1239))
 	 *     .as(PARSER.list(), conn);
-	 * }
+ * } * * @since 1.3 * @@ -130,12 +128,11 @@ private static Stream stream(final Iterable values) { /** * Create a new (multi) query parameter object for the given {@code name} * and the given {@code values}. - * - *
{@code
+	 * {@snippet lang="java":
 	 * final var result = Query.of("SELECT * FROM table WHERE id = IN(:ids);")
 	 *     .on(Param.values("ids", 43245, 434, 23, 987, 1239)
 	 *     .as(PARSER.list(), conn);
-	 * }
+ * } * * @since 1.3 * @@ -155,12 +152,11 @@ static MultiParam values(final String name, final Object... values) { /** * Create a new query parameter object from the given {@code name} and * lazily evaluated {@code value}. - * - *
{@code
+	 * {@snippet lang="java":
 	 * final var result = Query.of("SELECT * FROM table WHERE date < :date;")
 	 *     .on(Param.lazyValue("date", LocalDate::now)
 	 *     .as(PARSER.singleOpt(), conn);
-	 * }
+ * } * * @param name the parameter name * @param value the lazily evaluated parameter value @@ -178,14 +174,13 @@ static SingleParam lazyValue(final String name, final SqlSupplier value) { /** * Create a new query parameter object for the given {@code name} and * lazily evaluated {@code values}. - * - *
{@code
+	 * {@snippet lang="java":
 	 * final SqlSupplier id1 = ...;
 	 * final SqlSupplier id2 = ...;
 	 * final var result = Query.of("SELECT * FROM table WHERE id = IN(:ids);")
 	 *     .on(Param.lazyValues("id", List.of(id1, id2))
 	 *     .as(PARSER.list(), conn);
-	 * }
+ * } * * @param name the parameter name * @param values the parameter values @@ -209,12 +204,11 @@ static MultiParam lazyValues( /** * Create a new query parameter object for the given {@code name} and * lazily evaluated {@code values}. - * - *
{@code
+	 * {@snippet lang="java":
 	 * final var result = Query.of("SELECT * FROM table WHERE id = IN(:ids);")
 	 *     .on(Param.lazyValues("id", () -> 324, () -> 9967))
 	 *     .as(PARSER.list(), conn);
-	 * }
+ * } * * @param name the parameter name * @param values the parameter values diff --git a/facilejdbc/src/main/java/io/jenetics/facilejdbc/Query.java b/facilejdbc/src/main/java/io/jenetics/facilejdbc/Query.java index 7d29386..c7c2d7f 100644 --- a/facilejdbc/src/main/java/io/jenetics/facilejdbc/Query.java +++ b/facilejdbc/src/main/java/io/jenetics/facilejdbc/Query.java @@ -52,8 +52,7 @@ /** * A {@code Query} represents an executable piece of SQL text. - * - *
{@code
+ * {@snippet lang="java":
  * private static final Query SELECT = Query.of("""
  *     SELECT * FROM person
  *     WHERE forename like :forename
@@ -66,7 +65,7 @@
  *     VALUES(:forename, :surname, :birthday, :email);
  *     """
  * );
- * }
+ * } * * @apiNote * This class is immutable and thread-safe. @@ -111,11 +110,11 @@ public String sql() { /** * Return the original SQL string, this object is created with. So the * following assertion holds for every possible SQL string; - *
{@code
+	 * {@snippet lang="java":
 	 * final String sql = "SELECT * FROM table WHERE id = :id;";
 	 * final Query query = Query.of(sql);
 	 * assert sql.equals(query.rawSql());
-	 * }
+ * } * * @since 1.1 * @@ -209,12 +208,11 @@ public Query withTimeout(final Duration timeout) { /** * Return a new query object with the given query parameter values. - * - *
{@code
+	 * {@snippet lang="java":
 	 * final var result = Query.of("SELECT * FROM table WHERE id = :id;")
-	 *     .on(List.of(Param.value("id", 43245))
+	 *     .on(List.of(Param.value("id", 43245)))
 	 *     .as(PARSER.singleOpt(), conn);
-	 * }
+ * } * * @see #on(Param...) * @see #on(Map) @@ -279,12 +277,11 @@ private static Stream toParams(final MultiParam param) { /** * Return a new query object with the given query parameter values. - * - *
{@code
+	 * {@snippet lang="java":
 	 * final var result = Query.of("SELECT * FROM table WHERE id = :id;")
-	 *     .on(Param.value("id", 43245)
+	 *     .on(Param.value("id", 43245))
 	 *     .as(PARSER.singleOpt(), conn);
-	 * }
+ * } * * @param params the query parameters * @return a new query object with the set parameters @@ -298,12 +295,11 @@ public Query on(final Param... params) { /** * Return a new query object with the given query parameter values. - * - *
{@code
+	 * {@snippet lang="java":
 	 * final var result = Query.of("SELECT * FROM table WHERE id = :id;")
 	 *     .on(Map.of("id", 43245))
 	 *     .as(PARSER.singleOpt(), conn);
-	 * }
+ * } * * @param params the query parameters * @return a new query object with the set parameters @@ -624,7 +620,7 @@ public String toString() { /** * Create a new query object from the given SQL string. - *
{@code
+	 * {@snippet lang="java":
 	 * private static final Query SELECT = Query.of("""
 	 *     SELECT * FROM person
 	 *     WHERE forename like :forename
@@ -637,7 +633,7 @@ public String toString() {
 	 *     VALUES(:forename, :surname, :birthday, :email);
 	 *     """
 	 * );
-	 * }
+ * } * * @param sql the SQL string of the created query * @return a new query object from the given SQL string diff --git a/facilejdbc/src/main/java/io/jenetics/facilejdbc/Records.java b/facilejdbc/src/main/java/io/jenetics/facilejdbc/Records.java index 8c927c2..331003c 100644 --- a/facilejdbc/src/main/java/io/jenetics/facilejdbc/Records.java +++ b/facilejdbc/src/main/java/io/jenetics/facilejdbc/Records.java @@ -41,7 +41,7 @@ * snake_case) correspond to column names of the table. *

* Creating a {@link Dctor} from a given record type: - *

{@code
+ * {@snippet lang="java":
  * // The book record.
  * record Book(
  *     String title,
@@ -54,7 +54,7 @@
  * // Matching column names, with book columns:
  * // [title, author, isbn, pages, published_at]
  * final Dctor dctor = Records.dctor(Book.class);
- * }
+ * } * * @author
Franz Wilhelmstötter * @version 2.0 @@ -71,8 +71,7 @@ private Records() { /** * Create a new deconstructor for the given record type. This method gives * you the greatest flexibility - * - *
{@code
+	 * {@snippet lang="java":
 	 * // Handling additional columns and different column names, with book columns:
 	 * // [title, primary_author, isbn13, pages, published_at, title_hash]
 	 * final Dctor dctor = Records.dctor(
@@ -91,7 +90,7 @@ private Records() {
 	 *         field("title_hash", book -> book.title().hashCode())
 	 *     )
 	 * );
-	 * }
+ * } * * @see #dctor(Class, Function, Dctor.Field[]) * @@ -153,8 +152,7 @@ private static Dctor.Field toFiled( /** * Create a new deconstructor for the given record type. This method gives * you the greatest flexibility - * - *
{@code
+	 * {@snippet lang="java":
 	 * // Handling additional columns and different column names, with book columns:
 	 * // [title, primary_author, isbn13, pages, published_at, title_hash]
 	 * final Dctor dctor = Records.dctor(
@@ -171,7 +169,7 @@ private static  Dctor.Field toFiled(
 	 *     // Define an additional column and it's value.
 	 *     field("title_hash", book -> book.title().hashCode())
 	 * );
-	 * }
+ * } * * @see #dctor(Class, Function, List) * @@ -198,8 +196,7 @@ public static Dctor dctor( /** * Create a new deconstructor for the given record type. - * - *
{@code
+	 * {@snippet lang="java":
 	 * // Matching column names, with book columns:
 	 * // [title, author, isbn, pages, published_at]
 	 * final Dctor dctor = Records.dctor(Book.class);
@@ -218,7 +215,7 @@ public static  Dctor dctor(
 	 *     field("pages", book -> book.pages()*3),
 	 *     field("title_hash", book -> book.title().hashCode())
 	 * );
-	 * }
+ * } * * @see #dctor(Class, Function, List) * @see #dctor(Class, Function, Dctor.Field[]) @@ -318,7 +315,7 @@ public static String toSnakeCase(final String name) { * Creates a {@link RowParser} for the given record {@code type}. This * method gives you the greatest flexibility in creating row-parser * instances. - *
{@code
+	 * {@snippet lang="java":
 	 * // Handling different column names and column types:
 	 * // [title, primary_author, isbn, pages, published_at]
 	 * final RowParser parser = Records.parser(
@@ -335,7 +332,7 @@ public static String toSnakeCase(final String name) {
 	 *         default -> null;
 	 *     }
 	 * );
-	 * }
+ * } * * @param type the record type * @param toColumnName function for mapping the record component to the @@ -384,7 +381,7 @@ public static RowParser parser( * Creates a {@link RowParser} for the given record {@code type}. This * method gives you the greatest flexibility in creating row-parser * instances. - *
{@code
+	 * {@snippet lang="java":
 	 * // Handling different column names and column types:
 	 * // [title, primary_author, isbn, pages, published_at]
 	 * final RowParser parser = Records.parser(
@@ -392,7 +389,7 @@ public static  RowParser parser(
 	 *     Map.of("author", "primary_author"),
 	 *     Map.of("isbn", RowParser.string("isbn").map(Isbn::new))
 	 * );
-	 * }
+ * } * * @see #parser(Class, Function, Function) * @@ -422,7 +419,7 @@ public static RowParser parser( /** * Creates a {@link RowParser} for the given record {@code type} and an * additional record-component to column name mapping. - *
{@code
+	 * {@snippet lang="java":
 	 * // Handling different column names and column types:
 	 * // [title, primary_author, isbn, pages, published_at]
 	 * final RowParser parser = Records.parserWithColumnNames(
@@ -433,7 +430,7 @@ public static  RowParser parser(
 	 *         default -> Records.toSnakeCase(component);
 	 *     }
 	 * );
-	 * }
+ * } * * @see #parserWithColumnNames(Class, Map) * @@ -454,14 +451,14 @@ public static RowParser parserWithColumnNames( /** * Creates a {@link RowParser} for the given record {@code type} and an * additional record-component name to column name mapping. - *
{@code
+	 * {@snippet lang="java":
 	 * // Handling different column names and column types:
 	 * // [title, primary_author, isbn, pages, published_at]
 	 * final RowParser parser = Records.parserWithColumnNames(
 	 *     Book.class,
 	 *     Map.of("author", "primary_author")
 	 * );
-	 * }
+ * } * * @see #parserWithColumnNames(Class, Function) * @@ -482,7 +479,7 @@ public static RowParser parserWithColumnNames( /** * Creates a {@link RowParser} for the given record {@code type} and an * additional record-component to column mapping. - *
{@code
+	 * {@snippet lang="java":
 	 * // Handling different column names and column types:
 	 * // [title, author, isbn, pages, published_at]
 	 * final RowParser parser = Records.parserWithFields(
@@ -494,7 +491,7 @@ public static  RowParser parserWithColumnNames(
 	 *         default -> null;
 	 *     }
 	 * );
-	 * }
+ * } * * @see #parserWithFields(Class, Map) * @@ -514,14 +511,14 @@ public static RowParser parserWithFields( /** * Creates a {@link RowParser} for the given record {@code type} and an * additional record-component name to column mapping. - *
{@code
+	 * {@snippet lang="java":
 	 * // Handling different column names and column types:
 	 * // [title, author, isbn, pages, published_at]
 	 * final RowParser parser = Records.parserWithFields(
 	 *     Book.class,
 	 *     Map.of("isbn", RowParser.string("isbn").map(Isbn::new))
 	 * );
-	 * }
+ * } * * @see #parserWithFields(Class, Function) * @@ -540,13 +537,13 @@ public static RowParser parserWithFields( /** * Creates a {@link RowParser} for the given record {@code type}. - *
{@code
+	 * {@snippet lang="java":
 	 * // Handling different column names and column types:
 	 * // [title, author, isbn, pages, published_at]
 	 * final RowParser parser = Records.parser(Book.class);
-	 * }
+ * } * - * @see RowParser#of(Class) + * @see RowParser#record(Class) * * @param type the record type * @param the record type diff --git a/facilejdbc/src/main/java/io/jenetics/facilejdbc/ResultSetParser.java b/facilejdbc/src/main/java/io/jenetics/facilejdbc/ResultSetParser.java index 91b5d36..87a125c 100644 --- a/facilejdbc/src/main/java/io/jenetics/facilejdbc/ResultSetParser.java +++ b/facilejdbc/src/main/java/io/jenetics/facilejdbc/ResultSetParser.java @@ -27,8 +27,7 @@ * This interface is responsible for parsing a {@link ResultSet} to a record of * type {@code T}. The intended way for creating a result-set parser is via an * existing {@link RowParser}. - * - *
{@code
+ * {@snippet lang="java":
  * final RowParser parser = (row, conn) -> new Person(
  *     row.getString("name"),
  *     row.getString("email"),
@@ -38,7 +37,7 @@
  * final ResultSetParser rsp1 = parser.single();
  * final ResultSetParser> rsp2 = parser.singleOpt();
  * final ResultSetParser> rsp3 = parser.list();
- * }
+ * } * * @see RowParser * @@ -69,12 +68,11 @@ T parse(final ResultSet rs, final Connection conn) /** * Return a {@link ResultSet} parser, which converts the query result to a * CSV line. - * - *
{@code
+	 * {@snippet lang="java":
 	 * final var select = Query.of("SELECT * FROM book;");
 	 * final var csv = select.as(ResultSetParser.csvLine(), conn);
 	 * System.out.println(csv);
-	 * }
+ * } * The CSV output will look like this: *
 	 * "ID","PUBLISHED_AT","TITLE","ISBN","PAGES"
diff --git a/facilejdbc/src/main/java/io/jenetics/facilejdbc/RowParser.java b/facilejdbc/src/main/java/io/jenetics/facilejdbc/RowParser.java
index f8e7b98..94022b9 100644
--- a/facilejdbc/src/main/java/io/jenetics/facilejdbc/RowParser.java
+++ b/facilejdbc/src/main/java/io/jenetics/facilejdbc/RowParser.java
@@ -52,22 +52,21 @@
 /**
  * Converts one row from the given {@link ResultSet} into a data object from
  * the given type.
- *
- * 
{@code
+ * {@snippet lang="java":
  * final RowParser parser = (row, conn) -> new Person(
  *     row.getString("name"),
  *     row.getString("email"),
  *     row.getString("link")
  * );
- * }
+ * } *

* If you are using records as entity objects, the creation of * row-parser instances is even simpler. - *

{@code
+ * {@snippet lang="java":
  * // Handling different column names and column types:
  * // [title, author, isbn, pages, published_at]
- * final RowParser parser = RowParser.of(Book.class);
- * }
+ * final RowParser parser = RowParser.record(Book.class); + * } * * @see ResultSetParser * @see Dctor @@ -138,15 +137,14 @@ public interface RowParser { * Returns a parser that will apply the given {@code mapper} to the result * of {@code this} first parser, which will then be used for parsing the * final result. This allows combining existing row parsers. - * - *
{@code
+	 * {@snippet lang="java":
 	 * static final RowParser PARSER =
 	 * RowParser.string("title").flatMap(title ->
 	 *     RowParser.string("isbn").flatMap(isbn ->
 	 *         RowParser.int32("pages").map(pages -> new Book(title, isbn, pages))
 	 *     )
 	 * );
-	 * }
+ * } * * @since 1.3 * @@ -361,13 +359,12 @@ default ResultSetParser> unmodifiableSet() { * closes the underlying {@link ResultSet} and {@link java.sql.Statement}. * While consuming the result {@link Stream}, possible {@link SQLException}s * are wrapped into {@link UncheckedSQLException}s. - * - *
{@code
+	 * {@snippet lang="java":
 	 * final var select = Query.of("SELECT * FROM book;");
 	 * try (var stream = select.as(PARSER.stream(), conn)) {
-	 *     stream.forEach(book -> ...);
+	 *     stream.forEach(book -> null); // @replace substring='null' replacement="..."
+	 * }
 	 * }
-	 * }
* * @see UncheckedSQLException * @@ -464,12 +461,11 @@ static RowParser compose( /** * Returns a parser for a scalar not-null value. - * - *
{@code
+	 * {@snippet lang="java":
 	 * final String name = Query.of("SELECT name FROM person WHERE id = :id")
 	 *     .on(value("id", 23))
 	 *     .as(scalar(String.class).single(), conn);
-	 * }
+ * } * * @see #scalar(int, Class) * @see #scalar(String, Class) @@ -485,12 +481,11 @@ static RowParser scalar(final Class type) { /** * Returns a parser for a scalar not-null value. - * - *
{@code
+	 * {@snippet lang="java":
 	 * final String name = Query.of("SELECT id, name FROM person WHERE id = :id")
 	 *     .on(value("id", 23))
 	 *     .as(scalar(2, String.class).single(), conn);
-	 * }
+ * } * * @since 1.3 * @@ -509,12 +504,11 @@ static RowParser scalar(final int index, final Class type) { /** * Returns a parser for a scalar not-null value. - * - *
{@code
+	 * {@snippet lang="java":
 	 * final String name = Query.of("SELECT id, name FROM person WHERE id = :id")
 	 *     .on(value("id", 23))
 	 *     .as(scalar("name", String.class).single(), conn);
-	 * }
+ * } * * @since 1.3 * @@ -821,8 +815,7 @@ static RowParser date(final int index) { * Return a row parser which converts a DB row into a CSV row. This parser * can be used for exporting a huge amount of data into a file. The * following example shows how to stream a DB result into a file. - * - *
{@code
+	 * {@snippet lang="java":
 	 * final var select = Query.of("SELECT * FROM book ORDER BY id;");
 	 * try (var lines = select.as(RowParser.csvLine().stream(), conn);
 	 *     var out = Files.newBufferedWriter(Path.of("out.csv")))
@@ -836,7 +829,7 @@ static RowParser date(final int index) {
 	 *         }
 	 *     });
 	 * }
-	 * }
+ * } * * The rows are written without a CSV header and will look like this: *
@@ -883,11 +876,11 @@ static RowParser csvLine() {
 
 	/**
 	 * Creates a {@link RowParser} for the given record {@code type}.
-	 * 
{@code
+	 * {@snippet lang="java":
 	 * // Handling different column names and column types:
 	 * // [title, author, isbn, pages, published_at]
-	 * final RowParser parser = RowParser.of(Book.class);
-	 * }
+ * final RowParser parser = RowParser.record(Book.class); + * } * * @see Records#parser(Class) * @@ -904,12 +897,11 @@ static RowParser of(final Class type) { /** * Returns a parser for the given record {@code type}. - * - *
{@code
+	 * {@snippet lang="java":
 	 * final Book book = Query.of("SELECT * FROM book WHERE id = :id")
 	 *     .on(value("id", 23))
 	 *     .as(record(Book.class).singleNull(), conn);
-	 * }
+ * } * * @since 2.1 * diff --git a/facilejdbc/src/main/java/io/jenetics/facilejdbc/SingleParam.java b/facilejdbc/src/main/java/io/jenetics/facilejdbc/SingleParam.java index 7713f55..4a92f18 100644 --- a/facilejdbc/src/main/java/io/jenetics/facilejdbc/SingleParam.java +++ b/facilejdbc/src/main/java/io/jenetics/facilejdbc/SingleParam.java @@ -27,13 +27,12 @@ * Represents a query parameter with name and value. The * parameter value is evaluated lazily. But it is also possible to create * {@code Param} objects with eagerly evaluated values. - * - *
{@code
+ * {@snippet lang="java":
  * INSERT_QUERY.on(
  *     Param.value("forename", "Werner"),
  *     Param.value("birthday", LocalDate.now()),
  *     Param.value("email", "some.email@gmail.com"))
- * }
+ * } * * @author Franz Wilhelmstötter * @version 2.0 diff --git a/facilejdbc/src/main/java/io/jenetics/facilejdbc/Sql.java b/facilejdbc/src/main/java/io/jenetics/facilejdbc/Sql.java index 57b7973..ace0a2a 100644 --- a/facilejdbc/src/main/java/io/jenetics/facilejdbc/Sql.java +++ b/facilejdbc/src/main/java/io/jenetics/facilejdbc/Sql.java @@ -43,8 +43,7 @@ * the SQL string, respectively finds the query parameters. A query parameter * starts with a colon ':' and contains of one or more Word-Character, as * defined by \W ([a-zA-Z_0-9]) in the Regex syntax. - * - *
{@code
+ * {@snippet lang="java":
  * private static final Sql SELECT = Sql.of("""
  *     SELECT * FROM person
  *     WHERE forename like :forename
@@ -57,7 +56,7 @@
  *     VALUES(:forename, :surname, :birthday, :email);
  *     """
  * );
- * }
+ * } * * @see Query * @@ -98,11 +97,11 @@ String string() { /** * Return the original SQL string, this object is created with. So the * following assertion holds for every possible SQL string; - *
{@code
+	 * {@snippet lang="java":
 	 * final String query = "SELECT * FROM table WHERE id = :id;";
 	 * final Sql sql = Sql.of(query);
 	 * assert query.equals(sql.sql());
-	 * }
+ * } * * @since 1.1 * diff --git a/facilejdbc/src/main/java/io/jenetics/facilejdbc/Transaction.java b/facilejdbc/src/main/java/io/jenetics/facilejdbc/Transaction.java index a7d0c92..657f5fe 100644 --- a/facilejdbc/src/main/java/io/jenetics/facilejdbc/Transaction.java +++ b/facilejdbc/src/main/java/io/jenetics/facilejdbc/Transaction.java @@ -31,15 +31,14 @@ /** * This interface defines methods for executing an SQL query in a transactional * context. - * - *
{@code
- * final Transaction transaction = ...;
+ * {@snippet lang="java":
+ * final Transaction transaction = null; // @replace substring='null' replacement="..."
  * final Optional id = transaction.apply(conn ->
  *     Query.of("SELECT id FROM author WHERE name = :name")
- *         .on(value("name", "Hemingway"))
- *         .as(RowParser.int64("id").singleOpt(), conn);
+ *         .on(Param.value("name", "Hemingway"))
+ *         .as(RowParser.int64("id").singleOpt(), conn)
  * );
- * }
+ * } * * All queries within the {@code apply} block are executed within the same * transaction. If any exception is thrown within this block, a rollback on the @@ -56,14 +55,13 @@ public interface Transaction { /** * Executes the given {@code block} with a DB connection. - * - *
{@code
+	 * {@snippet lang="java":
 	 * final Optional id = apply(conn ->
 	 *     Query.of("SELECT id FROM author WHERE name = :name")
 	 *         .on(value("name", "Hemingway"))
-	 *         .as(RowParser.int64("id").singleOpt(), conn);
+	 *         .as(RowParser.int64("id").singleOpt(), conn)
 	 * );
-	 * }
+ * } * * @param block the SQL function which is executed within a DB transaction * @param the returned data type @@ -76,14 +74,13 @@ T apply(final SqlFunction block) /** * Executes the given {@code block} with a DB connection. - * - *
{@code
+	 * {@snippet lang="java":
 	 * accept(conn ->
 	 *     Query.of("SELECT id FROM author WHERE name = :name")
-	 *         .on(value("name", "Hemingway"))
-	 *         .as(RowParser.int64("id").singleOpt(), conn);
+	 *         .on(Param.value("name", "Hemingway"))
+	 *         .as(RowParser.int64("id").singleOpt(), conn)
 	 * );
-	 * }
+ * } * * @param block the SQL function which is executed within a DB transaction * @throws SQLException it the execution of the SQL block fails. In this @@ -107,16 +104,16 @@ default void accept(final SqlConsumer block) * exception is then propagated to the caller. * * - *
{@code
-	 * final DataSource ds = ...;
+	 * {@snippet lang="java":
+	 * final DataSource ds = null;  // @replace substring='null' replacement="..."
 	 * try (var conn = ds.getConnection()) {
 	 *     return Transaction.txm(conn, () ->
 	 *         Query.of("SELECT id FROM author WHERE name = :name")
-	 *             .on(value("name", "Hemingway"))
-	 *             .as(RowParser.int64("id").singleOpt(), conn);
+	 *             .on(Param.value("name", "Hemingway"))
+	 *             .as(RowParser.int64("id").singleOpt(), conn)
 	 *     );
 	 * }
-	 * }
+ * } * * @apiNote * This method implements the transactional default behavior of the diff --git a/facilejdbc/src/main/java/io/jenetics/facilejdbc/Transactional.java b/facilejdbc/src/main/java/io/jenetics/facilejdbc/Transactional.java index c49bb76..3b5373a 100644 --- a/facilejdbc/src/main/java/io/jenetics/facilejdbc/Transactional.java +++ b/facilejdbc/src/main/java/io/jenetics/facilejdbc/Transactional.java @@ -32,30 +32,27 @@ * exposed by a database. In this sense, it can be seen as a minimal database * interface, just by exposing a {@link Connection} factory method, * {@link #connection()}. - * - *
{@code
+ * {@snippet lang="java":
  * final Transactional db = () -> DriverManager.getConnection(
  *     "jdbc:hsqldb:mem:testdb",
  *     "SA",
  *     ""
  * );
- * }
+ * } * * The code example shows how easy it is to create an in-memory HSQLDB * {@code Transactional} instance. If you already have a * {@link javax.sql.DataSource} instance, the creation of a transactional * object is even easier. - * - *
{@code
- * final DataSource ds = ...;
+ * {@snippet lang="java":
+ * final DataSource ds = null; // @replace substring='null' replacement="..."
  * final Transactional db = ds::getConnection;
- * }
+ * } * * If you want to implement a different transaction strategy, you have also to * implement the {@link #txm(Connection, SqlSupplier)} method of {@code this} * interface. - * - *
{@code
+ * {@snippet lang="java":
  * final var db = new Transactional() {
  *     public Connection connection() throws SQLException {
  *         return DriverManager.getConnection(
@@ -68,27 +65,25 @@
  *         throws SQLException
  *     {
  *         // Implement your transaction handling.
- *         return ...;
+ *         return null; // @replace substring='null' replacement="..."
  *     }
  * };
- * }
+ * } * * * The usage of the db is then also very straight forward. - * - *
{@code
+ * {@snippet lang="java":
  * final long id = db.transaction().apply(conn ->
  *     INSERT_QUERY
  *         .on(author, DCTOR)
  *         .executeInsert(conn)
  *         .orElseThrow()
  * );
- * }
+ * } * * Using a transaction for batch update. - * - *
{@code
- * db.transaction().accept(conn ->
+ * {@snippet lang="java":
+ * db.transaction().accept(conn -> {
  *     final Batch batch = Batch.of(
  *         authors,
  *         Dctor.of(
@@ -98,8 +93,8 @@
  *     );
  *
  *     INSERT_BOOK_AUTHOR.executeUpdate(batch, conn);
- * );
- * }
+ * }); + * } * * @apiNote * The transactional default behavior @@ -117,14 +112,13 @@ public interface Transactional { * Return the DB connection. If you get a new connection, you are * responsible for closing it after usage. This is done ideally in a * resource-try block. - * - *
{@code
-	 * final Transactional db = ...;
+	 * {@snippet lang="java":
+	 * final Transactional db = null; // @replace substring='null' replacement="..."
 	 * try (var conn = db.connection()) {
 	 *     // Using the connection.
-	 *     ...;
+	 *     // ...
+	 * }
 	 * }
-	 * }
* * You are usually using the {@link #transaction()} method for getting an * instance of the {@link Transaction} interface, which is then using this @@ -142,16 +136,15 @@ public interface Transactional { * needed for executing a query, from the {@link #connection()} factory * method. The transactional behavior is defined by the * {@link #txm(Connection, SqlSupplier)} method of {@code this} interface. - * - *
{@code
-	 * final Transaction db = ...;
+	 * {@snippet lang="java":
+	 * final Transaction db = null; // @replace substring='null' replacement="..."
 	 * final long id = db.transaction().apply(conn ->
 	 *     INSERT_QUERY
 	 *         .on(author, DCTOR)
 	 *         .executeInsert(conn)
 	 *         .orElseThrow()
 	 * );
-	 * }
+ * } * * @implNote * It is possible to store the {@code Transaction} instance, returned by diff --git a/facilejdbc/src/main/java/io/jenetics/facilejdbc/function/SqlSupplier.java b/facilejdbc/src/main/java/io/jenetics/facilejdbc/function/SqlSupplier.java index f160137..6313670 100644 --- a/facilejdbc/src/main/java/io/jenetics/facilejdbc/function/SqlSupplier.java +++ b/facilejdbc/src/main/java/io/jenetics/facilejdbc/function/SqlSupplier.java @@ -24,7 +24,6 @@ /** * Represents a supplier of results. There is no requirement that a new or * distinct result be returned each time the supplier is invoked. - * * This is a functional interface whose functional method is {@link #get()}. * * @param the result type diff --git a/facilejdbc/src/main/java/io/jenetics/facilejdbc/spi/SqlTypeMapper.java b/facilejdbc/src/main/java/io/jenetics/facilejdbc/spi/SqlTypeMapper.java index a9de073..064681f 100644 --- a/facilejdbc/src/main/java/io/jenetics/facilejdbc/spi/SqlTypeMapper.java +++ b/facilejdbc/src/main/java/io/jenetics/facilejdbc/spi/SqlTypeMapper.java @@ -24,48 +24,44 @@ * proper type of the used DB. This may lead to a more readable insertion code. * Usually, it is not possible to insert an {@code URI} field directly into the * DB. You have to convert it into a string object first. - *
{@code
- * public static final class Person {
- *     private final String name;
- *     private final URI link;
- * }
+ * {@snippet lang="java":
+ * public record Person(String name, URI link) {}
  *
  * static final Dctor DCTOR = Dctor.of(
  *     field("name", Person::name),
  *     field("email", p -> p.link().toString())
  * );
- * }
+ * } * * If a mapper for the {@code URI} class is defined, it is possible to write the * deconstructor more concise. - *
{@code
+ * {@snippet lang="java":
  * static final Dctor DCTOR = Dctor.of(
  *     field("name", Person::name),
  *     field("email", Person::link)
  * );
- * }
+ * } * * The implementation of such a mapping is quite simple and will look like showed * in the following code snippet. - *
{@code
+ * {@snippet lang="java":
  * public class MyTypeMapper extends SqlTypeMapper {
  *     public Object convert(final Object value) {
  *         if (value instanceof URI) return value.toString();
  *         return value;
  *     }
  * }
- * }
+ * } * * Add the following line - *
{@code
+ * {@snippet lang="java":
  * org.foobar.MyTypeMapper
- * }
+ * } * * to the service definition file - * - *
{@code
+ * {@snippet lang="java":
  * META-INF/services/io.jenetics.facilejdbc.spi.SqlTypeMapper
- * }
+ * } * * and you are done. * From ed99bcc54f5c18f70769737a5cf1ec374c4b1de4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Franz=20Wilhelmst=C3=B6tter?= Date: Mon, 4 Aug 2025 22:18:05 +0200 Subject: [PATCH 11/14] #64: Remove deprecated API. MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Franz Wilhelmstötter --- .../io/jenetics/facilejdbc/RowParser.java | 23 ------------------- 1 file changed, 23 deletions(-) diff --git a/facilejdbc/src/main/java/io/jenetics/facilejdbc/RowParser.java b/facilejdbc/src/main/java/io/jenetics/facilejdbc/RowParser.java index 94022b9..46a88c9 100644 --- a/facilejdbc/src/main/java/io/jenetics/facilejdbc/RowParser.java +++ b/facilejdbc/src/main/java/io/jenetics/facilejdbc/RowParser.java @@ -31,7 +31,6 @@ import java.time.Instant; import java.time.LocalDate; import java.util.ArrayList; -import java.util.Arrays; import java.util.Collection; import java.util.HashSet; import java.util.List; @@ -41,7 +40,6 @@ import java.util.Spliterator; import java.util.function.BiFunction; import java.util.function.Function; -import java.util.function.IntFunction; import java.util.function.Supplier; import java.util.stream.Stream; import java.util.stream.StreamSupport; @@ -874,27 +872,6 @@ static RowParser csvLine() { }; } - /** - * Creates a {@link RowParser} for the given record {@code type}. - * {@snippet lang="java": - * // Handling different column names and column types: - * // [title, author, isbn, pages, published_at] - * final RowParser parser = RowParser.record(Book.class); - * } - * - * @see Records#parser(Class) - * - * @param type the record type - * @param the record type - * @return a new row-parser for the given record {@code type} - * @throws NullPointerException if one of the arguments is {@code null} - * @deprecated Use {@link #record(Class)} instead - */ - @Deprecated(since = "2.1", forRemoval = true) - static RowParser of(final Class type) { - return Records.parser(type); - } - /** * Returns a parser for the given record {@code type}. * {@snippet lang="java": From dfcbcfcebe6ac606c664dd0a5c4a1a519bb856c7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Franz=20Wilhelmst=C3=B6tter?= Date: Mon, 4 Aug 2025 22:58:29 +0200 Subject: [PATCH 12/14] Code improvements. MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Franz Wilhelmstötter --- .../java/io/jenetics/facilejdbc/Param.java | 72 +++++++++++++------ .../java/io/jenetics/facilejdbc/Query.java | 21 ++---- 2 files changed, 57 insertions(+), 36 deletions(-) diff --git a/facilejdbc/src/main/java/io/jenetics/facilejdbc/Param.java b/facilejdbc/src/main/java/io/jenetics/facilejdbc/Param.java index b1dc2b9..eb52cfe 100644 --- a/facilejdbc/src/main/java/io/jenetics/facilejdbc/Param.java +++ b/facilejdbc/src/main/java/io/jenetics/facilejdbc/Param.java @@ -33,18 +33,26 @@ * This is the base interface of the {@link SingleParam} and {@link MultiParam} * class. *

- * Creating single-valued parameters: + * Creating single-valued parameters * {@snippet lang="java": * INSERT_QUERY.on( * Param.value("forename", "Werner"), * Param.value("birthday", LocalDate.now()), - * Param.value("email", "some.email@gmail.com")) + * Param.value("email", "some.email@gmail.com") + * ); * } - * - * Creating multivalued parameters: + *

+ * Creating multi-valued parameters * {@snippet lang="java": - * Query.of("SELECT * FROM table WHERE id = IN(:ids);") + * var query = Query.of("SELECT * FROM table WHERE id = IN(:ids);") * .on(Param.values("ids", 1, 2, 3, 4)) + * + * assert query.rawSql().equals( + * "SELECT * FROM book WHERE id IN(:ids[0],:ids[1],:ids[2],:ids[3]);" + * ); + * assert query.sql().equals( + * "SELECT * FROM book WHERE id IN(?,?,?,?);" + * ); * } * * @see SingleParam @@ -72,7 +80,7 @@ public sealed interface Param permits SingleParam, MultiParam { * {@code value}. * {@snippet lang="java": * final var result = Query.of("SELECT * FROM table WHERE id = :id;") - * .on(Param.value("id", 43245) + * .on(Param.value("id", 43245)) * .as(PARSER.singleOpt(), conn); * } * @@ -91,11 +99,20 @@ static SingleParam value(final String name, final Object value) { /** * Create a new (multi) query parameter object for the given {@code name} - * and the given {@code values}. + * and the given {@code values}. Each value is converted into prepared + * statement parameter. * {@snippet lang="java": - * final var result = Query.of("SELECT * FROM table WHERE id = IN(:ids);") - * .on(Param.values("ids", List.of(43245, 434, 23, 987, 1239)) - * .as(PARSER.list(), conn); + * final var query = Query.of("SELECT * FROM table WHERE id = IN(:ids);") + * .on(Param.values("ids", List.of(43245, 434, 23, 987))); + * + * assert query.rawSql().equals( + * "SELECT * FROM table WHERE id IN(:ids[0],:ids[1],:ids[2],:ids[3]);" + * ); + * assert query.sql().equals( + * "SELECT * FROM table WHERE id IN(?,?,?,?);" + * ); + * + * final var result = query.as(PARSER.list(), conn); * } * * @since 1.3 @@ -118,20 +135,31 @@ static MultiParam values(final String name, final Iterable values) { ); } - @SuppressWarnings("unchecked") private static Stream stream(final Iterable values) { - return values instanceof Collection - ? ((Collection)values).stream() - : StreamSupport.stream(((Iterable)values).spliterator(), false); + @SuppressWarnings("unchecked") + final var vals = (Iterable)values; + + return vals instanceof Collection collection + ? collection.stream() + : StreamSupport.stream((vals).spliterator(), false); } /** * Create a new (multi) query parameter object for the given {@code name} - * and the given {@code values}. + * and the given {@code values}. Each value is converted into prepared + * statement parameter. * {@snippet lang="java": - * final var result = Query.of("SELECT * FROM table WHERE id = IN(:ids);") - * .on(Param.values("ids", 43245, 434, 23, 987, 1239) - * .as(PARSER.list(), conn); + * final var query = Query.of("SELECT * FROM table WHERE id = IN(:ids);") + * .on(Param.values("ids", 43245, 434, 23, 987)); + * + * assert query.rawSql().equals( + * "SELECT * FROM table WHERE id IN(:ids[0],:ids[1],:ids[2],:ids[3]);" + * ); + * assert query.sql().equals( + * "SELECT * FROM table WHERE id IN(?,?,?,?);" + * ); + * + * final var result = query.as(PARSER.list(), conn); * } * * @since 1.3 @@ -154,7 +182,7 @@ static MultiParam values(final String name, final Object... values) { * lazily evaluated {@code value}. * {@snippet lang="java": * final var result = Query.of("SELECT * FROM table WHERE date < :date;") - * .on(Param.lazyValue("date", LocalDate::now) + * .on(Param.lazyValue("date", LocalDate::now)) * .as(PARSER.singleOpt(), conn); * } * @@ -175,10 +203,10 @@ static SingleParam lazyValue(final String name, final SqlSupplier value) { * Create a new query parameter object for the given {@code name} and * lazily evaluated {@code values}. * {@snippet lang="java": - * final SqlSupplier id1 = ...; - * final SqlSupplier id2 = ...; + * final SqlSupplier id1 = null; // @replace substring='null' replacement="..." + * final SqlSupplier id2 = null; // @replace substring='null' replacement="..." * final var result = Query.of("SELECT * FROM table WHERE id = IN(:ids);") - * .on(Param.lazyValues("id", List.of(id1, id2)) + * .on(Param.lazyValues("id", List.of(id1, id2))) * .as(PARSER.list(), conn); * } * diff --git a/facilejdbc/src/main/java/io/jenetics/facilejdbc/Query.java b/facilejdbc/src/main/java/io/jenetics/facilejdbc/Query.java index 24dc45e..efa945c 100644 --- a/facilejdbc/src/main/java/io/jenetics/facilejdbc/Query.java +++ b/facilejdbc/src/main/java/io/jenetics/facilejdbc/Query.java @@ -19,7 +19,6 @@ */ package io.jenetics.facilejdbc; -import static java.lang.String.format; import static java.sql.Statement.RETURN_GENERATED_KEYS; import static java.util.Arrays.asList; import static java.util.Objects.requireNonNull; @@ -44,7 +43,6 @@ import java.util.List; import java.util.Map; import java.util.Optional; -import java.util.stream.Collectors; import java.util.stream.IntStream; import java.util.stream.Stream; @@ -223,18 +221,13 @@ public Query withTimeout(final Duration timeout) { * @throws NullPointerException if the given {@code params} is {@code null} */ public Query on(final Iterable params) { - final List singleParams = new ArrayList<>(); - final List multiParams = new ArrayList<>(); - for (var param : params) { + final var singleParams = new ArrayList(); + final var multiParams = new ArrayList(); - if (param instanceof SingleParam p) { - singleParams.add(p); - } else if (param instanceof MultiParam p) { - multiParams.add(p); - } else { - throw new AssertionError(format( - "Type '%s' not expected.", param.getClass().getName() - )); + for (var param : params) { + switch (param) { + case SingleParam sp -> singleParams.add(sp); + case MultiParam mp -> multiParams.add(mp); } } @@ -261,7 +254,7 @@ private Query onMultiParam(final List params) { new Params( params.stream() .flatMap(Query::toParams) - .collect(Collectors.toList()) + .toList() ) ); From 766e56428fa87fb69279a3be764d067f0cb47d19 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Franz=20Wilhelmst=C3=B6tter?= Date: Mon, 4 Aug 2025 23:29:37 +0200 Subject: [PATCH 13/14] Code improvements. MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Franz Wilhelmstötter --- .../java/io/jenetics/facilejdbc/Dctor.java | 1 - .../java/io/jenetics/facilejdbc/Records.java | 22 +++++++++---------- .../io/jenetics/facilejdbc/Reflections.java | 2 +- .../io/jenetics/facilejdbc/RowParser.java | 20 ++++++++--------- .../java/io/jenetics/facilejdbc/Stored.java | 2 -- 5 files changed, 22 insertions(+), 25 deletions(-) diff --git a/facilejdbc/src/main/java/io/jenetics/facilejdbc/Dctor.java b/facilejdbc/src/main/java/io/jenetics/facilejdbc/Dctor.java index 0df4c22..5f42fc1 100644 --- a/facilejdbc/src/main/java/io/jenetics/facilejdbc/Dctor.java +++ b/facilejdbc/src/main/java/io/jenetics/facilejdbc/Dctor.java @@ -37,7 +37,6 @@ /** * This interface is responsible for deconstructing a given record, of * type {@code T}, to a DB-row ({@link ParamValues}). - * * {@snippet lang="java": * final Dctor dctor = Dctor.of( * Dctor.field("title", Book::title), diff --git a/facilejdbc/src/main/java/io/jenetics/facilejdbc/Records.java b/facilejdbc/src/main/java/io/jenetics/facilejdbc/Records.java index 331003c..fe04b65 100644 --- a/facilejdbc/src/main/java/io/jenetics/facilejdbc/Records.java +++ b/facilejdbc/src/main/java/io/jenetics/facilejdbc/Records.java @@ -107,7 +107,7 @@ private Records() { * @throws IllegalArgumentException if there are duplicate fields defined */ public static Dctor dctor( - final Class type, + final Class type, final Function toColumnName, final List> fields ) { @@ -187,7 +187,7 @@ private static Dctor.Field toFiled( */ @SafeVarargs public static Dctor dctor( - final Class type, + final Class type, final Function toColumnName, final Dctor.Field... fields ) { @@ -233,7 +233,7 @@ public static Dctor dctor( */ @SafeVarargs public static Dctor dctor( - final Class type, + final Class type, final Dctor.Field... fields ) { return dctor(type, Records::toSnakeCase, List.of(fields)); @@ -343,7 +343,7 @@ public static String toSnakeCase(final String name) { * @throws NullPointerException if one of the arguments is {@code null} */ public static RowParser parser( - final Class type, + final Class type, final Function toColumnName, final Function> fields ) { @@ -357,7 +357,7 @@ public static RowParser parser( .map(toColumnName) .toArray(String[]::new); - final Constructor ctor = ctor(type); + final var ctor = ctor(type); return (row, conn) -> { final Object[] values = new Object[components.length]; @@ -402,7 +402,7 @@ public static RowParser parser( * @throws NullPointerException if one of the arguments is {@code null} */ public static RowParser parser( - final Class type, + final Class type, final Map toColumnName, final Map> fields ) { @@ -442,7 +442,7 @@ public static RowParser parser( * @throws NullPointerException if one of the arguments is {@code null} */ public static RowParser parserWithColumnNames( - final Class type, + final Class type, final Function toColumnName ) { return parser(type, toColumnName, component -> null); @@ -470,7 +470,7 @@ public static RowParser parserWithColumnNames( * @throws NullPointerException if one of the arguments is {@code null} */ public static RowParser parserWithColumnNames( - final Class type, + final Class type, final Map toColumnName ) { return parser(type, toColumnName, Map.of()); @@ -502,7 +502,7 @@ public static RowParser parserWithColumnNames( * @throws NullPointerException if one of the arguments is {@code null} */ public static RowParser parserWithFields( - final Class type, + final Class type, final Function> fields ) { return parser(type, Records::toSnakeCase, fields); @@ -529,7 +529,7 @@ public static RowParser parserWithFields( * @throws NullPointerException if one of the arguments is {@code null} */ public static RowParser parserWithFields( - final Class type, + final Class type, final Map> fields ) { return parser(type, Records::toSnakeCase, cmp -> fields.get(cmp.getName())); @@ -550,7 +550,7 @@ public static RowParser parserWithFields( * @return a new row-parser for the given record {@code type} * @throws NullPointerException if one of the arguments is {@code null} */ - public static RowParser parser(final Class type) { + public static RowParser parser(final Class type) { return parser(type, Records::toSnakeCase, component -> null); } diff --git a/facilejdbc/src/main/java/io/jenetics/facilejdbc/Reflections.java b/facilejdbc/src/main/java/io/jenetics/facilejdbc/Reflections.java index d1bf075..357785a 100644 --- a/facilejdbc/src/main/java/io/jenetics/facilejdbc/Reflections.java +++ b/facilejdbc/src/main/java/io/jenetics/facilejdbc/Reflections.java @@ -36,7 +36,7 @@ final class Reflections { private Reflections() { } - static Constructor ctor(final Class type) { + static Constructor ctor(final Class type) { final Class[] columnTypes = Stream.of(type.getRecordComponents()) .map(RecordComponent::getType) .toArray(Class[]::new); diff --git a/facilejdbc/src/main/java/io/jenetics/facilejdbc/RowParser.java b/facilejdbc/src/main/java/io/jenetics/facilejdbc/RowParser.java index 46a88c9..3893975 100644 --- a/facilejdbc/src/main/java/io/jenetics/facilejdbc/RowParser.java +++ b/facilejdbc/src/main/java/io/jenetics/facilejdbc/RowParser.java @@ -247,7 +247,7 @@ default ResultSetParser> singleOpt() { * @throws NullPointerException if the given {@code factory} is {@code null} */ default > - ResultSetParser collection(final Supplier factory) { + ResultSetParser collection(final Supplier factory) { return collection(factory, Function.identity()); } @@ -269,7 +269,7 @@ default ResultSetParser> list() { * * @return a new parser witch parses a whole selection result */ - default ResultSetParser array(final Class type) { + default ResultSetParser array(final Class type) { return (rs, conn) -> list().parse(rs, conn).toArray(length -> { @SuppressWarnings("unchecked") final var array = (T[])Array.newInstance(type, length); @@ -279,7 +279,7 @@ default ResultSetParser array(final Class type) { private , C2 extends Collection> ResultSetParser collection( - final Supplier factory, + final Supplier factory, final Function mapper ) { requireNonNull(factory); @@ -461,7 +461,7 @@ static RowParser compose( * Returns a parser for a scalar not-null value. * {@snippet lang="java": * final String name = Query.of("SELECT name FROM person WHERE id = :id") - * .on(value("id", 23)) + * .on(Param.value("id", 23)) * .as(scalar(String.class).single(), conn); * } * @@ -473,7 +473,7 @@ static RowParser compose( * @return a parser for a scalar not-null value * @throws NullPointerException if the give {@code type} is {@code null} */ - static RowParser scalar(final Class type) { + static RowParser scalar(final Class type) { return scalar(1, type); } @@ -481,7 +481,7 @@ static RowParser scalar(final Class type) { * Returns a parser for a scalar not-null value. * {@snippet lang="java": * final String name = Query.of("SELECT id, name FROM person WHERE id = :id") - * .on(value("id", 23)) + * .on(Param.value("id", 23)) * .as(scalar(2, String.class).single(), conn); * } * @@ -496,7 +496,7 @@ static RowParser scalar(final Class type) { * @return a parser for a scalar not-null value * @throws NullPointerException if the give {@code type} is {@code null} */ - static RowParser scalar(final int index, final Class type) { + static RowParser scalar(final int index, final Class type) { return (row, conn) -> row.getObject(index, type); } @@ -504,7 +504,7 @@ static RowParser scalar(final int index, final Class type) { * Returns a parser for a scalar not-null value. * {@snippet lang="java": * final String name = Query.of("SELECT id, name FROM person WHERE id = :id") - * .on(value("id", 23)) + * .on(Param.value("id", 23)) * .as(scalar("name", String.class).single(), conn); * } * @@ -519,7 +519,7 @@ static RowParser scalar(final int index, final Class type) { * @return a parser for a scalar not-null value * @throws NullPointerException if the give {@code type} is {@code null} */ - static RowParser scalar(final String name, final Class type) { + static RowParser scalar(final String name, final Class type) { return (row, conn) -> row.getObject(name, type); } @@ -887,7 +887,7 @@ static RowParser csvLine() { * @param the record type * @throws NullPointerException if the give {@code type} is {@code null} */ - static RowParser record(final Class type) { + static RowParser record(final Class type) { return Records.parser(type); } diff --git a/facilejdbc/src/main/java/io/jenetics/facilejdbc/Stored.java b/facilejdbc/src/main/java/io/jenetics/facilejdbc/Stored.java index ceeebb5..4dc98e8 100644 --- a/facilejdbc/src/main/java/io/jenetics/facilejdbc/Stored.java +++ b/facilejdbc/src/main/java/io/jenetics/facilejdbc/Stored.java @@ -22,8 +22,6 @@ /** * This class combines a record, stored in the DB, with its primary key. * - * @since 2.1 - * * @param the key type * @param the record type, stored in the DB * @param id the primary key From 3db7d003e6611a601fdfdc35a96e8d4022a835ea Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Franz=20Wilhelmst=C3=B6tter?= Date: Wed, 6 Aug 2025 21:37:31 +0200 Subject: [PATCH 14/14] Code improvements. MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Franz Wilhelmstötter --- .../io/jenetics/facilejdbc/Lifecycle.java | 22 +++++++++---------- .../java/io/jenetics/facilejdbc/Query.java | 14 ++++++++++-- .../io/jenetics/facilejdbc/RowParser.java | 3 +++ .../io/jenetics/facilejdbc/SingleParam.java | 2 +- .../java/io/jenetics/facilejdbc/Stored.java | 5 +++++ .../io/jenetics/facilejdbc/Transaction.java | 1 + 6 files changed, 33 insertions(+), 14 deletions(-) diff --git a/facilejdbc/src/main/java/io/jenetics/facilejdbc/Lifecycle.java b/facilejdbc/src/main/java/io/jenetics/facilejdbc/Lifecycle.java index a3c223c..c93cd51 100644 --- a/facilejdbc/src/main/java/io/jenetics/facilejdbc/Lifecycle.java +++ b/facilejdbc/src/main/java/io/jenetics/facilejdbc/Lifecycle.java @@ -257,25 +257,25 @@ public static final class Value implements Supplier, ExtendedCloseable { - private final T _value; - private final ThrowingConsumer _release; + private final T value; + private final ThrowingConsumer release; private Value( final T value, final ThrowingConsumer release ) { - _value = value; - _release = requireNonNull(release); + this.value = value; + this.release = requireNonNull(release); } @Override public T get() { - return _value; + return value; } @Override public void close() throws E { - _release.accept(get()); + release.accept(get()); } @Override @@ -430,7 +430,7 @@ public static final class Resources implements ExtendedCloseable { - private final List> _resources = new ArrayList<>(); + private final List> resources = new ArrayList<>(); /** * Create a new {@code Resources} object, initialized with the given @@ -441,7 +441,7 @@ public static final class Resources public Resources( final Collection> releases ) { - _resources.addAll(releases); + resources.addAll(releases); } /** @@ -480,14 +480,14 @@ public C add( requireNonNull(resource); requireNonNull(release); - _resources.add(() -> release.accept(resource)); + resources.add(() -> release.accept(resource)); return resource; } @Override public void close() throws E { - if (!_resources.isEmpty()) { - ExtendedCloseable.of(_resources).close(); + if (!resources.isEmpty()) { + ExtendedCloseable.of(resources).close(); } } diff --git a/facilejdbc/src/main/java/io/jenetics/facilejdbc/Query.java b/facilejdbc/src/main/java/io/jenetics/facilejdbc/Query.java index efa945c..8e70ad1 100644 --- a/facilejdbc/src/main/java/io/jenetics/facilejdbc/Query.java +++ b/facilejdbc/src/main/java/io/jenetics/facilejdbc/Query.java @@ -50,6 +50,8 @@ /** * A {@code Query} represents an executable piece of SQL text. + *

+ * Select query * {@snippet lang="java": * private static final Query SELECT = Query.of(""" * SELECT * FROM person @@ -57,7 +59,10 @@ * ORDER BY surname; * """ * ); - * + * } + *

+ * Insert query + * {@snippet lang="java": * private static final Query INSERT = Query.of(""" * INSERT INTO person(forename, surname, birthday, email) * VALUES(:forename, :surname, :birthday, :email); @@ -613,6 +618,8 @@ public String toString() { /** * Create a new query object from the given SQL string. + *

+ * Select query * {@snippet lang="java": * private static final Query SELECT = Query.of(""" * SELECT * FROM person @@ -620,7 +627,10 @@ public String toString() { * ORDER BY surname; * """ * ); - * + * } + *

+ * Insert query + * {@snippet lang="java": * private static final Query INSERT = Query.of(""" * INSERT INTO person(forename, surname, birthday, email) * VALUES(:forename, :surname, :birthday, :email); diff --git a/facilejdbc/src/main/java/io/jenetics/facilejdbc/RowParser.java b/facilejdbc/src/main/java/io/jenetics/facilejdbc/RowParser.java index 3893975..c6eadf1 100644 --- a/facilejdbc/src/main/java/io/jenetics/facilejdbc/RowParser.java +++ b/facilejdbc/src/main/java/io/jenetics/facilejdbc/RowParser.java @@ -358,7 +358,10 @@ default ResultSetParser> unmodifiableSet() { * While consuming the result {@link Stream}, possible {@link SQLException}s * are wrapped into {@link UncheckedSQLException}s. * {@snippet lang="java": + * static final RowParser PARSER = RowParser.record(Book.class); * final var select = Query.of("SELECT * FROM book;"); + * + * // Query result stream must be used within a try-with-resources block. * try (var stream = select.as(PARSER.stream(), conn)) { * stream.forEach(book -> null); // @replace substring='null' replacement="..." * } diff --git a/facilejdbc/src/main/java/io/jenetics/facilejdbc/SingleParam.java b/facilejdbc/src/main/java/io/jenetics/facilejdbc/SingleParam.java index 4a92f18..a176888 100644 --- a/facilejdbc/src/main/java/io/jenetics/facilejdbc/SingleParam.java +++ b/facilejdbc/src/main/java/io/jenetics/facilejdbc/SingleParam.java @@ -31,7 +31,7 @@ * INSERT_QUERY.on( * Param.value("forename", "Werner"), * Param.value("birthday", LocalDate.now()), - * Param.value("email", "some.email@gmail.com")) + * Param.value("email", "some.email@gmail.com")); * } * * @author Franz Wilhelmstötter diff --git a/facilejdbc/src/main/java/io/jenetics/facilejdbc/Stored.java b/facilejdbc/src/main/java/io/jenetics/facilejdbc/Stored.java index 4dc98e8..51d54a0 100644 --- a/facilejdbc/src/main/java/io/jenetics/facilejdbc/Stored.java +++ b/facilejdbc/src/main/java/io/jenetics/facilejdbc/Stored.java @@ -19,6 +19,8 @@ */ package io.jenetics.facilejdbc; +import static java.util.Objects.requireNonNull; + /** * This class combines a record, stored in the DB, with its primary key. * @@ -32,4 +34,7 @@ * @since 2.1 */ public record Stored(K id, T value) { + public Stored { + requireNonNull(id); + } } diff --git a/facilejdbc/src/main/java/io/jenetics/facilejdbc/Transaction.java b/facilejdbc/src/main/java/io/jenetics/facilejdbc/Transaction.java index 657f5fe..1afee1d 100644 --- a/facilejdbc/src/main/java/io/jenetics/facilejdbc/Transaction.java +++ b/facilejdbc/src/main/java/io/jenetics/facilejdbc/Transaction.java @@ -51,6 +51,7 @@ * @version 1.1 * @since 1.1 */ +@FunctionalInterface public interface Transaction { /**