package fr.lteconsulting.hexa.databinding.gwt; import java.util.HashMap; import java.util.logging.Logger; import com.google.gwt.core.client.GWT; import com.google.gwt.user.client.ui.HasValue; import com.google.gwt.user.client.ui.TextBox; import fr.lteconsulting.hexa.databinding.Converters; import fr.lteconsulting.hexa.databinding.DataAdapterInfo; import fr.lteconsulting.hexa.databinding.PlatformSpecific; import fr.lteconsulting.hexa.databinding.gwt.propertyadapters.ValuePropertyAdapter; import fr.lteconsulting.hexa.databinding.properties.DynamicPropertyBag; import fr.lteconsulting.hexa.databinding.propertyadapters.CompositePropertyAdapter; import fr.lteconsulting.hexa.databinding.propertyadapters.PropertyAdapter; import fr.lteconsulting.hexa.databinding.tools.Property; public final class PlatformSpecificGwt implements PlatformSpecific { private static final PlatformSpecificGwt INSTANCE; static { Logger.getLogger(PlatformSpecificGwt.class.getName()).info("PlatformSpecificGwt STARTED"); INSTANCE = new PlatformSpecificGwt(); } public static PlatformSpecificGwt get() { return INSTANCE; } private PlatformSpecificGwt() {} private static class DynamicPropertyBagAccessJre { private static HashMap<Integer, DynamicPropertyBag> propertyBags = new HashMap<>(); static void setObjectDynamicPropertyBag(Object object, DynamicPropertyBag bag) { propertyBags.put(System.identityHashCode(object), bag); } static DynamicPropertyBag getObjectDynamicPropertyBag(Object object) { return propertyBags.get(System.identityHashCode(object)); } } @Override public DynamicPropertyBag getObjectDynamicPropertyBag(Object object) { if(GWT.isScript()) return getObjectDynamicPropertyBagImpl(object); else return DynamicPropertyBagAccessJre.getObjectDynamicPropertyBag(object); } private native DynamicPropertyBag getObjectDynamicPropertyBagImpl(Object object) /*-{ return object.__hexa_dynamic_ppty_bag || null; }-*/; @Override public void setObjectDynamicPropertyBag(Object object, DynamicPropertyBag bag) { if(GWT.isScript()) setObjectDynamicPropertyBagImpl(object, bag); else DynamicPropertyBagAccessJre.setObjectDynamicPropertyBag(object, bag); } private native void setObjectDynamicPropertyBagImpl(Object object, DynamicPropertyBag bag) /*-{ object.__hexa_dynamic_ppty_bag = bag; }-*/; @Override public boolean isBindingToken(String token) { return token.equals(CompositePropertyAdapter.HASVALUE_TOKEN); } @Override public <T> T getBindingValue(Object object, String token) { @SuppressWarnings({ "rawtypes", "unchecked" }) T result = (T) ((HasValue) object).getValue(); return result; } @Override public boolean setBindingValue(Object object, String name, Object value) { assert object instanceof HasValue : "Object should be implementing HasValue<?> !"; @SuppressWarnings("unchecked") HasValue<Object> hasValue = ((HasValue<Object>) object); hasValue.setValue(value, true); return true; } @Override public PropertyAdapter createPropertyAdapter(Object object) { return new ValuePropertyAdapter((HasValue<?>) object); } // Metadata private static class MetatdataJre { private static final HashMap<Integer, Object> metadatas = new HashMap<>(); static void setObjectMetadata(Object object, Object metadata) { metadatas.put(System.identityHashCode(object), metadata); } static <T> T getObjectMetadata(Object object) { @SuppressWarnings("unchecked") T result = (T) metadatas.get(System.identityHashCode(object)); return result; } } @Override public void setObjectMetadata(Object object, Object metadata) { if(GWT.isScript()) setObjectMetadataImpl(object, metadata); else MetatdataJre.setObjectMetadata(object, metadata); } private native void setObjectMetadataImpl(Object object, Object metadata) /*-{ object.__hexa_metadata = metadata; }-*/; @Override public <T> T getObjectMetadata(Object object) { if(GWT.isScript()) return getObjectMetadataImpl(object); else return MetatdataJre.getObjectMetadata(object); } private native <T> T getObjectMetadataImpl(Object object) /*-{ return object.__hexa_metadata || null; }-*/; // DTOMapper @Override public boolean isSpecificDataAdapter(Object object) { return object instanceof HasValue; } @Override public void fillSpecificDataAdapter(Object widget, Object context, String property, Class<?> srcPptyType, DataAdapterInfo res) { // try to guess the HasValue type res.setDataType(null); if(widget instanceof TextBox) res.setDataType(String.class); String debugString = ""; // try to find a converter if dataType does not match srcPptyType Class<?> dataType = res.getDataType(); if(srcPptyType != null && dataType != null && dataType != srcPptyType && srcPptyType != Property.class) { // try to find a converter, if not : fail res.setConverter(Converters.findConverter(srcPptyType, dataType)); if(res.getConverter() == null) debugString = "[ERROR: Cannot find converter from " + srcPptyType + " to " + dataType + "]"; else debugString = "[" + srcPptyType.getSimpleName() + ">" + dataType.getSimpleName() + "] " + debugString; } debugString += "\"" + property + ".$HasValue\""; res.setDebugString(debugString); res.setAdapter(new CompositePropertyAdapter(context, property + ".$HasValue")); } }