DBConverter | RuleConverter |
---|
CommandLineOptionsParser | CommandLineOptionsLoader |
ConfigPropertiesLoader | PropertyLoader |
ConfigDeterminer | ConfigBuilder |
ConfigManager | ConfigProvider |
PropertiesResourceLoader | |
BeanMerger | |
ConfigValidator |
@PropertyValue("user.name")
private String userName;
@SystemPropertyValue("user.name")
private String userName;
@EnvironmentVariableValue("PATH")
private String path;
@CommandLineValue(shortOpt="u", longOpt="user", hasArg="true")
private String userName;
public class TechDayConfig {
private boolean isOpenTechDay;
private int numberOfSteaks;
private String location;
private String userName;
private Barbecue barbecue;
private Collection<String> people;
private Collection<Steak> steaks;
}
@PropertiesFiles("techday")
public class TechDayConfig {
...
@DefaultValue("false")
@CommandLineValue(shortOpt="t", longOpt="test", hasArg=false)
private boolean isOpenTechDay;
@DefaultValue("3")
@CommandLineValue(shortOpt="n", longOpt="steaks", hasArg=true)
private int numberOfSteaks;
@EnvironmentVariableValue("HOME")
@PropertyValue("location")
private String location;
@SystemPropertyValue("user.name")
private String userName;
@TypeTransformer(BarbecueFactory.class)
@PropertyValue("barbecue")
private Barbecue barbecue;
@PropertyValue("people")
private Collection<String> people;
@TypeTransformer(Steak.class)
@PropertyValue("steaks")
private Collection<Steak> steaks;
}
@PropertyLocations(directories = {"/home/user"}, contextClassLoader = true)
@PropertySuffixes(extraSuffixes = {"tngtech","myname"}, hostNames = true)
public class TechDayConfig {
}
@NotEmpty("username.notEmpty")
private String userName;
@Validation
private void validate() {
<...>
}
public class TechDayConfig {
public MyConfig(Barbecue barbecue) {
this.barbecue = barbecue;
}
}
key = {$nested{$variable}}
variable = test
nestedtest = value
key = $PATH
%include=file1,file2,file3
key = DECRYPT:value
propertyLoader.atDefaultLocations()
propertyLoader.atDirectory(String directory)
propertyLoader.atBaseURL(URL url)
propertyLoader.atCurrentDirectory()
propertyLoader.atHomeDirectory()
propertyLoader.atContextClassPath()
propertyLoader.atClassLoader(ClassLoader classLoader)
propertyLoader.atRelativeToClass(Class<?> clazz)
propertyLoader.addDefaultSuffixes()
propertyLoader.addLocalHostNames()
propertyLoader.addUserName()
propertyLoader.addSuffix(String directory)
propertyLoader.addSuffixList(List<String> suffixes)
propertyLoader.withDefaultFilters()
propertyLoader.withVariableResolvingFilter()
propertyLoader.withEnvironmentResolvingFilter()
propertyLoader.withDecryptingFilter()
propertyLoader.withWarnIfPropertyHasToBeDefined()
propertyLoader.withWarnOnSurroundingWhitespace()
@ValueExtractorAnnotation(CommandLineValueProcessor.class)
@Target(ElementType.FIELD)
@Retention(RetentionPolicy.RUNTIME)
public @interface CommandLineValue {
String shortOpt();
String longOpt();
String description() default "";
boolean hasArg() default false;
boolean required() default false;
}
no inheritance | annotate annotations again |
no implementation of method bodies |
AnnotationProcessor classes |
limited selection of "attachment" types: primitives, strings, classes, annotations and arrays |
- |
only constant "attachments" | ? |
Class<? extends IValueExtractorProcessor> processor;
for (Annotation annotation : ) {
processor = annotation.annotationType().getAnnotation(ValueExtractorAnnotation.class).value();
value = configBuilderFactory.getInstance(processor).getValue(annotation, builderConfiguration);
if (value != null) {
break;
}
}
Class<?> clazz = obj.getClass();
Field[] publicFields = clazz.getFields();
Field[] allFields = clazz.getDeclaredFields();
Field userNameField = clazz.getField("userName");
final class java.lang.reflect.Field
extends AccessibleObject
implements Member
Class<?> clazz = ...
Method[] publicMethods = clazz.getMethods();
Method[] allMethods = clazz.getDeclaredMethods();
Method getValue = clazz.getMethods("getValue", Class[] args);
Constructor[] constructors = clazz.getConstructors();
Constructor<T> getConstructor(Class... parameterTypes)throws NoSuchMethodException
final class java.lang.reflect.Method
extends AccessibleObject
implements GenericDeclaration, Member
final class java.lang.reflect.Constructor<T>
extends AccessibleObject
implements GenericDeclaration, Member
Annotation[] annotations = clazz.getAnnotations()
Annotation[] annotations = clazz.getDeclaredAnnotations()
Annotation[] annotations = field.getDeclaredAnnotations()
Annotation[] annotations = method.getDeclaredAnnotations()
Annotation[] annotations = annotation.getDeclaredAnnotations()
Annotation annotation = clazz.getAnnotation(PropertyValue.class)
Object newObj = clazz.newInstance();
Object newObj = constructor.newInstance(args);
Object newObj = field.get();
String fieldName = field.getName();
Object fieldType = field.getType();
field.set(Object o);
private ...
field.setAccessible(true);
method.setAccessible(true);
Method method = o.getClass().getDeclaredMethod("methodName");
Method method = o.getClass().getDeclaredMethod("methodName", Object[] args);
method.setAccessible(true);
method.invoke(Object o);
method.invoke(Object o, Object[] args);
method.invoke(null);
https://github.com/TNG/config-builder
https://github.com/TNG/property-loader
<dependency>
<groupId>com.tngtech.java</groupId>
<artifactId>config-builder</artifactId>
<version>1.0</version>
</dependency>
<dependency>
<groupId>com.tngtech.java</groupId>
<artifactId>property-loader</artifactId>
<version>1.1</version>
</dependency>