/*
* (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.antar.binding;
import java.io.Serializable;
import java.lang.reflect.Type;
import java.util.List;
import java.util.logging.Logger;
import org.openflexo.antar.expr.NullReferenceException;
import org.openflexo.antar.expr.TypeMismatchException;
import org.openflexo.xmlcode.StringConvertable;
import org.openflexo.xmlcode.StringEncoder;
import org.openflexo.xmlcode.StringEncoder.Converter;
public abstract class AbstractBinding implements Bindable, Cloneable, StringConvertable<AbstractBinding>, Serializable {
static final Logger logger = Logger.getLogger(BindingValue.class.getPackage().getName());
/*public static BindingFactory abstractBindingConverter = new BindingFactory();
public static StaticBindingFactory staticBindingConverter = new StaticBindingFactory();
public static BindingExpressionFactory bindingExpressionConverter = new BindingExpressionFactory();
public static BindingValueFactory bindingValueConverter = new BindingValueFactory();*/
protected Bindable _owner;
private BindingDefinition _bindingDefinition;
protected String unparsableValue = null;
public AbstractBinding() {
super();
}
public AbstractBinding(BindingDefinition bindingDefinition, Bindable owner) {
this();
_owner = owner;
setBindingDefinition(bindingDefinition);
}
public abstract String getStringRepresentation();
public final Bindable getOwner() {
return _owner;
}
public void setOwner(Bindable owner) {
_owner = owner;
}
@Override
public final BindingModel getBindingModel() {
if (_owner != null) {
return _owner.getBindingModel();
}
return null;
}
@Override
public BindingFactory getBindingFactory() {
if (_owner != null) {
return _owner.getBindingFactory();
}
return null;
}
@Override
public final String toString() {
return getStringRepresentation();
}
public BindingDefinition getBindingDefinition() {
return _bindingDefinition;
}
public final void setBindingDefinition(BindingDefinition bindingDefinition) {
_bindingDefinition = bindingDefinition;
}
// ==========================================================
// ================= Serialization stuff ====================
// ==========================================================
public AbstractBinding getBindingFromString(String aValue) {
return getConverter().convertFromString(aValue);
}
@Override
public StringEncoder.Converter<? extends AbstractBinding> getConverter() {
if (getOwner() != null) {
return (Converter<? extends AbstractBinding>) getOwner().getBindingFactory();
}
return null;
// return abstractBindingConverter;
}
public void setsWith(AbstractBinding aValue) {
if (aValue != null) {
_owner = aValue._owner;
_bindingDefinition = aValue.getBindingDefinition();
}
}
public abstract Object getBindingValue(BindingEvaluationContext context) throws TypeMismatchException, NullReferenceException;
public abstract void setBindingValue(Object value, BindingEvaluationContext context);
public static interface BindingEvaluationContext {
public Object getValue(BindingVariable variable);
}
public abstract Type getAccessedType();
public abstract boolean isBindingValid();
public abstract boolean debugIsBindingValid();
public abstract String invalidBindingReason();
public abstract boolean isStaticValue();
@Override
public abstract AbstractBinding clone();
@Override
public boolean equals(Object object) {
if (object == null) {
return false;
}
if (object instanceof AbstractBinding) {
AbstractBinding bv = (AbstractBinding) object;
if (getBindingDefinition() == null) {
if (bv.getBindingDefinition() != null) {
return false;
}
} else {
if (!getBindingDefinition().equals(bv.getBindingDefinition())) {
return false;
}
}
return _owner == bv._owner && getStringRepresentation().equals(bv.getStringRepresentation());
} else {
return super.equals(object);
}
}
@Override
public int hashCode() {
return getStringRepresentation() == null ? getUnparsableValue().hashCode() : getStringRepresentation().hashCode();
}
public String getUnparsableValue() {
return unparsableValue;
}
public void setUnparsableValue(String unparsableString) {
this.unparsableValue = unparsableString;
}
public abstract boolean isSettable();
/**
* Build and return a list of objects (the current object path computed from supplied context)
*
* @param context
* @return
*/
public abstract List<Object> getConcernedObjects(BindingEvaluationContext context);
/**
* Build and return a list of target objects (the current object path computed from supplied context) Those objects are the one which
* are involved in the computation of this binding for the supplied context
*
* @param context
* @return
*/
public abstract List<TargetObject> getTargetObjects(BindingEvaluationContext context);
public static class TargetObject {
public Object target;
public String propertyName;
public TargetObject(Object target, String propertyName) {
super();
this.target = target;
this.propertyName = propertyName;
}
@Override
public String toString() {
return "TargetObject[" + target + "/" + propertyName + "]";
}
@Override
public boolean equals(Object obj) {
if (obj instanceof TargetObject) {
TargetObject t = (TargetObject) obj;
return target == t.target && propertyName != null && propertyName.equals(t.propertyName);
}
return super.equals(obj);
}
@Override
public int hashCode() {
return target.hashCode() + (propertyName == null ? 0 : propertyName.hashCode());
}
}
}