+ ctx.getInjector().getInjectedType()
+ " has not been initialized. Either initialize or add @Inject!")).finish());
}
// Check if the bound property exists in data model type
Bound bound = ctx.getAnnotation();
String property = bound.property().equals("") ? ctx.getMemberName() : bound.property();
if (!DataBindingValidator.isValidPropertyChain(binderLookup.getDataModelType(), property)) {
throw new GenerationException("Invalid binding of field " + ctx.getMemberName()
+ " in class " + ctx.getInjector().getInjectedType() + "! Property " + property
+ " not resolvable from class " + binderLookup.getDataModelType()
+ "! Hint: Is " + binderLookup.getDataModelType() + " marked as @Bindable? When binding to a "
+ "property chain, all properties but the last in a chain must be of a @Bindable type!");
}
Statement widget = ctx.getValueStatement();
// Ensure the @Bound field or method provides a widget or DOM element
MetaClass widgetType = ctx.getElementTypeOrMethodReturnType();
if (widgetType.isAssignableTo(Widget.class)) {
// Ensure @Bound widget field is initialized
if (!ctx.isAnnotationPresent(Inject.class) && ctx.getField() != null && widgetType.isDefaultInstantiable()) {
Statement widgetInit = Stmt.invokeStatic(
ctx.getInjectionContext().getProcessingContext().getBootstrapClass(),
PrivateAccessUtil.getPrivateFieldInjectorName(ctx.getField()),
Refs.get(ctx.getInjector().getInstanceVarName()),
ObjectBuilder.newInstanceOf(widgetType));
statements.add(If.isNull(widget).append(widgetInit).finish());
}
}
else if (widgetType.isAssignableTo(Element.class)) {
widget = Stmt.invokeStatic(ElementWrapperWidget.class, "getWidget", widget);
}
else {
throw new GenerationException("@Bound field or method " + ctx.getMemberName()
+ " in class " + ctx.getInjector().getInjectedType()
+ " must provide a widget or DOM element type but provides: "
+ widgetType.getFullyQualifiedName());
}
// Generate the binding
Statement conv = bound.converter().equals(Bound.NO_CONVERTER.class) ? null : Stmt.newObject(bound.converter());
statements.add(Stmt.loadVariable("binder").invoke("bind", widget, property, conv));
}
else {
throw new GenerationException("No @Model or @AutoBound data binder found for @Bound field or method "
+ ctx.getMemberName() + " in class " + ctx.getInjector().getInjectedType());