/* * (c) Copyright 2010-2011 AgileBirds * * This file is part of OpenFlexo. * * OpenFlexo is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * OpenFlexo is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with OpenFlexo. If not, see <http://www.gnu.org/licenses/>. * */ package org.openflexo.foundation.toc; import java.util.logging.Logger; import org.openflexo.antar.binding.AbstractBinding; import org.openflexo.antar.binding.AbstractBinding.BindingEvaluationContext; import org.openflexo.antar.binding.Bindable; import org.openflexo.antar.binding.BindingDefinition; import org.openflexo.antar.binding.BindingFactory; import org.openflexo.antar.expr.NullReferenceException; import org.openflexo.antar.expr.TypeMismatchException; import org.openflexo.xmlcode.StringConvertable; import org.openflexo.xmlcode.StringEncoder.Converter; public class TOCDataBinding implements StringConvertable<TOCDataBinding> { private static final Logger logger = Logger.getLogger(TOCDataBinding.class.getPackage().getName()); public static TOCDataBinding.DataBindingConverter CONVERTER = new DataBindingConverter(); public static class DataBindingConverter extends Converter<TOCDataBinding> { public DataBindingConverter() { super(TOCDataBinding.class); } @Override public TOCDataBinding convertFromString(String value) { return new TOCDataBinding(value); } @Override public String convertToString(TOCDataBinding value) { return value.toString(); }; } @Override public Converter<? extends TOCDataBinding> getConverter() { return CONVERTER; } private Bindable owner; private TOCBindingAttribute bindingAttribute; private String unparsedBinding; private BindingDefinition bindingDefinition; private AbstractBinding binding; public TOCDataBinding(Bindable owner, TOCBindingAttribute attribute, BindingDefinition df) { setOwner(owner); setBindingAttribute(attribute); setBindingDefinition(df); } public TOCDataBinding(String unparsed) { unparsedBinding = unparsed; } public Object getBindingValue(BindingEvaluationContext context) { // logger.info("getBindingValue() "+this); if (getBinding() != null) { try { return getBinding().getBindingValue(context); } catch (TypeMismatchException e) { return null; } catch (NullReferenceException e) { return null; } } return null; } public void setBindingValue(Object value, BindingEvaluationContext context) { if (getBinding() != null && getBinding().isSettable()) { getBinding().setBindingValue(value, context); } } @Override public String toString() { if (binding != null) { return binding.getStringRepresentation(); } return unparsedBinding; } public BindingDefinition getBindingDefinition() { return bindingDefinition; } public void setBindingDefinition(BindingDefinition bindingDefinition) { this.bindingDefinition = bindingDefinition; } public AbstractBinding getBinding() { if (binding == null) { finalizeDeserialization(); } return binding; } /*public void setBinding(AbstractBinding binding) { this.binding = binding; }*/ public void setBinding(AbstractBinding value) { System.out.println("TOCDataBinding: Set binding with " + value); AbstractBinding oldValue = this.binding; if (oldValue == null) { if (value == null) { return; // No change } else { this.binding = value; unparsedBinding = value != null ? value.getStringRepresentation() : null; updateDependancies(); if (bindingAttribute != null && owner instanceof TOCEntry) { ((TOCEntry) owner).notifyChange(bindingAttribute, oldValue, value); } if (owner instanceof TOCEntry) { ((TOCEntry) owner).notifyBindingChanged(this); } return; } } else { if (oldValue.equals(value)) { return; // No change } else { this.binding = value; unparsedBinding = value != null ? value.getStringRepresentation() : null; logger.info("Binding takes now value " + value); updateDependancies(); if (bindingAttribute != null && owner instanceof TOCEntry) { ((TOCEntry) owner).notifyChange(bindingAttribute, oldValue, value); } if (owner instanceof TOCEntry) { ((TOCEntry) owner).notifyBindingChanged(this); } return; } } } public boolean hasBinding() { return binding != null; } public boolean isValid() { return getBinding() != null && getBinding().isBindingValid(); } public boolean isSet() { return unparsedBinding != null || binding != null; } public boolean isUnset() { return unparsedBinding == null && binding == null; } public String getUnparsedBinding() { return unparsedBinding; } public void setUnparsedBinding(String unparsedBinding) { this.unparsedBinding = unparsedBinding; } public Bindable getOwner() { return owner; } public void setOwner(Bindable owner) { this.owner = owner; } protected void finalizeDeserialization() { if (getUnparsedBinding() == null) { return; } // System.out.println("BindingModel: "+getOwner().getBindingModel()); if (getOwner() != null) { BindingFactory factory = getOwner().getBindingFactory(); binding = factory.convertFromString(getUnparsedBinding(), getOwner()); binding.setBindingDefinition(getBindingDefinition()); // System.out.println(">>>>>>>>>>>>>> Binding: "+binding.getStringRepresentation()+" owner="+binding.getOwner()); // System.out.println("binding.isBindingValid()="+binding.isBindingValid()); } if (binding != null && !binding.isBindingValid()) { logger.warning("Binding not valid: " + binding + " for owner " + getOwner() + " context=" + getOwner()); /*logger.info("BindingModel="+getOwner().getBindingModel()); BindingExpression.logger.setLevel(Level.FINE); binding = factory.convertFromString(getUnparsedBinding()); binding.setBindingDefinition(getBindingDefinition()); binding.isBindingValid();*/ } updateDependancies(); } protected void updateDependancies() { if (binding == null) { return; } // logger.info("Searching dependancies for "+this); /*InspectorEntry component = getOwner(); List<TargetObject> targetList = binding.getTargetObjects(owner); if (targetList != null) { for (TargetObject o : targetList) { //System.out.println("> "+o.target+" for "+o.propertyName); if (o.target instanceof InspectorEntry) { InspectorEntry c = (InspectorEntry)o.target; InspectorBindingAttribute param = InspectorBindingAttribute.valueOf(o.propertyName); logger.info("OK, found "+getBindingAttribute()+" of "+getOwner()+" depends of "+param+" , "+c); try { component.declareDependantOf(c,getBindingAttribute(),param); } catch (DependancyLoopException e) { logger.warning("DependancyLoopException raised while declaring dependancy (data lookup)" +"in the context of binding: "+binding.getStringRepresentation() +" component: "+component +" dependancy: "+c +" message: "+e.getMessage()); } } } }*/ // Vector<Expression> primitives; // try { /*primitives = Expression.extractPrimitives(binding.getStringRepresentation()); GraphicalRepresentation component = getOwner(); GraphicalRepresentation rootComponent = component.getRootGraphicalRepresentation(); for (Expression p : primitives) { if (p instanceof Variable) { String fullVariable = ((Variable)p).getName(); if (fullVariable.indexOf(".") > 0) { String identifier = fullVariable.substring(0,fullVariable.indexOf(".")); String parameter = fullVariable.substring(fullVariable.indexOf(".")+1); logger.info("identifier="+identifier); logger.info("parameter="+parameter); Iterator<GraphicalRepresentation> allComponents = rootComponent.allGRIterator(); while (allComponents.hasNext()) { GraphicalRepresentation<?> next = allComponents.next(); if (next != getOwner()) { if (identifier.equals(next.getIdentifier())) { for (GRParameter param : next.getAllParameters()) { if (param.name().equals(parameter)) { logger.info("OK, found "+getBindingAttribute()+" of "+getOwner()+" depends of "+param+" , "+next); try { component.declareDependantOf(next,getBindingAttribute(),param); } catch (DependancyLoopException e) { logger.warning("DependancyLoopException raised while declaring dependancy (data lookup)" +"in the context of binding: "+binding.getStringRepresentation() +" fullVariable: "+fullVariable +" component: "+component +" dependancy: "+next +" identifier: "+next.getIdentifier() +" message: "+e.getMessage()); } } } } } } } } } } catch (ParseException e) { // TODO Auto-generated catch block e.printStackTrace(); } catch (TypeMismatchException e) { // TODO Auto-generated catch block e.printStackTrace(); } */ } public TOCBindingAttribute getBindingAttribute() { return bindingAttribute; } public void setBindingAttribute(TOCBindingAttribute bindingAttribute) { this.bindingAttribute = bindingAttribute; } @Override public boolean equals(Object obj) { if (obj instanceof TOCDataBinding) { if (toString() == null) { return false; } return toString().equals(obj.toString()); } else { return super.equals(obj); } } public static interface TOCBindingAttribute { } }