/******************************************************************************* * 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.papyrus.xwt.databinding; import org.eclipse.core.databinding.conversion.IConverter; import org.eclipse.core.databinding.observable.Diffs; import org.eclipse.core.databinding.observable.IObserving; import org.eclipse.core.databinding.observable.value.AbstractObservableValue; import org.eclipse.core.databinding.observable.value.ValueDiff; import org.eclipse.jface.util.Util; import org.eclipse.papyrus.xwt.XWT; /** * Notes: Binding type is java.lang.String. * * @author jliu (jin.liu@soyatec.com) */ public abstract class XWTObservableValue extends AbstractObservableValue implements IObserving { private Object observed; private Class<?> valueType; private EventManager eventManager; private EventListener eventListener; private String path; private boolean updating = false; /** * */ public XWTObservableValue(Class<?> valueType, Object observed, String path) { super(XWT.getRealm()); this.valueType = valueType; this.observed = observed; this.path = path; init(); } /** * Add listener to observed. */ private void init() { if(eventListener == null) { eventListener = new EventListener() { public void handleEvent(Event evt) { if(!updating) { final ValueDiff diff = Diffs.createValueDiff(evt.getOldValue(), evt.getNewValue()); getRealm().exec(new Runnable() { public void run() { fireValueChange(diff); } }); } } }; } eventManager = EventManager.getEventManager(observed, getRealm()); eventManager.addEventListener(path, eventListener); } /** * @return the observed */ public Object getObserved() { return observed; } /* * (non-Javadoc) * * @see org.eclipse.core.databinding.observable.value.AbstractObservableValue#doSetValue(java.lang.Object) */ protected void doSetValue(Object value) { updating = true; Object oldValue = doGetValue(); value = convert(oldValue == null ? null : oldValue.getClass(), value); if(!Util.equals(oldValue, value)) { doSetApprovedValue(value); fireValueChange(Diffs.createValueDiff(oldValue, value)); eventManager.dispatchEvent(new Event(observed, oldValue, value, getPath())); } updating = false; } /** * @param value * @return */ protected Object convert(Class type, Object value) { if(value != null) { if(type != null && type.isEnum() && value instanceof String) { return Enum.valueOf(type, (String)value); } IConverter c = XWT.findConvertor(value.getClass(), (Class<?>)getValueType()); if(c != null) { return c.convert(value); } } return value; } /** * @param value */ protected abstract void doSetApprovedValue(Object value); /* * (non-Javadoc) * * @see org.eclipse.core.databinding.observable.value.AbstractObservableValue#doGetValue() */ protected Object doGetValue() { return observed; } /* * (non-Javadoc) * * @see org.eclipse.core.databinding.observable.value.IObservableValue#getValueType() */ public Class<?> getValueType() { return valueType; } public String getPath() { return path; } public void setPath(String path) { this.path = path; } }