private void validate(String propertyName, String propertyValue, Optional<Pattern> p) throws ConfigBuilderException { if ( p.isPresent() ) { Pattern pattern = p.get(); if ( ! pattern.matcher(propertyValue).matches()) { throw new ConfigBuilderException("Property " + propertyName + " value '" + propertyValue + "' does not match pattern '" + pattern + "'"); } } }
private Object mapToEnum(String propertyValue, Class targetClass) throws ConfigBuilderException { Object[] enumConstants = targetClass.getEnumConstants(); for (Object e: enumConstants) { if ( ((Enum)e).name().equalsIgnoreCase(propertyValue)) { return e; } } throw new ConfigBuilderException("Could not convert property value " + propertyValue + " to an instance of Enum class " + targetClass.getName()); }
private boolean checkValidationMethod(Method method, Class configClass) throws ConfigBuilderException { if (method.getParameterCount() > 0) { throw new ConfigBuilderException("Validation method " + method.getName() + " on class " + configClass.getSimpleName() + " requires an argument and this is not supported"); } else if (method.getReturnType() != Void.TYPE) { throw new ConfigBuilderException("Validation method " + method.getName() + " on class " + configClass.getSimpleName() + " does not have a void return type"); } return true; }
private <C> void runClassLevelValidation(Class<C> configClass, C configInstance) throws ConfigBuilderException { List<Method> validationMethods = configPropertyParser.getValidationMethods(configClass); for (Method m : validationMethods) { try { m.invoke(configInstance); } catch (InvocationTargetException i) { log.debug("Config validation failed", i); throw new ConfigBuilderException("Validation method failed: [" + i.getCause().getMessage() + "]"); } catch (Exception e) { throw new ConfigBuilderException("Failed to execute validation method " + m.getName() + " on config class " + configClass.getSimpleName(), e); } } }
private Object mapToEnumOrPrimitiveWrapper(String propertyValue, Class targetClass) throws ConfigBuilderException { Object result; try { if ( targetClass.isEnum()) { result = mapToEnum(propertyValue, targetClass); } else { result = mapToPrimitiveWrapper(propertyValue, targetClass); } } catch (NumberFormatException nfe) { throw new ConfigBuilderException(getClass().getSimpleName() + " could not convert the property value '" + propertyValue + "' to a " + targetClass.getName()); } return result; }
return propertyValue.charAt(0); } else { throw new ConfigBuilderException("Could not convert a String with more than one character to a char"); throw new ConfigBuilderException(getClass().getSimpleName() + " cannot convert property value to a " + targetClass.getName() + " consider configuring a custom value converter");
private void validateDefaultValue(Pattern validationPattern, ConfigProperty p) throws ConfigBuilderException { if (!validationPattern.matcher(p.defaultValue()).matches()) { throw new ConfigBuilderException( String.format("The default value [%s] did not match the validation pattern [%s], for %s", p.defaultValue(), validationPattern.pattern(), getAnnotationDescription(p) ) ); } }
private ConfigBuilderTypeConverter getConverterFunction(ConfigProperty p, Class javaType) throws ConfigBuilderException { ConfigBuilderTypeConverter f; try { Class<? extends ConfigBuilderTypeConverter> c = p.valueConverter(); f = c.newInstance(); } catch (Exception e) { throw new ConfigBuilderException("Failed to instantiate converter class " + p.valueConverter().getClass().getName() + " for " + getAnnotationDescription(p), e); } return f; }
public <C> C buildConfig(Class<C> configClass, Properties properties) throws ConfigBuilderException { Map<String, HandlerConfigProperty> configPropertiesByName = configPropertyParser.getConfigPropertiesByName(configClass); C configInstance; try { configInstance = configClass.newInstance(); } catch (Exception e) { throw new ConfigBuilderException("Failed to instantiate config class " + configClass.getSimpleName() + " - " + e.getClass().getSimpleName(), e); } //iterate sorted by field name for consistent/deterministic behaviour List<String> props = configPropertiesByName.keySet().stream().sorted().collect(Collectors.toList()); for ( String configPropertyName : props) { log.debug("Processing config property " + configPropertyName); HandlerConfigPropertyImpl configProperty = (HandlerConfigPropertyImpl)configPropertiesByName.get(configPropertyName); String propertyValue = properties.getProperty(configPropertyName); setValueForConfigProperty(configInstance, configPropertyName, configProperty, propertyValue); } warnOnUnusedProperties(properties, configPropertiesByName); runClassLevelValidation(configClass, configInstance); return configInstance; }
private Pattern compilePattern(ConfigProperty p) throws ConfigBuilderException { Pattern pattern; try { pattern = Pattern.compile(p.validationPattern()); } catch (PatternSyntaxException e) { throw new ConfigBuilderException("The validation pattern '" + p.validationPattern() + "' could not be compiled, for " + getAnnotationDescription(p)); } return pattern; }
private Object applyConverterFunction(String propertyName, HandlerConfigPropertyImpl configProperty, String propertyValue) throws ConfigBuilderException { Object result = configProperty.getValueConverter().convertToTargetType(propertyValue, configProperty.getJavaType()); if ( result == null) { throw new ConfigBuilderException("Property " + propertyName + " converter function returned null when converting value " + propertyValue); } return result; }
throw new ConfigBuilderException( "A config bean can only annotate a setter method (the method " + method.getName() + " does not start with 'set'), for " + getAnnotationDescription(p)); throw new ConfigBuilderException( "The annotated method must take a single argument, for " + getAnnotationDescription(p) ); throw new ConfigBuilderException("Default value \"" + p.defaultValue() + "\" was converted to a type " + defaultValue.getClass().getName() + " which did not match the expected class type " + javaType.getName() + " for " + getAnnotationDescription(p));
throw new ConfigBuilderException("Property " + configPropertyName + " is mandatory but no value was provided"); throw new ConfigBuilderException("The expected value type for the property " + configPropertyName + " is a " + configProperty.getJavaType().getName() + " but the converted value was a " + convertedValue.getClass().getName()); configProperty.getSetterMethod().invoke(configInstance, convertedValue); } catch (Exception e) { throw new ConfigBuilderException("Failed to set property + " + configPropertyName + " to value " + convertedValue + " on config instance with class type " + configInstance.getClass().getName(), e);