package com.googlecode.objectify.impl; import com.googlecode.objectify.ObjectifyFactory; import com.googlecode.objectify.condition.Always; import com.googlecode.objectify.condition.If; import com.googlecode.objectify.condition.InitializeIf; import com.googlecode.objectify.repackaged.gentyref.GenericTypeReflector; import java.lang.reflect.Field; import java.lang.reflect.Type; /** * Utility that makes it easy to generate If conditions. */ public class IfConditionGenerator { /** For simple cases that always test positive (ie, empty if arrays) */ private static final If<?, ?>[] ALWAYS = new If<?, ?>[] { new Always() }; /** */ ObjectifyFactory fact; /** */ public IfConditionGenerator(ObjectifyFactory fact) { this.fact = fact; } /** * Clever enough to recognize that an empty set of conditions means Always. */ public If<?, ?>[] generateIfConditions(Class<? extends If<?, ?>>[] ifClasses, Field field) { if (ifClasses.length == 0) return ALWAYS; If<?, ?>[] result = new If<?, ?>[ifClasses.length]; for (int i=0; i<ifClasses.length; i++) { Class<? extends If<?, ?>> ifClass = ifClasses[i]; result[i] = this.createIf(ifClass, field); // Sanity check the generic If class types to ensure that they match the actual types of the field & entity. Type valueType = GenericTypeReflector.getTypeParameter(ifClass, If.class.getTypeParameters()[0]); Class<?> valueClass = GenericTypeReflector.erase(valueType); Type pojoType = GenericTypeReflector.getTypeParameter(ifClass, If.class.getTypeParameters()[1]); Class<?> pojoClass = GenericTypeReflector.erase(pojoType); if (!TypeUtils.isAssignableFrom(valueClass, field.getType())) throw new IllegalStateException("Cannot use If class " + ifClass.getName() + " on " + field + " because you cannot assign " + field.getType().getName() + " to " + valueClass.getName()); if (!TypeUtils.isAssignableFrom(pojoClass, field.getDeclaringClass())) throw new IllegalStateException("Cannot use If class " + ifClass.getName() + " on " + field + " because the containing class " + field.getDeclaringClass().getName() + " is not compatible with " + pojoClass.getName()); } return result; } /** */ public If<?, ?> createIf(Class<? extends If<?, ?>> ifClass, Field field) { If<?, ?> created = fact.construct(ifClass); if (created instanceof InitializeIf) ((InitializeIf)created).init(fact, field); return created; } }