blob: aa1202654b7fe95a6fc981cdb7d886c960925953 [file] [log] [blame]
/*******************************************************************************
* 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.internal.core;
import org.eclipse.core.databinding.observable.IObservable;
import org.eclipse.core.databinding.observable.value.IObservableValue;
import org.eclipse.jface.viewers.Viewer;
import org.eclipse.swt.widgets.Control;
import org.eclipse.swt.widgets.Widget;
import org.eclipse.xwt.IDataProvider;
import org.eclipse.xwt.IValidationRule;
import org.eclipse.xwt.IValueConverter;
import org.eclipse.xwt.XWT;
import org.eclipse.xwt.XWTException;
import org.eclipse.xwt.core.IBinding;
import org.eclipse.xwt.core.IDynamicBinding;
import org.eclipse.xwt.databinding.ControlDataBinding;
import org.eclipse.xwt.databinding.DataBinding;
import org.eclipse.xwt.internal.utils.UserData;
/**
* Generic Binding definition
*
* @author yyang (yves.yang@soyatec.com)
*/
public class Binding extends DynamicBinding {
public static Binding[] EMPTY_ARRAY = new Binding[0];
private String name;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
private String path;
private Object source;
private String elementName;
private IValueConverter converter;
private IValidationRule[] validationRules = IValidationRule.EMPTY_ARRAY;
private IObservable observableSource;
public Binding() {
super();
}
/**
* <p>
* Default
* </p>
*
*/
private UpdateSourceTrigger updateSourceTrigger = UpdateSourceTrigger.Default;
private BindingExpressionPath pathSegments;
public BindingExpressionPath getPathPropertySegments() {
if (pathSegments == null) {
pathSegments = new BindingExpressionPath(getPath());
}
return pathSegments;
}
public UpdateSourceTrigger getUpdateSourceTrigger() {
return updateSourceTrigger;
}
public void setUpdateSourceTrigger(UpdateSourceTrigger updateSourceTrigger) {
this.updateSourceTrigger = updateSourceTrigger;
}
public IValueConverter getConverter() {
return converter;
}
public void setConverter(IValueConverter converter) {
this.converter = converter;
}
public String getPath() {
return path;
}
public Object getSource() {
return source;
}
public void setSource(Object source) {
this.source = source;
if (this.source instanceof IObservable) {
this.observableSource = (IObservable) this.source;
}
}
public void setPath(String path) {
this.path = path;
}
public String getElementName() {
return elementName;
}
public void setElementName(String elementName) {
this.elementName = elementName;
}
protected Object getSourceObject() {
if (source != null) {
return source;
} else if (elementName != null) {
return XWT.findElementByName(getControl(), elementName);
}
return null;
}
protected boolean isSelfBinding(Object data) {
if (data != this) {
return false;
}
Binding binding = (Binding) data;
return BindingExpressionPath.isEmptyPath(binding.getPath());
}
public Object createBoundSource() {
Object control = getControl();
Object source = getSourceObject();
if (source == null) {
source = XWT.getDataContext(control, IDynamicBinding.class);
Object localDataContext = UserData.getLocalDataContext(control);
if (localDataContext == this) {
return source;
}
}
if (source instanceof IDynamicBinding) {
Object value = ((IDynamicBinding) source).createBoundSource();
if (value != null && path != null) {
Widget widget = UserData.getWidget(value);
if (widget == null) {
widget = UserData.getWidget(control);
}
return ScopeManager.observeValue(widget, value,
getPathPropertySegments(), getUpdateSourceTrigger());
}
}
if (source != null && !BindingExpressionPath.isEmptyPath(path)) {
Widget widget = UserData.getWidget(source);
if (widget == null) {
widget = UserData.getWidget(control);
}
return ScopeManager.observeValue(widget, source,
getPathPropertySegments(), getUpdateSourceTrigger());
}
return source;
}
public boolean isSourceControl() {
Object source = getSourceObject();
if (source == null) {
Object dataContextHost = getDataContextHost();
if (dataContextHost != null) {
source = UserData.getLocalDataContext(dataContextHost);
}
}
if (source instanceof IDynamicBinding) {
return ((IDynamicBinding) source).isSourceControl();
}
if (source instanceof IBinding) {
source = ((IBinding) source).getValue(null);
}
if (path == null) {
return false;
}
int index = BindingExpressionPath.lastIndexOf(path);
if (index == -1) {
return (source instanceof Control || source instanceof Viewer);
}
if (source instanceof IDataProvider) {
return false;
}
String parentPath = path.substring(0, index);
IObservable observable = ScopeManager.observeValue(getControl(),
source, parentPath, getUpdateSourceTrigger());
if (observable != null) {
IObservableValue observableValue = (IObservableValue) observable;
Object type = observableValue.getValueType();
if (type != null) {
return UserData.isUIElementType(type);
}
}
return false;
}
public Object getValue(Class<?> targetType) {
Object dataContext = getSourceObject();
if (dataContext == null) {
Object dataContextHost = getDataContextHost();
if (dataContextHost != null) {
dataContext = UserData.getLocalDataContext(dataContextHost);
if (dataContext instanceof IDynamicBinding) {
IDynamicBinding dynamicBinding = (IDynamicBinding) dataContext;
Object boundSource = dynamicBinding.createBoundSource();
if (boundSource != null) {
dataContext = boundSource;
}
}
}
}
// direct binding
if (dataContext instanceof IBinding) {
dataContext = ((IBinding) dataContext).getValue(null);
}
IDataProvider dataProvider = getDataProvider(dataContext);
try {
if (isSourceControl()) {
ControlDataBinding controlDataBinding = new ControlDataBinding(
dataContext, this, dataProvider);
return controlDataBinding.getValue(targetType);
}
} catch (XWTException e) {
// in case the property cannot be bound. return value
}
DataBinding dataBinding = null;
if (dataProvider != null
&& (path != null || dataContext instanceof IObservable)) {
dataBinding = new DataBinding(this, dataProvider);
}
if (dataBinding != null) {
return dataBinding.getValue(targetType);
}
return convertedValue(dataContext);
}
private Object convertedValue(Object value) {
IValueConverter converter = getConverter();
if (converter != null) {
value = converter.convert(value);
}
return value;
}
public boolean isSourcePropertyReadOnly() {
IDataProvider dataProvider = getDataProvider();
try {
return ScopeManager.isPropertyReadOnly(dataProvider,
getPathPropertySegments());
} catch (XWTException e) {
}
return false;
}
public IObservable getObservableSource() {
return observableSource;
}
public void setObservableSource(IObservable observableSource) {
this.observableSource = observableSource;
}
/**
* Returns the validationRules for the binding
*
* @return the array of validationRules
*/
public IValidationRule[] getValidationRules() {
return this.validationRules;
}
/**
* Sets a single validationRule
*
* @param validator
*/
public IValidationRule getValidationRule() {
if (this.validationRules != null && this.validationRules.length > 0) {
return this.validationRules[0];
}
return null;
}
/**
* Set the validationRules for the binding
*
* @param validators
*/
public void setValidationRules(IValidationRule[] validationRules) {
this.validationRules = validationRules;
}
/**
* Sets a single validationRule
*
* @param validator
*/
public void setValidationRule(IValidationRule validationRule) {
this.validationRules = new IValidationRule[] { validationRule };
}
public void reset() {
observableSource = null;
}
}