package gueei.binding;
import gueei.binding.ISyntaxResolver.SyntaxResolveException;
import gueei.binding.bindingProviders.BindingProvider;
import gueei.binding.exception.AttributeNotDefinedException;
import java.lang.ref.WeakReference;
import java.util.ArrayList;
import java.util.Map.Entry;
import android.content.Context;
import android.view.View;
public class AttributeBinder {
private static AttributeBinder _attributeFactory;
private ArrayList<BindingProvider> providers = new ArrayList<BindingProvider>(10);
protected AttributeBinder() {
}
/**
* Ensure it is Singleton
*
* @return
*/
public static AttributeBinder getInstance() {
if (_attributeFactory == null)
_attributeFactory = new AttributeBinder();
return _attributeFactory;
}
public ViewAttribute<?, ?> createAttributeForView(View view,
String attributeId) {
for (BindingProvider p : providers) {
ViewAttribute<?, ?> a = p.createAttributeForView(view, attributeId);
if (a != null)
return a;
}
return null;
}
public void registerProvider(BindingProvider provider) {
if (!providers.contains(provider))
providers.add(provider);
}
public void bindView(Context context, View view, Object model) {
BindingMap map = Binder.getBindingMapForView(view);
// TODO redesign this fix in future
// Force to initialize filter attribute
String filterKey = "filter";
String filterValue = map.get(filterKey);
if (null != filterValue) {
BindingLog.debug("bindView", "Attribute filter should be bind before initialize itemSource. To be sure that filtering will be worked.");
bindAttributeWithModel(context, view, filterKey, filterValue, model);
}
for(Entry<String, String> entry: map.getMapTable().entrySet()){
bindAttributeWithModel(context, view, entry.getKey(), entry.getValue(), model);
}
}
public boolean bindAttributeWithModel(Context context,
View view, String viewAttributeName, String statement, Object model) {
IObservable<?> property;
// Set the reference context to the current binding view
refViewAttributeProvider.viewContextRef = new WeakReference<View>(view);
try {
property = Binder.getSyntaxResolver()
.constructObservableFromStatement(context, statement, model, refViewAttributeProvider);
} catch (SyntaxResolveException e1) {
BindingLog.exception("AttributeBinder.bindAttributeWithObservable()", e1);
return false;
}
if (property != null) {
try {
ViewAttribute<?, ?> attr = Binder.getAttributeForView(view,
viewAttributeName);
BindingType result = attr.BindTo(context, property);
if (result.equals(BindingType.NoBinding)) {
BindingLog.warning("Binding Provider", statement
+ " cannot setup bind with attribute");
}
return true;
} catch (AttributeNotDefinedException e) {
BindingLog.exception("AttributeBinder.bindAttributeWithObservable()", e);
return false;
}
}
return false;
}
public boolean bindAttributeWithObservable(Context context, View view, String viewAttributeName, IObservable<?> obs){
try {
ViewAttribute<?,?> attr = Binder.getAttributeForView(view,
viewAttributeName);
BindingType result = attr.BindTo(context, obs);
if (result.equals(BindingType.NoBinding)) {
BindingLog.warning("Binding Provider", "Observable: " + obs
+ ", cannot setup bind with attribute");
}
return true;
} catch (AttributeNotDefinedException e) {
BindingLog.exception("AttributeBinder.bindAttributeWithObservable()", e);
return false;
}
}
private RefViewAttributeProvider refViewAttributeProvider =
new RefViewAttributeProvider();
private static class RefViewAttributeProvider implements IReferenceObservableProvider{
public WeakReference<View> viewContextRef;
public IObservable<?> getReferenceObservable(int referenceId,
String field) {
if (viewContextRef==null || viewContextRef.get()==null) return null;
View reference = viewContextRef.get().getRootView().findViewById(referenceId);
if (reference==null) return null;
try {
return Binder.getAttributeForView(reference, field);
} catch (AttributeNotDefinedException e) {
return null;
}
}
}
}