From dd9f72b94eb7b2c37061c80457e74e8d7ac3e18f Mon Sep 17 00:00:00 2001 From: Carlo Zancanaro Date: Tue, 9 Jun 2015 17:33:56 +1000 Subject: Add an ObjectGenerator<>, and related machinery (also a mapOf generator) --- .../id/zancanaro/javacheck/DataSourceHelper.java | 109 +++++++++++++++++++++ 1 file changed, 109 insertions(+) create mode 100644 src/main/java/au/id/zancanaro/javacheck/DataSourceHelper.java (limited to 'src/main/java/au/id/zancanaro/javacheck/DataSourceHelper.java') 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> generators; + + public DataSourceHelper(Class classObject) { + this.classObject = classObject; + this.generators = new HashMap<>(); + } + + public static Set validateGeneratorFields(Class classObject, List errors) { + Set 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")); + } + } else { + errors.add(new Error("@DataSource fields must be of type Generator")); + } + } else { + errors.add(new Error("@DataSource fields must be of type Generator")); + } + } + } + + return result; + } + + + private static final Map rawTypes; + + static { + Map 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> 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 generator = (Generator) 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; + } +} -- cgit v1.2.3