/* * (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.bindings; import java.io.Serializable; import java.util.logging.Level; import java.util.logging.Logger; import org.openflexo.foundation.DataFlexoObserver; import org.openflexo.foundation.FlexoModelObject; import org.openflexo.foundation.dm.DMType; import org.openflexo.foundation.rm.FlexoProject; import org.openflexo.foundation.rm.XMLStorageResourceData; import org.openflexo.xmlcode.StringConvertable; import org.openflexo.xmlcode.StringEncoder; public abstract class AbstractBinding extends FlexoModelObject implements Bindable, DataFlexoObserver, Cloneable, StringConvertable<AbstractBinding>, Serializable { static final Logger logger = Logger.getLogger(BindingValue.class.getPackage().getName()); protected FlexoModelObject _owner; private BindingDefinition _bindingDefinition; protected String unparsableValue = null; public AbstractBinding() { super(null); } public AbstractBinding(BindingDefinition bindingDefinition, FlexoModelObject owner) { super(owner != null ? owner.getProject() : null); _owner = owner; setBindingDefinition(bindingDefinition); } public abstract String getStringRepresentation(); public abstract String getCodeStringRepresentation(); public abstract String getWodStringRepresentation(); @Override public abstract String getClassNameKey(); public abstract String getJavaCodeStringRepresentation(); @Override public final XMLStorageResourceData getXMLResourceData() { if (_owner != null) { return _owner.getXMLResourceData(); } return null; } public final FlexoModelObject getOwner() { return _owner; } public void setOwner(FlexoModelObject owner) { _owner = owner; if (_owner == null) { if (logger.isLoggable(Level.WARNING)) { logger.warning("Null owner declared for BindingValue"); } } else if (!(_owner instanceof Bindable)) { if (logger.isLoggable(Level.WARNING)) { logger.warning("Declared owner is not a Bindable !"); } } } @Override public final BindingModel getBindingModel() { if (_owner != null) { return ((Bindable) _owner).getBindingModel(); } return null; } @Override public final String toString() { return getFullyQualifiedName(); } @Override public abstract String getFullyQualifiedName(); public BindingDefinition getBindingDefinition() { return _bindingDefinition; } public final void setBindingDefinition(BindingDefinition bindingDefinition) { BindingDefinition oldBindingDefinition = getBindingDefinition(); if (oldBindingDefinition != bindingDefinition) { _bindingDefinition = bindingDefinition; _applyNewBindingDefinition(); if (logger.isLoggable(Level.FINE)) { logger.fine("Binding " + this + " received " + bindingDefinition + " as BindingDefinition"); } } } protected abstract void _applyNewBindingDefinition(); // ========================================================== // ================= Serialization stuff ==================== // ========================================================== public AbstractBinding getBindingFromString(String aValue) { return getConverter().convertFromString(aValue); } public static class AbstractBindingStringConverter<T extends AbstractBinding> extends StringEncoder.Converter<T> { private FlexoProject _project; boolean warnOnFailure = true; public AbstractBindingStringConverter(Class<T> aClass) { super(aClass); } public AbstractBindingStringConverter(Class<T> aClass, FlexoProject project) { super(aClass); _project = project; } public void setBindable(Bindable bindable) { _project.getBindingValueConverter().setBindable(bindable); _project.getBindingExpressionConverter().setBindable(bindable); _project.getStaticBindingConverter().setBindable(bindable); _project.getTranstypedBindingStringConverter().setBindable(bindable); } public void setWarnOnFailure(boolean aFlag) { if (_project != null && this == _project.getBindingValueConverter()) { logger.info("Sets warnOnFailure to be " + aFlag); } warnOnFailure = aFlag; if (_project != null && this == _project.getAbstractBindingConverter()) { if (_project.getBindingValueConverter() != this) { _project.getBindingValueConverter().setWarnOnFailure(aFlag); } if (_project.getBindingExpressionConverter() != this) { _project.getBindingExpressionConverter().setWarnOnFailure(aFlag); } if (_project.getStaticBindingConverter() != this) { _project.getStaticBindingConverter().setWarnOnFailure(aFlag); } if (_project.getTranstypedBindingStringConverter() != this) { _project.getTranstypedBindingStringConverter().setWarnOnFailure(aFlag); } } } @Override public T convertFromString(String value) { if (logger.isLoggable(Level.FINE)) { logger.fine("Decoding abstract binding: " + value); } if ("null".equals(value)) { return null; } StaticBinding decodedStringAsStaticBinding = _project.getStaticBindingConverter().convertFromString(value); if (decodedStringAsStaticBinding != null) { if (logger.isLoggable(Level.FINE)) { logger.fine("Succeeded to decode as a StaticBinding"); } return (T) decodedStringAsStaticBinding; } else { // Lets try as a binding value _project.getBindingValueConverter().setWarnOnFailure(false); BindingValue decodedStringAsBindingValue = _project.getBindingValueConverter().convertFromString(value); _project.getBindingValueConverter().setWarnOnFailure(true); if (decodedStringAsBindingValue != null) { if (logger.isLoggable(Level.FINE)) { logger.fine("Succeeded to decode as a BindingValue"); } return (T) decodedStringAsBindingValue; } else { // Lets try as a transtyped binding _project.getTranstypedBindingStringConverter().setWarnOnFailure(false); TranstypedBinding decodedStringAsTranstypedBinding = _project.getTranstypedBindingStringConverter().convertFromString( value); _project.getTranstypedBindingStringConverter().setWarnOnFailure(true); if (decodedStringAsTranstypedBinding != null) { if (logger.isLoggable(Level.FINE)) { logger.fine("Succeeded to decode as a TranstypedBinding"); } return (T) decodedStringAsTranstypedBinding; } else { // Lets try as an expression BindingExpression decodedStringAsBindingExpression = _project.getBindingExpressionConverter().convertFromString( value); if (logger.isLoggable(Level.FINE)) { logger.fine("Cound not decode as a BindingValue, trying as an expression"); } return (T) decodedStringAsBindingExpression; } } } } @Override public String convertToString(T value) { if (value instanceof BindingValue) { return _project.getBindingValueConverter().convertToString((BindingValue) value); } if (value instanceof BindingExpression) { return _project.getBindingExpressionConverter().convertToString((BindingExpression) value); } if (value instanceof StaticBinding) { return _project.getStaticBindingConverter().convertToString((StaticBinding) value); } if (value instanceof TranstypedBinding) { return _project.getTranstypedBindingStringConverter().convertToString((TranstypedBinding) value); } return "???"; } } @Override public AbstractBindingStringConverter<? extends AbstractBinding> getConverter() { if (getProject() != null) { return getProject().getAbstractBindingConverter(); } return null; } public void setsWith(AbstractBinding aValue) { if (aValue != null) { _owner = aValue._owner; _bindingDefinition = aValue.getBindingDefinition(); } } public abstract DMType getAccessedType(); public abstract boolean isBindingValid(); 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); } } public String getUnparsableValue() { return unparsableValue; } public void setUnparsableValue(String unparsableString) { this.unparsableValue = unparsableString; } }