From 11efe879e8e729828319ef4c6a9d6d574a30e946 Mon Sep 17 00:00:00 2001 From: Havoc Pennington Date: Fri, 27 Feb 2015 09:23:51 -0500 Subject: [PATCH] Move ConfigBeanFactory internals to impl.ConfigBeanImpl This is because I want to make some changes that will use impl-private API. --- .../typesafe/config/ConfigBeanFactory.java | 84 +---------------- .../typesafe/config/impl/ConfigBeanImpl.java | 93 +++++++++++++++++++ 2 files changed, 95 insertions(+), 82 deletions(-) create mode 100644 config/src/main/java/com/typesafe/config/impl/ConfigBeanImpl.java diff --git a/config/src/main/java/com/typesafe/config/ConfigBeanFactory.java b/config/src/main/java/com/typesafe/config/ConfigBeanFactory.java index acc2aa4f..ca1a3808 100644 --- a/config/src/main/java/com/typesafe/config/ConfigBeanFactory.java +++ b/config/src/main/java/com/typesafe/config/ConfigBeanFactory.java @@ -1,16 +1,6 @@ package com.typesafe.config; -import java.beans.BeanInfo; -import java.beans.IntrospectionException; -import java.beans.Introspector; -import java.beans.PropertyDescriptor; -import java.lang.reflect.InvocationTargetException; -import java.lang.reflect.Method; -import java.util.HashMap; -import java.util.Map; -import java.util.concurrent.TimeUnit; -import java.time.Duration; -import com.typesafe.config.impl.ConfigImplUtil; +import com.typesafe.config.impl.ConfigBeanImpl; /** * Factory for automatically creating a Java class from a {@link Config}. @@ -46,76 +36,6 @@ public class ConfigBeanFactory { * Can throw the same exceptions as the getters on Config */ public static T create(Config config, Class clazz) { - return createInternal(config, clazz); - } - - private static T createInternal(Config config, Class clazz) { - Map configAsMap = config.root().unwrapped(); - Map configProps = new HashMap(); - Map originalNames = new HashMap(); - for (Map.Entry configProp : configAsMap.entrySet()) { - configProps.put(ConfigImplUtil.toCamelCase(configProp.getKey()), configProp.getValue()); - originalNames.put(ConfigImplUtil.toCamelCase(configProp.getKey()),configProp.getKey()); - } - - BeanInfo beanInfo = null; - try { - beanInfo = Introspector.getBeanInfo(clazz); - } catch (IntrospectionException e) { - throw new ConfigException.BadBean("Could not get bean information for class " + clazz.getName(), e); - } - - try { - T bean = clazz.newInstance(); - for (PropertyDescriptor beanProp : beanInfo.getPropertyDescriptors()) { - if (beanProp.getReadMethod() == null || beanProp.getWriteMethod() == null) { - continue; - } - Method setter = beanProp.getWriteMethod(); - Object configValue = configProps.get(beanProp.getName()); - if (configValue == null) { - throw new ConfigException.Missing(beanProp.getName()); - } - if (configValue instanceof Map) { - configValue = createInternal(config.getConfig(originalNames.get(beanProp.getDisplayName())), beanProp.getPropertyType()); - } else { - Class parameterClass = setter.getParameterTypes()[0]; - configValue = getValueWithAutoConversion(parameterClass, config, originalNames.get(beanProp.getDisplayName())); - } - setter.invoke(bean, configValue); - - } - return bean; - } catch (InstantiationException e) { - throw new ConfigException.BadBean(clazz.getName() + " needs a public no-args constructor to be used as a bean", e); - } catch (IllegalAccessException e) { - throw new ConfigException.BadBean(clazz.getName() + " getters and setters are not accessible, they must be for use as a bean", e); - } catch (InvocationTargetException e) { - throw new ConfigException.BadBean("Calling bean method on " + clazz.getName() + " caused an exception", e); - } - } - - private static Object getValueWithAutoConversion(Class parameterClass, Config config, String configPropName) { - if (parameterClass == Boolean.class || parameterClass == boolean.class) { - return config.getBoolean(configPropName); - } else if (parameterClass == Byte.class || parameterClass == byte.class) { - return Integer.valueOf(config.getInt(configPropName)).byteValue(); - } else if (parameterClass == Short.class || parameterClass == short.class) { - return Integer.valueOf(config.getInt(configPropName)).shortValue(); - } else if (parameterClass == Integer.class || parameterClass == int.class) { - return config.getInt(configPropName); - } else if (parameterClass == Double.class || parameterClass == double.class) { - return config.getDouble(configPropName); - } else if (parameterClass == Long.class || parameterClass == long.class) { - return config.getLong(configPropName); - } else if (parameterClass == String.class) { - return config.getString(configPropName); - } else if (parameterClass == Duration.class) { - return config.getDuration(configPropName); - } else if (parameterClass == ConfigMemorySize.class) { - return config.getMemorySize(configPropName); - } - - return config.getAnyRef(configPropName); + return ConfigBeanImpl.createInternal(config, clazz); } } diff --git a/config/src/main/java/com/typesafe/config/impl/ConfigBeanImpl.java b/config/src/main/java/com/typesafe/config/impl/ConfigBeanImpl.java new file mode 100644 index 00000000..7c5494b2 --- /dev/null +++ b/config/src/main/java/com/typesafe/config/impl/ConfigBeanImpl.java @@ -0,0 +1,93 @@ +package com.typesafe.config.impl; + +import java.beans.BeanInfo; +import java.beans.IntrospectionException; +import java.beans.Introspector; +import java.beans.PropertyDescriptor; +import java.lang.reflect.InvocationTargetException; +import java.lang.reflect.Method; +import java.util.HashMap; +import java.util.Map; +import java.util.concurrent.TimeUnit; +import java.time.Duration; + +import com.typesafe.config.Config; +import com.typesafe.config.ConfigException; +import com.typesafe.config.ConfigMemorySize; + +public class ConfigBeanImpl { + + /** + * This is public ONLY for use by the "config" package, DO NOT USE this ABI + * may change. + */ + public static T createInternal(Config config, Class clazz) { + Map configAsMap = config.root().unwrapped(); + Map configProps = new HashMap(); + Map originalNames = new HashMap(); + for (Map.Entry configProp : configAsMap.entrySet()) { + configProps.put(ConfigImplUtil.toCamelCase(configProp.getKey()), configProp.getValue()); + originalNames.put(ConfigImplUtil.toCamelCase(configProp.getKey()),configProp.getKey()); + } + + BeanInfo beanInfo = null; + try { + beanInfo = Introspector.getBeanInfo(clazz); + } catch (IntrospectionException e) { + throw new ConfigException.BadBean("Could not get bean information for class " + clazz.getName(), e); + } + + try { + T bean = clazz.newInstance(); + for (PropertyDescriptor beanProp : beanInfo.getPropertyDescriptors()) { + if (beanProp.getReadMethod() == null || beanProp.getWriteMethod() == null) { + continue; + } + Method setter = beanProp.getWriteMethod(); + Object configValue = configProps.get(beanProp.getName()); + if (configValue == null) { + throw new ConfigException.Missing(beanProp.getName()); + } + if (configValue instanceof Map) { + configValue = createInternal(config.getConfig(originalNames.get(beanProp.getDisplayName())), beanProp.getPropertyType()); + } else { + Class parameterClass = setter.getParameterTypes()[0]; + configValue = getValueWithAutoConversion(parameterClass, config, originalNames.get(beanProp.getDisplayName())); + } + setter.invoke(bean, configValue); + + } + return bean; + } catch (InstantiationException e) { + throw new ConfigException.BadBean(clazz.getName() + " needs a public no-args constructor to be used as a bean", e); + } catch (IllegalAccessException e) { + throw new ConfigException.BadBean(clazz.getName() + " getters and setters are not accessible, they must be for use as a bean", e); + } catch (InvocationTargetException e) { + throw new ConfigException.BadBean("Calling bean method on " + clazz.getName() + " caused an exception", e); + } + } + + private static Object getValueWithAutoConversion(Class parameterClass, Config config, String configPropName) { + if (parameterClass == Boolean.class || parameterClass == boolean.class) { + return config.getBoolean(configPropName); + } else if (parameterClass == Byte.class || parameterClass == byte.class) { + return Integer.valueOf(config.getInt(configPropName)).byteValue(); + } else if (parameterClass == Short.class || parameterClass == short.class) { + return Integer.valueOf(config.getInt(configPropName)).shortValue(); + } else if (parameterClass == Integer.class || parameterClass == int.class) { + return config.getInt(configPropName); + } else if (parameterClass == Double.class || parameterClass == double.class) { + return config.getDouble(configPropName); + } else if (parameterClass == Long.class || parameterClass == long.class) { + return config.getLong(configPropName); + } else if (parameterClass == String.class) { + return config.getString(configPropName); + } else if (parameterClass == Duration.class) { + return config.getDuration(configPropName); + } else if (parameterClass == ConfigMemorySize.class) { + return config.getMemorySize(configPropName); + } + + return config.getAnyRef(configPropName); + } +}