Search in sources :

Example 1 with ConfigValueType

use of com.typesafe.config.ConfigValueType in project config by typesafehub.

the class ConfigBeanImpl method createInternal.

/**
     * This is public ONLY for use by the "config" package, DO NOT USE this ABI
     * may change.
     * @param <T> type of the bean
     * @param config config to use
     * @param clazz class of the bean
     * @return the bean instance
     */
public static <T> T createInternal(Config config, Class<T> clazz) {
    if (((SimpleConfig) config).root().resolveStatus() != ResolveStatus.RESOLVED)
        throw new ConfigException.NotResolved("need to Config#resolve() a config before using it to initialize a bean, see the API docs for Config#resolve()");
    Map<String, AbstractConfigValue> configProps = new HashMap<String, AbstractConfigValue>();
    Map<String, String> originalNames = new HashMap<String, String>();
    for (Map.Entry<String, ConfigValue> configProp : config.root().entrySet()) {
        String originalName = configProp.getKey();
        String camelName = ConfigImplUtil.toCamelCase(originalName);
        // the camel one wins
        if (originalNames.containsKey(camelName) && !originalName.equals(camelName)) {
        // if we aren't a camel name to start with, we lose.
        // if we are or we are the first matching key, we win.
        } else {
            configProps.put(camelName, (AbstractConfigValue) configProp.getValue());
            originalNames.put(camelName, originalName);
        }
    }
    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 {
        List<PropertyDescriptor> beanProps = new ArrayList<PropertyDescriptor>();
        for (PropertyDescriptor beanProp : beanInfo.getPropertyDescriptors()) {
            if (beanProp.getReadMethod() == null || beanProp.getWriteMethod() == null) {
                continue;
            }
            beanProps.add(beanProp);
        }
        // Try to throw all validation issues at once (this does not comprehensively
        // find every issue, but it should find common ones).
        List<ConfigException.ValidationProblem> problems = new ArrayList<ConfigException.ValidationProblem>();
        for (PropertyDescriptor beanProp : beanProps) {
            Method setter = beanProp.getWriteMethod();
            Class<?> parameterClass = setter.getParameterTypes()[0];
            ConfigValueType expectedType = getValueTypeOrNull(parameterClass);
            if (expectedType != null) {
                String name = originalNames.get(beanProp.getName());
                if (name == null)
                    name = beanProp.getName();
                Path path = Path.newKey(name);
                AbstractConfigValue configValue = configProps.get(beanProp.getName());
                if (configValue != null) {
                    SimpleConfig.checkValid(path, expectedType, configValue, problems);
                } else {
                    if (!isOptionalProperty(clazz, beanProp)) {
                        SimpleConfig.addMissing(problems, expectedType, path, config.origin());
                    }
                }
            }
        }
        if (!problems.isEmpty()) {
            throw new ConfigException.ValidationFailed(problems);
        }
        // Fill in the bean instance
        T bean = clazz.newInstance();
        for (PropertyDescriptor beanProp : beanProps) {
            Method setter = beanProp.getWriteMethod();
            Type parameterType = setter.getGenericParameterTypes()[0];
            Class<?> parameterClass = setter.getParameterTypes()[0];
            String configPropName = originalNames.get(beanProp.getName());
            // Is the property key missing in the config?
            if (configPropName == null) {
                // If so, continue if the field is marked as @{link Optional}
                if (isOptionalProperty(clazz, beanProp)) {
                    continue;
                }
                // Otherwise, raise a {@link Missing} exception right here
                throw new ConfigException.Missing(beanProp.getName());
            }
            Object unwrapped = getValue(clazz, parameterType, parameterClass, config, configPropName);
            setter.invoke(bean, unwrapped);
        }
        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);
    }
}
Also used : ConfigValue(com.typesafe.config.ConfigValue) HashMap(java.util.HashMap) BeanInfo(java.beans.BeanInfo) IntrospectionException(java.beans.IntrospectionException) ArrayList(java.util.ArrayList) ConfigException(com.typesafe.config.ConfigException) ConfigValueType(com.typesafe.config.ConfigValueType) PropertyDescriptor(java.beans.PropertyDescriptor) Method(java.lang.reflect.Method) InvocationTargetException(java.lang.reflect.InvocationTargetException) ConfigValueType(com.typesafe.config.ConfigValueType) ParameterizedType(java.lang.reflect.ParameterizedType) Type(java.lang.reflect.Type) ConfigObject(com.typesafe.config.ConfigObject) HashMap(java.util.HashMap) Map(java.util.Map)

Aggregations

ConfigException (com.typesafe.config.ConfigException)1 ConfigObject (com.typesafe.config.ConfigObject)1 ConfigValue (com.typesafe.config.ConfigValue)1 ConfigValueType (com.typesafe.config.ConfigValueType)1 BeanInfo (java.beans.BeanInfo)1 IntrospectionException (java.beans.IntrospectionException)1 PropertyDescriptor (java.beans.PropertyDescriptor)1 InvocationTargetException (java.lang.reflect.InvocationTargetException)1 Method (java.lang.reflect.Method)1 ParameterizedType (java.lang.reflect.ParameterizedType)1 Type (java.lang.reflect.Type)1 ArrayList (java.util.ArrayList)1 HashMap (java.util.HashMap)1 Map (java.util.Map)1