From 5d1ed1c6786bc7dde70a992977c161f3a512240d Mon Sep 17 00:00:00 2001 From: fpirson Date: Wed, 1 Aug 2018 16:06:20 +0200 Subject: [PATCH] Capability to instantiate an object based on the String class name (#1074) It is usefull when you want to set the MetricsTackerFactory from a property. --- .../com/zaxxer/hikari/util/PropertyElf.java | 9 +++- .../com/zaxxer/hikari/mocks/TestObject.java | 27 ++++++++++++ .../zaxxer/hikari/util/PropertyElfTest.java | 43 +++++++++++++++++++ 3 files changed, 78 insertions(+), 1 deletion(-) create mode 100644 src/test/java/com/zaxxer/hikari/mocks/TestObject.java create mode 100644 src/test/java/com/zaxxer/hikari/util/PropertyElfTest.java diff --git a/src/main/java/com/zaxxer/hikari/util/PropertyElf.java b/src/main/java/com/zaxxer/hikari/util/PropertyElf.java index f03b8c65..d7ca117b 100644 --- a/src/main/java/com/zaxxer/hikari/util/PropertyElf.java +++ b/src/main/java/com/zaxxer/hikari/util/PropertyElf.java @@ -146,7 +146,14 @@ public final class PropertyElf writeMethod.invoke(target, propValue.toString()); } else { - writeMethod.invoke(target, propValue); + try { + LOGGER.debug("Try to create a new instance of \"{}\"", propValue.toString()); + writeMethod.invoke(target, Class.forName(propValue.toString()).newInstance()); + } + catch (InstantiationException | ClassNotFoundException e) { + LOGGER.debug("Class \"{}\" not found or could not instantiate it (Default constructor)", propValue.toString()); + writeMethod.invoke(target, propValue); + } } } catch (Exception e) { diff --git a/src/test/java/com/zaxxer/hikari/mocks/TestObject.java b/src/test/java/com/zaxxer/hikari/mocks/TestObject.java new file mode 100644 index 00000000..f81b08bf --- /dev/null +++ b/src/test/java/com/zaxxer/hikari/mocks/TestObject.java @@ -0,0 +1,27 @@ +package com.zaxxer.hikari.mocks; + +public class TestObject +{ + private TestObject testObject; + private String string; + + public void setTestObject(TestObject testObject) + { + this.testObject = testObject; + } + + public void setString(String string) + { + this.string = string; + } + + public TestObject getTestObject() + { + return testObject; + } + + public String getString() + { + return string; + } +} diff --git a/src/test/java/com/zaxxer/hikari/util/PropertyElfTest.java b/src/test/java/com/zaxxer/hikari/util/PropertyElfTest.java new file mode 100644 index 00000000..8d97a699 --- /dev/null +++ b/src/test/java/com/zaxxer/hikari/util/PropertyElfTest.java @@ -0,0 +1,43 @@ +package com.zaxxer.hikari.util; + +import org.junit.Assert; +import org.junit.Test; +import com.zaxxer.hikari.mocks.TestObject; + +import java.util.Properties; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertNotSame; +import static org.junit.Assert.fail; + +public class PropertyElfTest +{ + @Test + public void setTargetFromProperties() throws Exception + { + Properties properties = new Properties(); + properties.setProperty("string", "aString"); + properties.setProperty("testObject", "com.zaxxer.hikari.mocks.TestObject"); + TestObject testObject = new TestObject(); + PropertyElf.setTargetFromProperties(testObject, properties); + assertEquals("aString", testObject.getString()); + assertEquals(com.zaxxer.hikari.mocks.TestObject.class, testObject.getTestObject().getClass()); + assertNotSame(testObject, testObject.getTestObject()); + } + + @Test + public void setTargetFromPropertiesNotAClass() throws Exception + { + Properties properties = new Properties(); + properties.setProperty("string", "aString"); + properties.setProperty("testObject", "it is not a class"); + TestObject testObject = new TestObject(); + try { + PropertyElf.setTargetFromProperties(testObject, properties); + fail("Could never come here"); + } + catch (RuntimeException e) { + assertEquals("argument type mismatch", e.getCause().getMessage()); + } + } +}