Use correct type for deriveFromProperties

Fix `DataSourceBuilder` so that the type used to access `deriveFrom`
properties is based on the actual instance type rather than the
user-defined type which could have been changed.

Fixes gh-26644
pull/26677/head
Phillip Webb 4 years ago
parent eed620fc80
commit b6d31fb6a1

@ -91,7 +91,7 @@ public final class DataSourceBuilder<T extends DataSource> {
private Class<T> type;
private final T deriveFrom;
private final DataSource deriveFrom;
private DataSourceBuilder(ClassLoader classLoader) {
this.classLoader = classLoader;
@ -168,25 +168,18 @@ public final class DataSourceBuilder<T extends DataSource> {
*/
public T build() {
DataSourceProperties<T> properties = DataSourceProperties.forType(this.classLoader, this.type);
DataSourceProperties<T> deriveFromProperties = (this.deriveFrom != null)
? DataSourceProperties.forType(this.classLoader, this.type) : null;
DataSourceProperties<DataSource> deriveFromProperties = getDeriveFromProperties();
Class<? extends T> instanceType = (this.type != null) ? this.type : properties.getDataSourceInstanceType();
T dataSource = BeanUtils.instantiateClass(instanceType);
Set<DataSourceProperty> applied = new HashSet<>();
for (DataSourceProperty property : DataSourceProperty.values()) {
if (this.values.containsKey(property)) {
String value = this.values.get(property);
if (value != null) {
properties.set(dataSource, property, value);
applied.add(property);
}
String value = this.values.get(property);
if (!this.values.containsKey(property) && deriveFromProperties != null && properties.canSet(property)) {
value = deriveFromProperties.get(this.deriveFrom, property);
}
else if (deriveFromProperties != null && properties.canSet(property)) {
String value = deriveFromProperties.get(this.deriveFrom, property);
if (value != null) {
properties.set(dataSource, property, value);
applied.add(property);
}
if (value != null) {
properties.set(dataSource, property, value);
applied.add(property);
}
}
if (!applied.contains(DataSourceProperty.DRIVER_CLASS_NAME)
@ -199,6 +192,14 @@ public final class DataSourceBuilder<T extends DataSource> {
return dataSource;
}
@SuppressWarnings("unchecked")
private DataSourceProperties<DataSource> getDeriveFromProperties() {
if (this.deriveFrom == null) {
return null;
}
return DataSourceProperties.forType(this.classLoader, (Class<DataSource>) this.deriveFrom.getClass());
}
/**
* Create a new {@link DataSourceBuilder} instance.
* @return a new datasource builder instance

@ -318,6 +318,19 @@ class DataSourceBuilderTests {
assertThat(built.getUrl()).startsWith("jdbc:hsqldb:mem");
}
@Test // gh-26644
void buildWhenDerivedFromExistingDatabaseWithTypeChange() {
HikariDataSource dataSource = new HikariDataSource();
dataSource.setUsername("test");
dataSource.setPassword("secret");
dataSource.setJdbcUrl("jdbc:postgresql://localhost:5432/postgres");
DataSourceBuilder<?> builder = DataSourceBuilder.derivedFrom(dataSource).type(SimpleDriverDataSource.class);
SimpleDriverDataSource built = (SimpleDriverDataSource) builder.username("test2").password("secret2").build();
assertThat(built.getUsername()).isEqualTo("test2");
assertThat(built.getPassword()).isEqualTo("secret2");
assertThat(built.getUrl()).isEqualTo("jdbc:postgresql://localhost:5432/postgres");
}
final class HidePackagesClassLoader extends URLClassLoader {
private final String[] hiddenPackages;

Loading…
Cancel
Save