| /******************************************************************************* |
| * Copyright (c) 2006, 2010 Soyatec (http://www.soyatec.com) and others. |
| * All rights reserved. This program and the accompanying materials |
| * are made available under the terms of the Eclipse Public License v1.0 |
| * which accompanies this distribution, and is available at |
| * http://www.eclipse.org/legal/epl-v10.html |
| * |
| * Contributors: |
| * Soyatec - initial API and implementation |
| *******************************************************************************/ |
| package org.eclipse.xwt.tools.ui.designer.databinding; |
| |
| import org.eclipse.core.runtime.Assert; |
| import org.eclipse.xwt.IConstants; |
| import org.eclipse.xwt.databinding.BindingMode; |
| import org.eclipse.xwt.internal.core.ScopeKeeper; |
| import org.eclipse.xwt.internal.core.UpdateSourceTrigger; |
| import org.eclipse.xwt.internal.utils.UserData; |
| import org.eclipse.gef.commands.Command; |
| import org.eclipse.gef.commands.CompoundCommand; |
| import org.eclipse.gef.commands.UnexecutableCommand; |
| import org.eclipse.swt.widgets.Widget; |
| import org.eclipse.xwt.tools.ui.designer.commands.AddNewChildCommand; |
| import org.eclipse.xwt.tools.ui.designer.commands.DeleteCommand; |
| import org.eclipse.xwt.tools.ui.designer.commands.NamedCommand; |
| import org.eclipse.xwt.tools.ui.designer.loader.XWTProxy; |
| import org.eclipse.xwt.tools.ui.xaml.XamlAttribute; |
| import org.eclipse.xwt.tools.ui.xaml.XamlDocument; |
| import org.eclipse.xwt.tools.ui.xaml.XamlElement; |
| import org.eclipse.xwt.tools.ui.xaml.XamlFactory; |
| import org.eclipse.xwt.tools.ui.xaml.XamlNode; |
| |
| /** |
| * @author jliu (jin.liu@soyatec.com) |
| */ |
| public class BindingInfo implements IBindingInfo, IBindingHandler, BindingConstants { |
| |
| private BindingContext context; |
| |
| private String elementName; |
| private BindingMode bindingMode; |
| private UpdateSourceTrigger triggerMode; |
| private String converter; |
| private CodeStyles codeStyles; |
| private XamlElement bindingNode; |
| |
| public BindingInfo(BindingContext bindingContext) { |
| Assert.isNotNull(bindingContext); |
| this.context = bindingContext; |
| } |
| |
| public BindingContext getBindingContext() { |
| return context; |
| } |
| |
| public void setBindingNode(XamlElement bindingNode) { |
| this.bindingNode = bindingNode; |
| } |
| |
| public XamlElement getBindingNode() { |
| return bindingNode; |
| } |
| |
| public void setConverter(String converter) { |
| this.converter = converter; |
| if (bindingNode != null) { |
| addAttr(bindingNode, CONVERTER, IConstants.XWT_NAMESPACE, converter); |
| } |
| } |
| |
| public String getConverter() { |
| return converter; |
| } |
| |
| public void setElementName(String elementName) { |
| this.elementName = elementName; |
| if (bindingNode != null) { |
| addAttr(bindingNode, ELEMENT_NAME, IConstants.XWT_NAMESPACE, elementName); |
| } |
| } |
| |
| public String getElementName() { |
| IObservable model = context.getModel(); |
| if (elementName == null && model != null && model.getType() == IObservable.OBSERVE_SWT_JFACE) { |
| Object source = model.getSource(); |
| elementName = getWidgetName(source); |
| } |
| return elementName; |
| } |
| |
| private String getWidgetName(Object widget) { |
| ScopeKeeper nameContext = UserData.findScopeKeeper(widget); |
| if (nameContext != null) { |
| for (String name : nameContext.names()) { |
| if (widget == nameContext.getNamedObject(name)) { |
| return name; |
| } |
| } |
| } |
| return null; |
| } |
| |
| public void setBindingMode(BindingMode bindingMode) { |
| this.bindingMode = bindingMode; |
| if (bindingNode != null) { |
| addAttr(bindingNode, MODE, IConstants.XWT_NAMESPACE, bindingMode.name()); |
| } |
| } |
| |
| public BindingMode getBindingMode() { |
| return bindingMode; |
| } |
| |
| public void setCodeStyles(CodeStyles codeStyles) { |
| if (codeStyles != null) { |
| this.codeStyles = codeStyles; |
| } |
| } |
| |
| public CodeStyles getCodeStyles() { |
| if (codeStyles == null) { |
| codeStyles = new CodeStyles(); |
| } |
| return codeStyles; |
| } |
| |
| private XamlAttribute getAttribute(XamlNode parent, String attrName, String namespace) { |
| XamlAttribute attribute = parent.getAttribute(attrName, namespace); |
| if (attribute == null) { |
| attribute = XamlFactory.eINSTANCE.createAttribute(attrName, namespace); |
| } |
| return attribute; |
| } |
| |
| private XamlElement getElement(XamlNode parent, String name, String namespace) { |
| XamlElement child = parent.getChild(name, namespace); |
| if (child == null) { |
| child = XamlFactory.eINSTANCE.createElement(name, namespace); |
| } |
| return child; |
| } |
| |
| private XamlAttribute addAttr(XamlNode parent, String attrName, String namespace, String value) { |
| if (parent == null || attrName == null || namespace == null) { |
| return null; |
| } |
| XamlAttribute attribute = parent.getAttribute(attrName, namespace); |
| if (attribute == null) { |
| attribute = XamlFactory.eINSTANCE.createAttribute(attrName, namespace); |
| } |
| attribute.setValue(value); |
| if (!parent.getAttributes().contains(attribute)) { |
| parent.getAttributes().add(attribute); |
| } |
| |
| return attribute; |
| } |
| |
| private String getCreateName(Object model, CompoundCommand commands) { |
| if (!(model instanceof Widget)) { |
| return null; |
| } |
| Widget widget = (Widget) model; |
| String original = getWidgetName(widget); |
| if (original != null) { |
| return original; |
| } |
| String elementName = getElementName(); |
| if (elementName == null) { |
| elementName = NamedCommand.generateName(widget); |
| } |
| commands.add(new NamedCommand(widget, elementName)); |
| UserData.setObjectName(widget, elementName); |
| return elementName; |
| } |
| |
| public boolean canBinding() { |
| return context.isValid(); |
| } |
| |
| public Command bindWithCommand() { |
| if (!canBinding()) { |
| return null; |
| } |
| CompoundCommand commandList = new CompoundCommand(); |
| |
| Property targetProperty = context.getTargetProperty(); |
| Property modelProperty = context.getModelProperty(); |
| IObservable target = context.getTarget(); |
| IObservable model = context.getModel(); |
| Object targetSource = target.getSource(); |
| |
| Object modelSource = model.getSource(); |
| |
| XamlNode node = null; |
| if (targetSource instanceof Widget) { |
| node = XWTProxy.getModel((Widget) targetSource); |
| } else if (targetSource instanceof XamlElement) { |
| node = (XamlElement) targetSource; |
| } |
| |
| if (node == null) { |
| return UnexecutableCommand.INSTANCE; |
| } |
| |
| // 1. Get attr of targetProperty, such as < text="{}"/> |
| XamlAttribute attribute = node.getAttribute(targetProperty.getName(), IConstants.XWT_NAMESPACE); |
| if (attribute != null) { |
| commandList.add(new DeleteCommand(attribute)); |
| attribute = null; |
| } |
| if (attribute == null) { |
| attribute = XamlFactory.eINSTANCE.createAttribute(targetProperty.getName(), IConstants.XWT_NAMESPACE); |
| } |
| // 2. Binding Node. |
| if (bindingNode == null) { |
| bindingNode = attribute.getChild(BINDING, IConstants.XWT_NAMESPACE); |
| } |
| if (bindingNode == null) { |
| bindingNode = XamlFactory.eINSTANCE.createElement(BINDING, IConstants.XWT_NAMESPACE); |
| } |
| // 3. ElementName |
| int type = model.getType(); |
| if (type == IObservable.OBSERVE_SWT_JFACE) { |
| addAttr(bindingNode, ELEMENT_NAME, IConstants.XWT_NAMESPACE, getCreateName(modelSource, commandList)); |
| } |
| // 4. DataContext |
| else if (IObservable.OBSERVE_JAVA_BAEN == type) { |
| XamlDocument ownerDocument = node.getOwnerDocument(); |
| XamlElement rootElement = ownerDocument.getRootElement(); |
| DataContext dataContext = (DataContext) modelSource; |
| String key = dataContext.getKey(); |
| if (key != null) { |
| boolean canUseDC = getCodeStyles().useDataContext; |
| if (canUseDC) { |
| XamlAttribute contextNode = getAttribute(rootElement, DATA_CONTEXT, IConstants.XWT_NAMESPACE); |
| contextNode.setUseFlatValue(true); |
| |
| XamlElement resourceNode = getElement(contextNode, STATIC_RESOURCE, IConstants.XWT_NAMESPACE); |
| if (!key.equals(resourceNode.getValue())) { |
| if (resourceNode.getValue() != null) { |
| canUseDC = false; |
| } else { |
| resourceNode.setValue(key); |
| commandList.add(new AddNewChildCommand(contextNode, resourceNode)); |
| commandList.add(new AddNewChildCommand(rootElement, contextNode)); |
| } |
| } |
| } |
| if (!canUseDC || !getCodeStyles().useDataContext) { |
| XamlAttribute sourceAttr = getAttribute(bindingNode, SOURCE, IConstants.XWT_NAMESPACE); |
| sourceAttr.setUseFlatValue(true); |
| XamlElement resourceNode = getElement(sourceAttr, STATIC_RESOURCE, IConstants.XWT_NAMESPACE); |
| |
| resourceNode.setValue(key); |
| commandList.add(new AddNewChildCommand(sourceAttr, resourceNode)); |
| commandList.add(new AddNewChildCommand(bindingNode, sourceAttr)); |
| } |
| } |
| } |
| |
| // 5. Path |
| addAttr(bindingNode, PATH, IConstants.XWT_NAMESPACE, modelProperty.toString()); |
| |
| // 6. BindingMode |
| if (bindingMode != null && BindingMode.TwoWay.equals(bindingMode)) { |
| addAttr(bindingNode, MODE, IConstants.XWT_NAMESPACE, bindingMode.name()); |
| } |
| |
| // 7. Converter. |
| if (converter != null) { |
| addAttr(bindingNode, CONVERTER, IConstants.XWT_NAMESPACE, converter); |
| } |
| |
| // 8. UpdateSourceTrigger |
| if (triggerMode != null) { |
| addAttr(bindingNode, UPDATE_SOURCE_TRIGGER, IConstants.XWT_NAMESPACE, triggerMode.name()); |
| } |
| |
| // 9. Code Style. |
| attribute.setUseFlatValue(getCodeStyles().useFlatVlaue); |
| |
| if (!attribute.getChildNodes().contains(bindingNode)) { |
| attribute.getChildNodes().add(bindingNode); |
| } |
| if (!node.getAttributes().contains(attribute)) { |
| commandList.add(new AddNewChildCommand(node, attribute)); |
| } |
| return commandList.unwrap(); |
| } |
| |
| public boolean canDelete() { |
| return bindingNode != null && bindingNode.eContainer() != null; |
| } |
| |
| public Command deleteWithCommand() { |
| if (canDelete()) { |
| XamlAttribute bindAttr = (XamlAttribute) bindingNode.eContainer(); |
| return new DeleteCommand(bindAttr); |
| } |
| return null; |
| } |
| |
| public IObservable getModel() { |
| return context.getModel(); |
| } |
| |
| public Property getModelProperty() { |
| return context.getModelProperty(); |
| } |
| |
| public IObservable getTarget() { |
| return context.getTarget(); |
| } |
| |
| public Property getTargetProperty() { |
| return context.getTargetProperty(); |
| } |
| |
| public UpdateSourceTrigger getTriggerMode() { |
| return triggerMode; |
| } |
| |
| public void setTriggerMode(UpdateSourceTrigger triggerMode) { |
| this.triggerMode = triggerMode; |
| } |
| } |