From af45053694789e7283aedb7ae9cb6b513ad4587b Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?St=C3=A9phane=20Nicoll?= <stephane.nicoll@broadcom.com>
Date: Mon, 4 Nov 2024 08:09:08 +0900
Subject: [PATCH] Hacking

---
 .../spring-boot-dependencies/build.gradle      |  8 ++++++++
 spring-boot-project/spring-boot/build.gradle   |  1 +
 .../boot/jdbc/DataSourceBuilder.java           | 15 +++++++++++++++
 .../jdbc/DataSourceBuilderRuntimeHints.java    |  3 ++-
 .../DataSourceBuilderRuntimeHintsTests.java    |  4 ++--
 .../boot/jdbc/DataSourceBuilderTests.java      | 18 ++++++++++++++++++
 6 files changed, 46 insertions(+), 3 deletions(-)

diff --git a/spring-boot-project/spring-boot-dependencies/build.gradle b/spring-boot-project/spring-boot-dependencies/build.gradle
index 6756c699185d..58df44d02355 100644
--- a/spring-boot-project/spring-boot-dependencies/build.gradle
+++ b/spring-boot-project/spring-boot-dependencies/build.gradle
@@ -2276,6 +2276,14 @@ bom {
 			]
 		}
 	}
+	library("Vibur", "25.0") {
+		group("org.vibur") {
+			modules = [
+					"vibur-dbcp",
+					"vibur-object-pool"
+			]
+		}
+	}
 	library("WebJars Locator Lite", "1.0.0") {
 		group("org.webjars") {
 			modules = [
diff --git a/spring-boot-project/spring-boot/build.gradle b/spring-boot-project/spring-boot/build.gradle
index 8e538638db39..be142076ccd3 100644
--- a/spring-boot-project/spring-boot/build.gradle
+++ b/spring-boot-project/spring-boot/build.gradle
@@ -96,6 +96,7 @@ dependencies {
 		exclude group: "org.eclipse.jetty", module: "jetty-servlet"
 		exclude group: "jakarta.mail", module: "jakarta.mail-api"
 	}
+	optional("org.vibur:vibur-dbcp")
 	optional("org.yaml:snakeyaml")
 	optional("org.jetbrains.kotlin:kotlin-reflect")
 	optional("org.jetbrains.kotlin:kotlin-stdlib")
diff --git a/spring-boot-project/spring-boot/src/main/java/org/springframework/boot/jdbc/DataSourceBuilder.java b/spring-boot-project/spring-boot/src/main/java/org/springframework/boot/jdbc/DataSourceBuilder.java
index cea962a7fa74..3c1016c61211 100644
--- a/spring-boot-project/spring-boot/src/main/java/org/springframework/boot/jdbc/DataSourceBuilder.java
+++ b/spring-boot-project/spring-boot/src/main/java/org/springframework/boot/jdbc/DataSourceBuilder.java
@@ -36,6 +36,7 @@
 import org.apache.commons.dbcp2.BasicDataSource;
 import org.h2.jdbcx.JdbcDataSource;
 import org.postgresql.ds.PGSimpleDataSource;
+import org.vibur.dbcp.ViburDBCPDataSource;
 
 import org.springframework.beans.BeanUtils;
 import org.springframework.core.ResolvableType;
@@ -411,6 +412,8 @@ private static <T extends DataSource> MappedDataSourceProperties<T> lookupPooled
 					OraclePoolDataSourceProperties::new, "oracle.jdbc.OracleConnection");
 			result = lookup(classLoader, type, result, "com.mchange.v2.c3p0.ComboPooledDataSource",
 					ComboPooledDataSourceProperties::new);
+			result = lookup(classLoader, type, result, "org.vibur.dbcp.ViburDBCPDataSource",
+					ViburDataSourceProperties::new);
 			return result;
 		}
 
@@ -693,6 +696,18 @@ private void setDriverClass(ComboPooledDataSource dataSource, String driverClass
 
 	}
 
+	private static class ViburDataSourceProperties extends MappedDataSourceProperties<ViburDBCPDataSource> {
+
+		ViburDataSourceProperties() {
+			add(DataSourceProperty.URL, ViburDBCPDataSource::getJdbcUrl, ViburDBCPDataSource::setJdbcUrl);
+			add(DataSourceProperty.DRIVER_CLASS_NAME, ViburDBCPDataSource::getDriverClassName,
+					ViburDBCPDataSource::setDriverClassName);
+			add(DataSourceProperty.USERNAME, ViburDBCPDataSource::getUsername, ViburDBCPDataSource::setUsername);
+			add(DataSourceProperty.PASSWORD, ViburDBCPDataSource::getPassword, ViburDBCPDataSource::setPassword);
+		}
+
+	}
+
 	/**
 	 * {@link DataSourceProperties} for Spring's {@link SimpleDriverDataSource}.
 	 */
diff --git a/spring-boot-project/spring-boot/src/main/java/org/springframework/boot/jdbc/DataSourceBuilderRuntimeHints.java b/spring-boot-project/spring-boot/src/main/java/org/springframework/boot/jdbc/DataSourceBuilderRuntimeHints.java
index a91efdf7b2b5..ae306c730322 100644
--- a/spring-boot-project/spring-boot/src/main/java/org/springframework/boot/jdbc/DataSourceBuilderRuntimeHints.java
+++ b/spring-boot-project/spring-boot/src/main/java/org/springframework/boot/jdbc/DataSourceBuilderRuntimeHints.java
@@ -1,5 +1,5 @@
 /*
- * Copyright 2012-2023 the original author or authors.
+ * Copyright 2012-2024 the original author or authors.
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -43,6 +43,7 @@ class DataSourceBuilderRuntimeHints implements RuntimeHintsRegistrar {
 		typeNames.add("org.apache.commons.dbcp2.BasicDataSource");
 		typeNames.add("oracle.jdbc.datasource.OracleDataSource");
 		typeNames.add("oracle.ucp.jdbc.PoolDataSource");
+		typeNames.add("org.vibur.dbcp.ViburDBCPDataSource");
 		typeNames.add("org.postgresql.ds.PGSimpleDataSource");
 		typeNames.add("org.springframework.jdbc.datasource.SimpleDriverDataSource");
 		typeNames.add("org.apache.tomcat.jdbc.pool.DataSource");
diff --git a/spring-boot-project/spring-boot/src/test/java/org/springframework/boot/jdbc/DataSourceBuilderRuntimeHintsTests.java b/spring-boot-project/spring-boot/src/test/java/org/springframework/boot/jdbc/DataSourceBuilderRuntimeHintsTests.java
index 3332d0732619..df82f638b76e 100644
--- a/spring-boot-project/spring-boot/src/test/java/org/springframework/boot/jdbc/DataSourceBuilderRuntimeHintsTests.java
+++ b/spring-boot-project/spring-boot/src/test/java/org/springframework/boot/jdbc/DataSourceBuilderRuntimeHintsTests.java
@@ -1,5 +1,5 @@
 /*
- * Copyright 2012-2023 the original author or authors.
+ * Copyright 2012-2024 the original author or authors.
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -42,7 +42,7 @@ void shouldRegisterDataSourceConstructors() {
 			.of(com.mchange.v2.c3p0.ComboPooledDataSource.class, org.h2.jdbcx.JdbcDataSource.class,
 					com.zaxxer.hikari.HikariDataSource.class, org.apache.commons.dbcp2.BasicDataSource.class,
 					oracle.jdbc.datasource.OracleDataSource.class, oracle.ucp.jdbc.PoolDataSource.class,
-					org.postgresql.ds.PGSimpleDataSource.class,
+					org.vibur.dbcp.ViburDBCPDataSource.class, org.postgresql.ds.PGSimpleDataSource.class,
 					org.springframework.jdbc.datasource.SimpleDriverDataSource.class,
 					org.apache.tomcat.jdbc.pool.DataSource.class)
 			.forEach((dataSourceType) -> {
diff --git a/spring-boot-project/spring-boot/src/test/java/org/springframework/boot/jdbc/DataSourceBuilderTests.java b/spring-boot-project/spring-boot/src/test/java/org/springframework/boot/jdbc/DataSourceBuilderTests.java
index 87778a9e5a3a..f8c1a6266200 100644
--- a/spring-boot-project/spring-boot/src/test/java/org/springframework/boot/jdbc/DataSourceBuilderTests.java
+++ b/spring-boot-project/spring-boot/src/test/java/org/springframework/boot/jdbc/DataSourceBuilderTests.java
@@ -42,6 +42,7 @@
 import org.junit.jupiter.api.AfterEach;
 import org.junit.jupiter.api.Test;
 import org.postgresql.ds.PGSimpleDataSource;
+import org.vibur.dbcp.ViburDBCPDataSource;
 
 import org.springframework.jdbc.datasource.AbstractDataSource;
 import org.springframework.jdbc.datasource.SimpleDriverDataSource;
@@ -504,6 +505,23 @@ void buildWhenC3P0TypeSpecifiedReturnsExpectedDataSource() {
 		assertThat(c3p0DataSource.getDriverClass()).isEqualTo("com.example.Driver");
 	}
 
+	@Test // gh-42903
+	void buildWhenViburTypeSpecifiedReturnsExpectedDataSource() {
+		this.dataSource = DataSourceBuilder.create()
+			.url("jdbc:postgresql://localhost:5432/postgres")
+			.type(ViburDBCPDataSource.class)
+			.username("test")
+			.password("secret")
+			.driverClassName("com.example.Driver")
+			.build();
+		assertThat(this.dataSource).isInstanceOf(ViburDBCPDataSource.class);
+		ViburDBCPDataSource viburDataSource = (ViburDBCPDataSource) this.dataSource;
+		assertThat(viburDataSource.getJdbcUrl()).isEqualTo("jdbc:postgresql://localhost:5432/postgres");
+		assertThat(viburDataSource.getUsername()).isEqualTo("test");
+		assertThat(viburDataSource.getPassword()).isEqualTo("secret");
+		assertThat(viburDataSource.getDriverClassName()).isEqualTo("com.example.Driver");
+	}
+
 	private DataSource wrap(DataSource target) {
 		return new DataSourceWrapper(target);
 	}