/* * (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.text.ParseException; import java.util.StringTokenizer; import java.util.logging.Level; import java.util.logging.Logger; import org.openflexo.antar.expr.EvaluationType; import org.openflexo.foundation.DataModification; import org.openflexo.foundation.FlexoModelObject; import org.openflexo.foundation.FlexoObservable; import org.openflexo.foundation.bindings.BindingDefinition.BindingDefinitionType; import org.openflexo.foundation.dkv.Domain; import org.openflexo.foundation.dkv.Key; import org.openflexo.foundation.dm.DMType; import org.openflexo.toolbox.Duration.DurationStringConverter; import org.openflexo.xmlcode.StringEncoder.DateConverter; public abstract class StaticBinding<T> extends AbstractBinding { @SuppressWarnings("hiding") static final Logger logger = Logger.getLogger(StaticBinding.class.getPackage().getName()); public StaticBinding() { super(); } public StaticBinding(BindingDefinition bindingDefinition, FlexoModelObject owner) { super(bindingDefinition, owner); } @Override public String getCodeStringRepresentation() { return getStringRepresentation(); } @Override public String getClassNameKey() { return "static_binding"; } @Override public String getFullyQualifiedName() { return "STATIC_BINDING=" + getSerializationRepresentation(); } public String getSerializationRepresentation() { return "$" + getStringRepresentation(); } @Override protected void _applyNewBindingDefinition() { // TODO Auto-generated method stub } // ========================================================== // ================= Serialization stuff ==================== // ========================================================== public static StaticBinding makeStaticBinding(String value, FlexoModelObject owner) { if (owner != null && owner.getProject() != null && owner instanceof Bindable) { StaticBindingStringConverter converter = owner.getProject().getStaticBindingConverter(); StaticBinding returned = converter.convertFromString(value); returned.setOwner(owner); return returned; } return null; } public StaticBinding getStaticBindingFromString(String aValue) { return getConverter().convertFromString(aValue); } public static class StaticBindingStringConverter extends AbstractBindingStringConverter<StaticBinding> { private DateConverter dateConverter = new DateConverter(); private DurationStringConverter durationConverter = new DurationStringConverter(); private Bindable _bindable; public StaticBindingStringConverter() { super(StaticBinding.class); } public Bindable getBindable() { return _bindable; } @Override public void setBindable(Bindable bindable) { _bindable = bindable; } @Override public StaticBinding convertFromString(String aValue) { if (aValue.startsWith("$") && aValue.length() > 1) { return convertFromString(aValue.substring(1)); } if (aValue.startsWith(DMType.DKV_PREFIX)) { if (_bindable != null) { StringTokenizer st = new StringTokenizer(aValue.substring(DMType.DKV_PREFIX.length()), "."); if (st.hasMoreTokens()) { String domainName = st.nextToken(); Domain domain = ((FlexoModelObject) _bindable).getProject().getDKVModel().getDomainNamed(domainName); if (domain != null && st.hasMoreTokens()) { Key key = domain.getKeyNamed(st.nextToken()); if (logger.isLoggable(Level.FINE)) { logger.fine("StaticBinding, found key: " + key); } if (key != null) { return new DKVBinding(null, null, key); } } } } } if (aValue.equalsIgnoreCase("true") || aValue.equalsIgnoreCase("yes")) { return new BooleanStaticBinding(true); } else if (aValue.equalsIgnoreCase("false") || aValue.equalsIgnoreCase("no")) { return new BooleanStaticBinding(false); } else if (aValue.startsWith("\"") && aValue.endsWith("\"") && aValue.length() > 1) { return new StringStaticBinding(aValue.substring(1, aValue.length() - 1)); } else if (aValue.startsWith("'") && aValue.endsWith("'") && aValue.length() > 1) { return new StringStaticBinding(aValue.substring(1, aValue.length() - 1)); } else if (aValue.indexOf(",") > -1) { try { return new DateStaticBinding(dateConverter.tryToConvertFromString(aValue)); } catch (ParseException e3) { // Lets continue... } } try { return new DurationStaticBinding(durationConverter.tryToConvertFromString(aValue)); } catch (ParseException e3) { // Lets continue... } try { return new IntegerStaticBinding(Long.parseLong(aValue)); } catch (NumberFormatException e) { try { return new FloatStaticBinding(Double.parseDouble(aValue)); } catch (NumberFormatException e2) { } } // Found nothing.... return null; } @Override public String convertToString(StaticBinding value) { return value.getSerializationRepresentation(); } } @Override public StaticBindingStringConverter getConverter() { if (getProject() != null) { return getProject().getStaticBindingConverter(); } return null; } @Override public void update(FlexoObservable observable, DataModification dataModification) { // TODO to be implemented } public abstract EvaluationType getEvaluationType(); public abstract T getValue(); public abstract void setValue(T aValue); @Override public void setsWith(AbstractBinding aValue) { super.setsWith(aValue); if (aValue != null) { if (aValue instanceof StaticBinding) { Object value = ((StaticBinding) aValue).getValue(); try { setValue((T) value); } catch (ClassCastException e) { logger.warning("setsWith() with mismatched types !!!"); } } else { logger.warning("setsWith called with mismatched type " + aValue.getClass().getSimpleName() + ", expected StaticBinding"); } } } @Override public boolean equals(Object object) { if (object == null) { return false; } if (object instanceof StaticBinding) { StaticBinding sb = (StaticBinding) object; if (getBindingDefinition() == null) { if (sb.getBindingDefinition() != null) { return false; } } else { if (!getBindingDefinition().equals(sb.getBindingDefinition())) { return false; } } return _owner == sb._owner && sb.getValue() != null && getValue().equals(sb.getValue()); } else { return super.equals(object); } } protected DMType accessedType = null; @Override public DMType getAccessedType() { if (getOwner() != null && getOwner().getProject() != null && accessedType == null) { return DMType.makeResolvedDMType(getOwner().getProject().getDataModel().getDMEntity(getStaticBindingClass())); } return accessedType; } public abstract Class<T> getStaticBindingClass(); @Override public boolean isBindingValid() { if (logger.isLoggable(Level.FINE)) { logger.fine("Is StaticBinding " + this + " valid ?"); } if (getAccessedType() == null) { if (logger.isLoggable(Level.FINE)) { logger.fine("Invalid binding because accessed type is null"); } return false; } if (getBindingDefinition() == null) { if (logger.isLoggable(Level.FINE)) { logger.fine("Invalid binding because binding definition is null"); } return false; } else if (getBindingDefinition().getIsSettable()) { if (logger.isLoggable(Level.FINE)) { logger.fine("Invalid binding because binding definition is declared as settable"); } return false; } else if (getBindingDefinition().getBindingDefinitionType() == BindingDefinitionType.EXECUTE) { if (logger.isLoggable(Level.FINE)) { logger.fine("Invalid binding because binding definition is declared as executable"); } return false; } if (getProject() == null) { if (logger.isLoggable(Level.WARNING)) { logger.warning("Project is null because owner is null for this binding value: " + getStringRepresentation() + " cannot determine if binding is valid"); } return true; } if (getAccessedType().isObject()) { return true; } if (_areTypesMatching()) { if (logger.isLoggable(Level.FINE)) { logger.fine("Valid binding"); } return true; } if (logger.isLoggable(Level.FINE)) { logger.fine("Invalid binding because types doesn't match: " + getAccessedType() + " cannot be assigned to " + getBindingDefinition().getType()); } return false; } protected boolean _areTypesMatching() { return getBindingDefinition().getType() == null || getBindingDefinition().getType().isAssignableFrom(getAccessedType(), true); } @Override public boolean isStaticValue() { return true; } @Override public abstract StaticBinding<T> clone(); @Override public String getJavaCodeStringRepresentation() { return getStringRepresentation(); } }