diff options
author | Carlo Zancanaro <carlo@zancanaro.id.au> | 2015-06-09 17:33:56 +1000 |
---|---|---|
committer | Carlo Zancanaro <carlo@zancanaro.id.au> | 2015-06-09 17:33:56 +1000 |
commit | dd9f72b94eb7b2c37061c80457e74e8d7ac3e18f (patch) | |
tree | 17ac650c0c4a5045b1cbf0ef5c194b0ea7f7acd3 /src/main/java/au/id/zancanaro/javacheck/DataSourceHelper.java | |
parent | 813e523e9e57dc38f81afc53340e216b948d87cf (diff) |
Add an ObjectGenerator<>, and related machinery (also a mapOf generator)
Diffstat (limited to 'src/main/java/au/id/zancanaro/javacheck/DataSourceHelper.java')
-rw-r--r-- | src/main/java/au/id/zancanaro/javacheck/DataSourceHelper.java | 109 |
1 files changed, 109 insertions, 0 deletions
diff --git a/src/main/java/au/id/zancanaro/javacheck/DataSourceHelper.java b/src/main/java/au/id/zancanaro/javacheck/DataSourceHelper.java new file mode 100644 index 0000000..522fd26 --- /dev/null +++ b/src/main/java/au/id/zancanaro/javacheck/DataSourceHelper.java @@ -0,0 +1,109 @@ +package au.id.zancanaro.javacheck; + +import au.id.zancanaro.javacheck.annotations.DataSource; + +import java.lang.reflect.Field; +import java.lang.reflect.Modifier; +import java.lang.reflect.ParameterizedType; +import java.lang.reflect.Type; +import java.util.*; + +public class DataSourceHelper { + private final Class<?> classObject; + private final Map<Type, Generator<?>> generators; + + public DataSourceHelper(Class<?> classObject) { + this.classObject = classObject; + this.generators = new HashMap<>(); + } + + public static Set<Type> validateGeneratorFields(Class<?> classObject, List<Throwable> errors) { + Set<Type> result = new HashSet<>(); + + for (Field field : classObject.getDeclaredFields()) { + if (field.isAnnotationPresent(DataSource.class)) { + boolean error = false; + if (!Modifier.isStatic(field.getModifiers())) { + errors.add(new Error("@DataSource field " + field.getName() + " must be static")); + error = true; + } + if (!Modifier.isPublic(field.getModifiers())) { + errors.add(new Error("@DataSource field " + field.getName() + " must be public")); + error = true; + } + + Type type = field.getGenericType(); + ParameterizedType parameterizedType; + if (type instanceof ParameterizedType) { + parameterizedType = (ParameterizedType) type; + if (parameterizedType.getRawType() instanceof Class) { + Class<?> c = (Class) parameterizedType.getRawType(); + if (c == Generator.class) { + if (!error) { + result.add(parameterizedType.getActualTypeArguments()[0]); + } + } else { + errors.add(new Error("@DataSource fields must be of type Generator<T>")); + } + } else { + errors.add(new Error("@DataSource fields must be of type Generator<T>")); + } + } else { + errors.add(new Error("@DataSource fields must be of type Generator<T>")); + } + } + } + + return result; + } + + + private static final Map<Type, Type> rawTypes; + + static { + Map<Type, Type> types = new HashMap<>(); + types.put(Double.class, Double.TYPE); + types.put(Float.class, Float.TYPE); + types.put(Long.class, Long.TYPE); + types.put(Integer.class, Integer.TYPE); + types.put(Short.class, Short.TYPE); + types.put(Byte.class, Byte.TYPE); + types.put(Character.class, Character.TYPE); + types.put(Boolean.class, Boolean.TYPE); + rawTypes = Collections.unmodifiableMap(types); + } + + public Map<Type, Generator<?>> computeGenerators() { + if (generators.isEmpty()) { + for (Field field : classObject.getDeclaredFields()) { + if (!field.isAnnotationPresent(DataSource.class)) { + continue; + } + Type type = field.getGenericType(); + if (!(type instanceof ParameterizedType)) { + continue; + } + ParameterizedType parameterizedType = (ParameterizedType) type; + if (!(parameterizedType.getRawType() instanceof Class)) { + continue; + } + Class<?> c = (Class) parameterizedType.getRawType(); + if (c != Generator.class) { + continue; + } + try { + Type target = parameterizedType.getActualTypeArguments()[0]; + @SuppressWarnings("unchecked") + Generator<Object> generator = (Generator<Object>) field.get(null); + generators.put(target, generator); + if (rawTypes.containsKey(target)) { + generators.put(rawTypes.get(target), generator); + } + } catch (IllegalAccessException ex) { + throw new RuntimeException(ex); + } + } + } + return generators; + } +} |