package org.openflexo.fge; import java.lang.reflect.Type; import java.util.ArrayList; import java.util.Collections; import java.util.Hashtable; import java.util.Iterator; import java.util.List; import java.util.Vector; import java.util.logging.Logger; import org.openflexo.antar.binding.AbstractBinding.BindingEvaluationContext; import org.openflexo.antar.binding.Bindable; import org.openflexo.antar.binding.BindingPathElement; import org.openflexo.antar.binding.BindingVariable; import org.openflexo.antar.binding.BindingVariableImpl; import org.openflexo.antar.binding.DefaultBindingFactory; import org.openflexo.antar.binding.FinalBindingPathElement; import org.openflexo.antar.binding.KeyValueLibrary; import org.openflexo.antar.binding.KeyValueProperty; import org.openflexo.antar.binding.ParameterizedTypeImpl; import org.openflexo.antar.binding.SimplePathElement; import org.openflexo.antar.binding.TypeUtils; import org.openflexo.fge.GraphicalRepresentation.GRParameter; import org.openflexo.fge.GraphicalRepresentation.Parameters; import org.openflexo.toolbox.ToolBox; public class GRBindingFactory extends DefaultBindingFactory { private static final Logger logger = Logger.getLogger(GRBindingFactory.class.getPackage().getName()); private static GRParameter[] allowedPropertiesInBindings = { Parameters.layer, Parameters.text, ShapeGraphicalRepresentation.Parameters.relativeTextX, ShapeGraphicalRepresentation.Parameters.relativeTextY, Parameters.absoluteTextX, Parameters.absoluteTextY, Parameters.isVisible, ShapeGraphicalRepresentation.Parameters.x, ShapeGraphicalRepresentation.Parameters.y, ShapeGraphicalRepresentation.Parameters.width, ShapeGraphicalRepresentation.Parameters.height, ShapeGraphicalRepresentation.Parameters.minimalWidth, ShapeGraphicalRepresentation.Parameters.minimalHeight, ShapeGraphicalRepresentation.Parameters.maximalWidth, ShapeGraphicalRepresentation.Parameters.maximalHeight }; private static Class<? extends GraphicalRepresentation<?>> DECLARING_CLASS; static { // Hack to have a grab on the Type Class<? extends GraphicalRepresentation<?> try { DECLARING_CLASS = (Class<? extends GraphicalRepresentation<?>>) Class.forName(GraphicalRepresentation.class.getName()); } catch (ClassNotFoundException e) { e.printStackTrace(); DECLARING_CLASS = null; } } /*@Override public BindingPathElement getBindingPathElement(BindingPathElement father, String propertyName) { if (father instanceof ComponentsBindingVariable) { for (ComponentPathElement c : ((ComponentsBindingVariable) father).getComponents()) { if (propertyName.equals(c.getLabel())) return c; } return null; } if (father instanceof ComponentPathElement) { return ((ComponentPathElement) father).getBindingPathElement(propertyName); } return null; } @Override public List<? extends BindingPathElement> getAccessibleBindingPathElements(BindingPathElement father) { if (father instanceof ComponentsBindingVariable) { return ((ComponentsBindingVariable) father).getComponents(); } if (father instanceof ComponentPathElement) { return ((ComponentPathElement) father).getAccessibleBindingPathElements(); } return EMPTY_LIST; }*/ private static boolean isAllowedProperty(String propertyName) { for (GRParameter p : allowedPropertiesInBindings) { if (propertyName.equals(p.name())) { return true; } } return false; } /*@Override public List<? extends BindingPathElement> getAccessibleCompoundBindingPathElements(BindingPathElement father) { return EMPTY_LIST; }*/ public static class VariableBindingPathElement implements SimplePathElement<Object>, FinalBindingPathElement<Object> { private GRVariable variable; public VariableBindingPathElement(GRVariable variable) { this.variable = variable; } @Override public Class<? extends GraphicalRepresentation<?>> getDeclaringClass() { return DECLARING_CLASS; } @Override public String getSerializationRepresentation() { return variable.getName(); } @Override public Type getType() { return variable.getType().getType(); } @Override public boolean isBindingValid() { return true; } @Override public String getLabel() { return variable.getName(); } @Override public String getTooltipText(Type resultingType) { String returned = "<html>"; String resultingTypeAsString; if (resultingType != null) { resultingTypeAsString = TypeUtils.simpleRepresentation(resultingType); resultingTypeAsString = ToolBox.replaceStringByStringInString("<", "<", resultingTypeAsString); resultingTypeAsString = ToolBox.replaceStringByStringInString(">", ">", resultingTypeAsString); } else { resultingTypeAsString = "???"; } returned += "<p><b>" + resultingTypeAsString + " " + variable.getName() + "</b></p>"; // returned += // "<p><i>"+(property.getDescription()!=null?property.getDescription():FlexoLocalization.localizedForKey("no_description"))+"</i></p>"; returned += "</html>"; return returned; } @Override public boolean isSettable() { return true; } @Override public Object getBindingValue(Object target, BindingEvaluationContext context) { return variable.getValue(); } @Override public void setBindingValue(Object value, Object target, BindingEvaluationContext context) { logger.info("Please implement me"); } } /** * Modelize a binding variable which is an access to all components in the whole hierarchy * * @author sylvain * */ public static class ComponentsBindingVariable extends BindingVariableImpl<Vector<GraphicalRepresentation<?>>> { private GraphicalRepresentation<?> owner; private Vector<ComponentPathElement> components; public ComponentsBindingVariable(GraphicalRepresentation<?> owner) { super(owner, "components", new ParameterizedTypeImpl(Vector.class, GraphicalRepresentation.class)); this.owner = owner; components = new Vector<GRBindingFactory.ComponentPathElement>(); Iterator<GraphicalRepresentation<?>> it = owner.getRootGraphicalRepresentation().allContainedGRIterator(); while (it.hasNext()) { GraphicalRepresentation<?> subComponent = it.next(); components.add(new ComponentPathElement(subComponent.getIdentifier(), subComponent, owner)); } } public GraphicalRepresentation<?> getOwner() { return owner; } public Vector<ComponentPathElement> getComponents() { return components; } } public static class ComponentPathElement implements SimplePathElement<GraphicalRepresentation<?>>, BindingVariable<GraphicalRepresentation<?>> { private String pathElementName; private GraphicalRepresentation<?> gr; private ComponentPathElement parent; private IndexPathElement index; private Hashtable<String, VariableBindingPathElement> variables; private Bindable container; public ComponentPathElement(String pathElementName, GraphicalRepresentation<?> gr, Bindable container) { this.pathElementName = pathElementName; this.gr = gr; this.container = container; index = new IndexPathElement(gr); if (gr.getParentGraphicalRepresentation() != null) { parent = new ComponentPathElement("parent", gr.getParentGraphicalRepresentation(), gr); } variables = new Hashtable<String, GRBindingFactory.VariableBindingPathElement>(); for (GRVariable v : getComponent().getVariables()) { variables.put(v.getName(), new VariableBindingPathElement(v)); } } public IndexPathElement getIndex() { return index; } public ComponentPathElement getParent() { return parent; } public GraphicalRepresentation<?> getComponent() { return gr; } @Override public Class<?> getDeclaringClass() { return container.getClass(); } @Override public Type getType() { return gr.getClass(); } @Override public String getSerializationRepresentation() { return pathElementName; } @Override public boolean isBindingValid() { return true; } @Override public String getLabel() { return getSerializationRepresentation(); } @Override public String getTooltipText(Type resultingType) { return getSerializationRepresentation(); } @Override public boolean isSettable() { return false; } @Override public Bindable getContainer() { return container; } @Override public String getVariableName() { return pathElementName; } @Override public GraphicalRepresentation<?> getBindingValue(Object target, BindingEvaluationContext context) { return gr; } @Override public void setBindingValue(GraphicalRepresentation<?> value, Object target, BindingEvaluationContext context) { // Not settable } } public static class IndexPathElement implements SimplePathElement<Integer>, FinalBindingPathElement<Integer> { private GraphicalRepresentation<?> gr; public IndexPathElement(GraphicalRepresentation<?> gr) { this.gr = gr; } public GraphicalRepresentation<?> getComponent() { return gr; } @Override public Class getDeclaringClass() { return gr.getClass(); } @Override public Type getType() { return Integer.TYPE; } @Override public String getSerializationRepresentation() { return "index"; } @Override public boolean isBindingValid() { return true; } @Override public String getLabel() { return getSerializationRepresentation(); } @Override public String getTooltipText(Type resultingType) { return getSerializationRepresentation(); } @Override public boolean isSettable() { return false; } @Override public Integer getBindingValue(Object target, BindingEvaluationContext context) { return gr.getIndex(); } @Override public void setBindingValue(Integer value, Object target, BindingEvaluationContext context) { // Not settable } } @Override public BindingPathElement getBindingPathElement(BindingPathElement father, String propertyName) { if (father instanceof ComponentsBindingVariable) { for (ComponentPathElement c : ((ComponentsBindingVariable) father).getComponents()) { if (propertyName.equals(c.getLabel())) { return c; } } return null; } else if (father instanceof ComponentPathElement) { if (propertyName.equals("index")) { return ((ComponentPathElement) father).getIndex(); } if (propertyName.equals("parent")) { return ((ComponentPathElement) father).getParent(); } for (GRParameter p : allowedPropertiesInBindings) { if (isAllowedProperty(propertyName)) { return KeyValueLibrary.getKeyValueProperty(((ComponentPathElement) father).getType(), propertyName); } } return ((ComponentPathElement) father).variables.get(propertyName); } return super.getBindingPathElement(father, propertyName); } @Override public List<? extends BindingPathElement> getAccessibleBindingPathElements(BindingPathElement father) { if (father instanceof ComponentsBindingVariable) { return ((ComponentsBindingVariable) father).getComponents(); } else if (father instanceof ComponentPathElement) { List<BindingPathElement> returned = new ArrayList<BindingPathElement>(); if (!((ComponentPathElement) father).getComponent().isRootGraphicalRepresentation()) { returned.add(((ComponentPathElement) father).getIndex()); returned.add(((ComponentPathElement) father).getParent()); } List<? extends BindingPathElement> all = KeyValueLibrary.getAccessibleProperties(((ComponentPathElement) father).getType()); for (BindingPathElement bpe : all) { if (isAllowedProperty(((KeyValueProperty) bpe).getName())) { returned.add(bpe); } } returned.addAll(((ComponentPathElement) father).variables.values()); return returned; } return super.getAccessibleBindingPathElements(father); } @Override public List<? extends BindingPathElement> getAccessibleCompoundBindingPathElements(BindingPathElement father) { if (father instanceof ComponentsBindingVariable) { return Collections.emptyList(); } else if (father instanceof ComponentPathElement) { return Collections.emptyList(); } return super.getAccessibleCompoundBindingPathElements(father); } }