/** * Evaluate the initial keys fromMap the configuration and applyChanges it to the field. * * @param target the target instance. * @throws ConfigException if evaluation or conversion failed. */ public void applyValue(Object target, boolean resolve) throws ConfigException { String configValue = InjectionUtils.getConfigValue(this.setterMethod); Objects.requireNonNull(target); try { String evaluatedString = resolve && configValue != null ? InjectionUtils.evaluateValue(configValue) : configValue; // Check for adapter/filter Object value = InjectionUtils.adaptValue( this.setterMethod, TypeLiteral.of(this.setterMethod.getParameterTypes()[0]), evaluatedString); AccessController.doPrivileged( new PrivilegedExceptionAction<Object>() { @Override public Object run() throws Exception { setterMethod.setAccessible(true); return setterMethod; } }); setterMethod.invoke(target, value); } catch (Exception e) { throw new ConfigException( "Failed to annotation configured method: " + this.setterMethod.getDeclaringClass().getName() + '.' + setterMethod.getName(), e); } }
@SuppressWarnings("rawtypes") public static <T> T adaptValue( AnnotatedElement element, TypeLiteral<T> targetType, String key, String configValue) { // Check for adapter/filter T adaptedValue = null; WithPropertyConverter converterAnnot = element.getAnnotation(WithPropertyConverter.class); Class<? extends PropertyConverter<T>> converterType; if (converterAnnot != null) { converterType = (Class<? extends PropertyConverter<T>>) converterAnnot.value(); if (!converterType.getName().equals(WithPropertyConverter.class.getName())) { try { // TODO cache here... ConversionContext ctx = new ConversionContext.Builder(key, targetType).setAnnotatedElement(element).build(); PropertyConverter<T> converter = PropertyConverter.class.cast(converterType.newInstance()); adaptedValue = converter.convert(configValue, ctx); } catch (Exception e) { LOG.log( Level.SEVERE, "Failed to convert using explicit PropertyConverter on " + element + ", trying default conversion.", e); } } } if (adaptedValue != null) { return adaptedValue; } if (String.class == targetType.getType()) { return (T) configValue; } else { List<PropertyConverter<T>> converters = ConfigurationProvider.getConfigurationContext().getPropertyConverters(targetType); ConversionContext ctx = new ConversionContext.Builder(ConfigurationProvider.getConfiguration(), key, targetType) .setAnnotatedElement(element) .build(); for (PropertyConverter<T> converter : converters) { adaptedValue = converter.convert(configValue, ctx); if (adaptedValue != null) { return adaptedValue; } } throw new ConfigException("Non convertible property type: " + element); } }