/** * */ package org.javabuilders.swing.handler.binding; import java.util.HashMap; import java.util.Map; import javax.swing.JComboBox; import javax.swing.JList; import javax.swing.JTable; import org.javabuilders.BuildException; import org.javabuilders.BuildProcess; import org.javabuilders.BuilderConfig; import org.javabuilders.NamedObjectProperty; import org.javabuilders.Node; import org.javabuilders.handler.binding.AbstractBuilderBindingsHandler; import org.javabuilders.handler.binding.BindingSourceDefinition; import org.javabuilders.util.BuilderUtils; import org.jdesktop.beansbinding.Binding; import org.jdesktop.beansbinding.BindingGroup; import org.jdesktop.beansbinding.Bindings; import org.jdesktop.beansbinding.ELProperty; import org.jdesktop.beansbinding.AutoBinding.UpdateStrategy; import org.jdesktop.swingbinding.SwingBindings; import org.slf4j.Logger; import org.slf4j.LoggerFactory; /** * Default handler for binding logic across all domains * * @author Jacek Furmankiewicz */ public class BeansBindingTypeHandler extends AbstractBuilderBindingsHandler { /** * Property name for model */ public static final String MODEL = "model"; private final static Logger logger = LoggerFactory.getLogger(BeansBindingTypeHandler.class); private static final BeansBindingTypeHandler singleton = new BeansBindingTypeHandler(); private Map<String, UpdateStrategy> updateStrategies = new HashMap<String, UpdateStrategy>(); /** * @return Singleton */ public static BeansBindingTypeHandler getInstance() { return singleton; } /** * Constructor */ private BeansBindingTypeHandler() { super(); updateStrategies.put(READ, UpdateStrategy.READ); updateStrategies.put(READ_ONCE, UpdateStrategy.READ_ONCE); updateStrategies.put(READ_WRITE, UpdateStrategy.READ_WRITE); } /* * (non-Javadoc) * * @see * org.javabuilders.handler.ITypeHandler#useExistingInstance(org.javabuilders * .BuilderConfig, org.javabuilders.BuildProcess, org.javabuilders.Node, * java.lang.String, java.util.Map, java.lang.Object) */ public Node useExistingInstance(BuilderConfig config, BuildProcess process, Node parent, String key, Map<String, Object> typeDefinition, Object instance) throws BuildException { Node node = new Node(parent, key, typeDefinition); node.setMainObject(instance); BindingGroup bindingGroup = new BindingGroup(); process.getBuildResult().setBindingContext(bindingGroup); Map<NamedObjectProperty, BindingSourceDefinition> defs = getBindingDefinitions(node, process); for (NamedObjectProperty targetProperty : defs.keySet()) { BindingSourceDefinition sourceDef = defs.get(targetProperty); UpdateStrategy strategy = updateStrategies.get(sourceDef.getUpdateStrategy()); Object source = sourceDef.getSource(); String sourceExpression = sourceDef.getBindingExpression(); Object target = process.getByName(targetProperty.getName()); String targetExpression = targetProperty.getPropertyExpression(); Binding<Object, Object, Object, Object> binding = null; if (MODEL.equals(targetExpression)) { // request to bind to a mode - need to use special Swing binding // extension binding = createSwingBinding(source, sourceExpression, target, targetExpression, strategy, process); } else { // bind to regular JavaBean properties binding = createELPropertyBinding(source, sourceExpression, target, targetExpression, strategy, process); } if (binding != null) { bindingGroup.addBinding(binding); } } return node; } // create EL binding private Binding<Object, Object, Object, Object> createELPropertyBinding(Object sourceObject, String sourcePropertyPath, Object targetObject, String targetPropertyName, UpdateStrategy strategy, BuildProcess process) { ELProperty<Object, Object> sourceProperty = getELProperty(sourcePropertyPath); ELProperty<Object, Object> targetProperty = getELProperty(targetPropertyName); Binding<Object, Object, Object, Object> binding = Bindings.createAutoBinding(strategy, sourceObject, sourceProperty, targetObject, targetProperty); BuilderUtils.fireBindingEvent(process.getBuildResult(), binding); binding.bind(); if (logger.isDebugEnabled()) { logger.debug(String.format("Bound [%s].%s to [%s].%s] with update strategy %s", sourceObject.getClass().getSimpleName(), sourceProperty, targetObject.getClass().getSimpleName(), targetProperty, strategy)); } return binding; } // create Swing binding @SuppressWarnings({ "rawtypes", "unchecked" }) private Binding<Object, Object, Object, Object> createSwingBinding(Object sourceObject, String sourcePropertyPath, Object targetObject, String targetPropertyName, UpdateStrategy strategy, BuildProcess process) { Binding binding = null; if (targetObject instanceof JList) { JList list = (JList) targetObject; ELProperty listProperty = getELProperty(sourcePropertyPath); binding = SwingBindings.createJListBinding(strategy, sourceObject, listProperty, list); BuilderUtils.fireBindingEvent(process.getBuildResult(), binding); binding.bind(); } else if (targetObject instanceof JComboBox) { JComboBox box = (JComboBox) targetObject; ELProperty listProperty = getELProperty(sourcePropertyPath); binding = SwingBindings.createJComboBoxBinding(strategy, sourceObject, listProperty, box); BuilderUtils.fireBindingEvent(process.getBuildResult(), binding); binding.bind(); } else if (targetObject instanceof JTable) { //the complex one- needs column specific info return createJTableBinding(sourceObject, sourcePropertyPath, (JTable) targetObject, targetPropertyName, strategy, process); } return binding; } // create Swing binding private Binding<Object, Object, Object, Object> createJTableBinding(Object sourceObject, String sourcePropertyPath, JTable targetObject, String targetPropertyName, UpdateStrategy strategy, BuildProcess result) { return null; } // standard logic for a property private ELProperty<Object, Object> getELProperty(String path) { ELProperty<Object, Object> property = path.indexOf("${") >= 0 ? ELProperty.create(path) : ELProperty.create(String.format( "${%s}", path)); return property; } }