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; } }