/*******************************************************************************
* Copyright (c) 2006-2013 The RCP Company 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:
* The RCP Company - initial API and implementation
*******************************************************************************/
package com.rcpcompany.uibindings.internal;
import java.util.ArrayList;
import java.util.Collection;
import java.util.List;
import org.eclipse.core.databinding.DataBindingContext;
import org.eclipse.core.databinding.observable.list.IObservableList;
import org.eclipse.core.databinding.observable.value.IObservableValue;
import org.eclipse.emf.common.notify.Adapter;
import org.eclipse.emf.common.notify.Notification;
import org.eclipse.emf.common.notify.NotificationChain;
import org.eclipse.emf.common.notify.impl.AdapterImpl;
import org.eclipse.emf.common.util.EList;
import org.eclipse.emf.ecore.EClass;
import org.eclipse.emf.ecore.EObject;
import org.eclipse.emf.ecore.EReference;
import org.eclipse.emf.ecore.EStructuralFeature;
import org.eclipse.emf.ecore.InternalEObject;
import org.eclipse.emf.ecore.impl.ENotificationImpl;
import org.eclipse.emf.ecore.util.EDataTypeUniqueEList;
import org.eclipse.emf.ecore.util.EObjectContainmentWithInverseEList;
import org.eclipse.emf.ecore.util.EObjectEList;
import org.eclipse.emf.ecore.util.InternalEList;
import org.eclipse.emf.edit.domain.EditingDomain;
import org.eclipse.jface.databinding.swt.SWTObservables;
import org.eclipse.jface.dialogs.TitleAreaDialog;
import org.eclipse.jface.viewers.ColumnViewer;
import org.eclipse.jface.wizard.WizardPage;
import org.eclipse.swt.SWT;
import org.eclipse.swt.custom.CTabFolder;
import org.eclipse.swt.events.DisposeEvent;
import org.eclipse.swt.events.DisposeListener;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Control;
import org.eclipse.swt.widgets.Event;
import org.eclipse.swt.widgets.Listener;
import org.eclipse.swt.widgets.Shell;
import org.eclipse.swt.widgets.TabFolder;
import org.eclipse.swt.widgets.Table;
import org.eclipse.swt.widgets.Widget;
import org.eclipse.ui.IWorkbenchPart;
import org.eclipse.ui.PlatformUI;
import org.eclipse.ui.forms.widgets.ScrolledForm;
import org.eclipse.ui.services.IServiceLocator;
import com.rcpcompany.uibindings.BindingState;
import com.rcpcompany.uibindings.IBinding;
import com.rcpcompany.uibindings.IBindingContext;
import com.rcpcompany.uibindings.IBindingContextFinalizer;
import com.rcpcompany.uibindings.IManager;
import com.rcpcompany.uibindings.IUIBindingsFactory;
import com.rcpcompany.uibindings.IUIBindingsPackage;
import com.rcpcompany.uibindings.IValueBinding;
import com.rcpcompany.uibindings.IViewerBinding;
import com.rcpcompany.uibindings.TextCommitStrategy;
import com.rcpcompany.uibindings.contextAdapters.ContextMessageDecorator;
import com.rcpcompany.uibindings.contextAdapters.IContextMessageDecoratorAdapter;
import com.rcpcompany.uibindings.contextAdapters.ScrolledFormContextMessageDecoratorAdapter;
import com.rcpcompany.uibindings.contextAdapters.TitleAreaDialogContextMessageDecoratorAdapter;
import com.rcpcompany.uibindings.contextAdapters.WizardPageContextMessageDecoratorAdapter;
import com.rcpcompany.uibindings.utils.EditingDomainUtils;
import com.rcpcompany.uibindings.utils.IManagerRunnable;
import com.rcpcompany.utils.logging.ITimedTask;
import com.rcpcompany.utils.logging.LogUtils;
/**
* <!-- begin-user-doc --> An implementation of the model object '<em><b>Binding Context</b></em>'.
* <!-- end-user-doc -->
* <p>
* The following features are implemented:
* <ul>
* <li>{@link com.rcpcompany.uibindings.internal.BindingContextImpl#getBindings <em>Bindings</em>}</li>
* <li>{@link com.rcpcompany.uibindings.internal.BindingContextImpl#getOkBindings <em>Ok Bindings
* </em>}</li>
* <li>{@link com.rcpcompany.uibindings.internal.BindingContextImpl#getTop <em>Top</em>}</li>
* <li>{@link com.rcpcompany.uibindings.internal.BindingContextImpl#getDbContext <em>Db Context
* </em>}</li>
* <li>{@link com.rcpcompany.uibindings.internal.BindingContextImpl#getServiceLocator <em>Service
* Locator</em>}</li>
* <li>{@link com.rcpcompany.uibindings.internal.BindingContextImpl#getState <em>State</em>}</li>
* <li>{@link com.rcpcompany.uibindings.internal.BindingContextImpl#getTextCommitStrategy <em>Text
* Commit Strategy</em>}</li>
* <li>{@link com.rcpcompany.uibindings.internal.BindingContextImpl#getTextCommitStrategyCalculated
* <em>Text Commit Strategy Calculated</em>}</li>
* <li>{@link com.rcpcompany.uibindings.internal.BindingContextImpl#getEditingDomain <em>Editing
* Domain</em>}</li>
* <li>{@link com.rcpcompany.uibindings.internal.BindingContextImpl#getFinalizers <em>Finalizers
* </em>}</li>
* </ul>
* </p>
*
* @generated
*/
public class BindingContextImpl extends BaseObjectImpl implements IBindingContext {
/**
* The cached value of the '{@link #getBindings() <em>Bindings</em>}' containment reference
* list. <!-- begin-user-doc --> <!-- end-user-doc -->
*
* @see #getBindings()
* @generated
* @ordered
*/
protected EList<IBinding> bindings;
/**
* The cached value of the '{@link #getOkBindings() <em>Ok Bindings</em>}' reference list. <!--
* begin-user-doc --> <!-- end-user-doc -->
*
* @see #getOkBindings()
* @generated
* @ordered
*/
protected EList<IBinding> okBindings;
/**
* The default value of the '{@link #getTop() <em>Top</em>}' attribute. <!-- begin-user-doc -->
* <!-- end-user-doc -->
*
* @see #getTop()
* @generated
* @ordered
*/
protected static final Composite TOP_EDEFAULT = null;
/**
* The cached value of the '{@link #getTop() <em>Top</em>}' attribute. <!-- begin-user-doc -->
* <!-- end-user-doc -->
*
* @see #getTop()
* @generated
* @ordered
*/
protected Composite top = TOP_EDEFAULT;
/**
* The default value of the '{@link #getDbContext() <em>Db Context</em>}' attribute. <!--
* begin-user-doc --> <!-- end-user-doc -->
*
* @see #getDbContext()
* @generated
* @ordered
*/
protected static final DataBindingContext DB_CONTEXT_EDEFAULT = null;
/**
* The cached value of the '{@link #getDbContext() <em>Db Context</em>}' attribute. <!--
* begin-user-doc --> <!-- end-user-doc -->
*
* @see #getDbContext()
* @generated
* @ordered
*/
protected DataBindingContext dbContext = DB_CONTEXT_EDEFAULT;
/**
* The default value of the '{@link #getServiceLocator() <em>Service Locator</em>}' attribute.
* <!-- begin-user-doc --> <!-- end-user-doc -->
*
* @see #getServiceLocator()
* @generated
* @ordered
*/
protected static final IServiceLocator SERVICE_LOCATOR_EDEFAULT = null;
/**
* The cached value of the '{@link #getServiceLocator() <em>Service Locator</em>}' attribute.
* <!-- begin-user-doc --> <!-- end-user-doc -->
*
* @see #getServiceLocator()
* @generated
* @ordered
*/
protected IServiceLocator serviceLocator = SERVICE_LOCATOR_EDEFAULT;
/**
* The default value of the '{@link #getState() <em>State</em>}' attribute. <!-- begin-user-doc
* --> <!-- end-user-doc -->
*
* @see #getState()
* @generated
* @ordered
*/
protected static final BindingState STATE_EDEFAULT = BindingState.INIT;
/**
* The cached value of the '{@link #getState() <em>State</em>}' attribute. <!-- begin-user-doc
* --> <!-- end-user-doc -->
*
* @see #getState()
* @generated
* @ordered
*/
protected BindingState state = STATE_EDEFAULT;
/**
* The default value of the '{@link #getTextCommitStrategy() <em>Text Commit Strategy</em>}'
* attribute. <!-- begin-user-doc --> Default is <code>null</code> meaning the value should be
* taken from the manager. <!-- end-user-doc -->
*
* @see #getTextCommitStrategy()
* @generated NOT
* @ordered
*/
protected static final TextCommitStrategy TEXT_COMMIT_STRATEGY_EDEFAULT = null;
/**
* The cached value of the '{@link #getTextCommitStrategy() <em>Text Commit Strategy</em>}'
* attribute. <!-- begin-user-doc --> <!-- end-user-doc -->
*
* @see #getTextCommitStrategy()
* @generated
* @ordered
*/
protected TextCommitStrategy textCommitStrategy = TEXT_COMMIT_STRATEGY_EDEFAULT;
/**
* The default value of the '{@link #getTextCommitStrategyCalculated()
* <em>Text Commit Strategy Calculated</em>}' attribute. <!-- begin-user-doc --> <!--
* end-user-doc -->
*
* @see #getTextCommitStrategyCalculated()
* @generated
* @ordered
*/
protected static final TextCommitStrategy TEXT_COMMIT_STRATEGY_CALCULATED_EDEFAULT = TextCommitStrategy.ON_MODIFY;
/**
* The cached value of the '{@link #getTextCommitStrategyCalculated()
* <em>Text Commit Strategy Calculated</em>}' attribute. <!-- begin-user-doc --> <!--
* end-user-doc -->
*
* @see #getTextCommitStrategyCalculated()
* @generated
* @ordered
*/
protected TextCommitStrategy textCommitStrategyCalculated = TEXT_COMMIT_STRATEGY_CALCULATED_EDEFAULT;
/**
* The default value of the '{@link #getEditingDomain() <em>Editing Domain</em>}' attribute.
* <!-- begin-user-doc --> <!-- end-user-doc -->
*
* @see #getEditingDomain()
* @generated
* @ordered
*/
protected static final EditingDomain EDITING_DOMAIN_EDEFAULT = null;
/**
* The cached value of the '{@link #getEditingDomain() <em>Editing Domain</em>}' attribute. <!--
* begin-user-doc --> <!-- end-user-doc -->
*
* @see #getEditingDomain()
* @generated
* @ordered
*/
protected EditingDomain editingDomain = EDITING_DOMAIN_EDEFAULT;
/**
* The cached value of the '{@link #getFinalizers() <em>Finalizers</em>}' attribute list. <!--
* begin-user-doc --> <!-- end-user-doc -->
*
* @see #getFinalizers()
* @generated
* @ordered
*/
protected EList<IBindingContextFinalizer> finalizers;
/**
* <!-- begin-user-doc -->Constructs and returns a new emptycontext.<!-- end-user-doc -->
*
* @generated NOT
*/
public BindingContextImpl() {
super();
dbContext = new DataBindingContext(SWTObservables.getRealm(PlatformUI.getWorkbench().getDisplay()));
// TODO Use the feature map
eAdapters().add(myAdapter);
final IManager manager = IManager.Factory.getManager();
manager.getContexts().add(this);
manager.eAdapters().add(myTextCommitStrategyAdapter);
// Force recalcalation of the attribute
getTextCommitStrategyCalculated();
}
/**
* <!-- begin-user-doc --> <!-- end-user-doc -->
*
* @generated
*/
@Override
protected EClass eStaticClass() {
return IUIBindingsPackage.Literals.BINDING_CONTEXT;
}
/**
* <!-- begin-user-doc --><!-- end-user-doc -->
*
* @generated
*/
@Override
public EList<IBinding> getBindings() {
if (bindings == null) {
bindings = new EObjectContainmentWithInverseEList<IBinding>(IBinding.class, this,
IUIBindingsPackage.BINDING_CONTEXT__BINDINGS, IUIBindingsPackage.BINDING__CONTEXT);
}
return bindings;
}
/**
* <!-- begin-user-doc --> <!-- end-user-doc -->
*
* @generated
*/
@Override
public EList<IBinding> getOkBindings() {
if (okBindings == null) {
okBindings = new EObjectEList<IBinding>(IBinding.class, this,
IUIBindingsPackage.BINDING_CONTEXT__OK_BINDINGS);
}
return okBindings;
}
/**
* <!-- begin-user-doc --> <!-- end-user-doc -->
*
* @generated
*/
@Override
public Composite getTop() {
return top;
}
/**
* Sets the top-level element for the context to the specified scrolled form.
*
* @param top the top element
*/
protected void setTop(final ScrolledForm top) {
myContextMessageDecoratorAdapter = new ScrolledFormContextMessageDecoratorAdapter(top);
myFormReflow = new IFormReflow() {
@Override
public void reflow() {
if (top.isDisposed()) return;
IManagerRunnable.Factory.asyncExec("reflow", top, new Runnable() {
@Override
public void run() {
if (top.isDisposed()) return;
top.layout(true, true);
top.reflow(true);
}
});
}
};
setTop(top.getBody());
}
/**
* Sets the top-level element for the context to the specified TitleAreaDialog.
*
* @param top the top element
*/
protected void setTop(final TitleAreaDialog top) {
myContextMessageDecoratorAdapter = new TitleAreaDialogContextMessageDecoratorAdapter(top);
myFormReflow = new IFormReflow() {
@Override
public void reflow() {
if (top.getShell().isDisposed()) return;
IManagerRunnable.Factory.asyncExec("reflow", top, new Runnable() {
@Override
public void run() {
if (top.getShell() == null || top.getShell().isDisposed()) return;
top.getShell().layout(true, true);
}
});
}
};
setTop(top.getShell());
}
/**
* Sets the top-level element for the context to the specified wizard page.
*
* @param page the wizard page
*/
protected void setTop(final WizardPage page) {
myContextMessageDecoratorAdapter = new WizardPageContextMessageDecoratorAdapter(page);
setTextCommitStrategy(TextCommitStrategy.ON_MODIFY);
final Shell shell = page.getWizard().getContainer().getShell();
myFormReflow = new IFormReflow() {
@Override
public void reflow() {
if (page.getControl() == null) return;
IManagerRunnable.Factory.asyncExec("reflow", page.getControl(), new Runnable() {
@Override
public void run() {
final Control control = page.getControl();
if (control == null || control.isDisposed()) return;
final Composite c = control.getParent();
if (c.isDisposed()) return;
c.layout(true, true);
}
});
}
};
setTop(shell);
}
/**
* <!-- begin-user-doc --> <!-- end-user-doc -->
*
* @generated NOT
*/
public void setTop(Composite newTop) {
setTopGen(newTop);
getTop().addDisposeListener(myDisposeListener);
if (myFormReflow == null) {
myFormReflow = new IFormReflow() {
@Override
public void reflow() {
if (getTop().isDisposed()) return;
IManagerRunnable.Factory.asyncExec("reflow", getTop(), new Runnable() {
@Override
public void run() {
if (getTop().isDisposed()) return;
getTop().layout(true, true);
}
});
}
};
}
}
/**
* <!-- begin-user-doc --> <!-- end-user-doc -->
*
* @generated
*/
public void setTopGen(Composite newTop) {
final Composite oldTop = top;
top = newTop;
if (eNotificationRequired()) {
eNotify(new ENotificationImpl(this, Notification.SET, IUIBindingsPackage.BINDING_CONTEXT__TOP, oldTop, top));
}
}
/**
* <!-- begin-user-doc --> <!-- end-user-doc -->
*
* @generated
*/
@Override
public DataBindingContext getDbContext() {
return dbContext;
}
/**
* <!-- begin-user-doc --> <!-- end-user-doc -->
*
* @generated NOT
*/
@Override
public IServiceLocator getServiceLocator() {
IServiceLocator sl = getServiceLocatorGen();
if (sl == null) {
final IWorkbenchPart activePart = PlatformUI.getWorkbench().getActiveWorkbenchWindow().getActivePage()
.getActivePart();
if (activePart != null) {
sl = activePart.getSite();
}
}
if (sl == null) {
sl = PlatformUI.getWorkbench();
}
return sl;
}
/**
* <!-- begin-user-doc --> <!-- end-user-doc -->
*
* @generated
*/
public IServiceLocator getServiceLocatorGen() {
return serviceLocator;
}
/**
* <!-- begin-user-doc --> <!-- end-user-doc -->
*
* @generated
*/
@Override
public void setServiceLocator(IServiceLocator newServiceLocator) {
final IServiceLocator oldServiceLocator = serviceLocator;
serviceLocator = newServiceLocator;
if (eNotificationRequired()) {
eNotify(new ENotificationImpl(this, Notification.SET, IUIBindingsPackage.BINDING_CONTEXT__SERVICE_LOCATOR,
oldServiceLocator, serviceLocator));
}
}
/**
* <!-- begin-user-doc --> <!-- end-user-doc -->
*
* @generated
*/
@Override
public BindingState getState() {
return state;
}
/**
* <!-- begin-user-doc --> <!-- end-user-doc -->
*
* @generated NOT
*/
public void setState(BindingState newState) {
final boolean runFinalizers = getState() != newState && newState == BindingState.OK;
setStateGen(newState);
if (runFinalizers && eIsSet(IUIBindingsPackage.Literals.BINDING_CONTEXT__FINALIZERS)) {
for (final IBindingContextFinalizer f : getFinalizers().toArray(
new IBindingContextFinalizer[getFinalizers().size()])) {
try {
f.run(this);
} catch (final Exception ex) {
LogUtils.error(f, ex);
}
}
}
}
/**
* <!-- begin-user-doc --> <!-- end-user-doc -->
*
* @generated NOT
*/
public void setStateGen(BindingState newState) {
final BindingState oldState = state;
state = newState == null ? STATE_EDEFAULT : newState;
if (eNotificationRequired()) {
eNotify(new ENotificationImpl(this, Notification.SET, IUIBindingsPackage.BINDING_CONTEXT__STATE, oldState,
state));
}
}
/**
* <!-- begin-user-doc --> <!-- end-user-doc -->
*
* @generated
*/
@Override
public TextCommitStrategy getTextCommitStrategy() {
return textCommitStrategy;
}
/**
* Sets the value of the '{@link IBindingContext#getTextCommitStrategy
* <em>Text Commit Strategy</em>}' attribute. <!-- begin-user-doc --> <!-- end-user-doc -->
*
* @param value the new value of the '<em>Text Commit Strategy</em>' attribute.
* @see #getTextCommitStrategy()
* @generated NOT
*/
@Override
public void setTextCommitStrategy(TextCommitStrategy newTextCommitStrategy) {
setTextCommitStrategyGen(newTextCommitStrategy);
getTextCommitStrategyCalculated();
}
/**
* <!-- begin-user-doc --> <!-- end-user-doc -->
*
* @generated
*/
public void setTextCommitStrategyGen(TextCommitStrategy newTextCommitStrategy) {
final TextCommitStrategy oldTextCommitStrategy = textCommitStrategy;
textCommitStrategy = newTextCommitStrategy == null ? TEXT_COMMIT_STRATEGY_EDEFAULT : newTextCommitStrategy;
if (eNotificationRequired()) {
eNotify(new ENotificationImpl(this, Notification.SET,
IUIBindingsPackage.BINDING_CONTEXT__TEXT_COMMIT_STRATEGY, oldTextCommitStrategy, textCommitStrategy));
}
}
private final Adapter myTextCommitStrategyAdapter = new AdapterImpl() {
@Override
public void notifyChanged(Notification msg) {
if (msg.isTouch()) return;
if (msg.getFeature() == IUIBindingsPackage.Literals.MANAGER__TEXT_COMMIT_STRATEGY) {
getTextCommitStrategyCalculated();
}
}
};
/**
* <!-- begin-user-doc --> <!-- end-user-doc -->
*
* @generated NOT
*/
@Override
public TextCommitStrategy getTextCommitStrategyCalculated() {
TextCommitStrategy strategy = getTextCommitStrategy();
if (strategy == null) {
strategy = IManager.Factory.getManager().getTextCommitStrategy();
}
final TextCommitStrategy oldTextCommitStrategyCalculated = textCommitStrategyCalculated;
textCommitStrategyCalculated = strategy;
if (oldTextCommitStrategyCalculated != textCommitStrategyCalculated && eNotificationRequired()) {
eNotify(new ENotificationImpl(this, Notification.SET,
IUIBindingsPackage.BINDING_CONTEXT__TEXT_COMMIT_STRATEGY_CALCULATED,
oldTextCommitStrategyCalculated, textCommitStrategyCalculated));
}
return textCommitStrategyCalculated;
}
/**
* <!-- begin-user-doc --> <!-- end-user-doc -->
*
* @generated NOT
*/
@Override
public EditingDomain getEditingDomain() {
if (editingDomain == null) return EditingDomainUtils.getEditingDomain();
return editingDomain;
}
/**
* <!-- begin-user-doc --> <!-- end-user-doc -->
*
* @generated
*/
@Override
public void setEditingDomain(EditingDomain newEditingDomain) {
final EditingDomain oldEditingDomain = editingDomain;
editingDomain = newEditingDomain;
if (eNotificationRequired()) {
eNotify(new ENotificationImpl(this, Notification.SET, IUIBindingsPackage.BINDING_CONTEXT__EDITING_DOMAIN,
oldEditingDomain, editingDomain));
}
}
/**
* <!-- begin-user-doc --> <!-- end-user-doc -->
*
* @generated
*/
@Override
public EList<IBindingContextFinalizer> getFinalizers() {
if (finalizers == null) {
finalizers = new EDataTypeUniqueEList<IBindingContextFinalizer>(IBindingContextFinalizer.class, this,
IUIBindingsPackage.BINDING_CONTEXT__FINALIZERS);
}
return finalizers;
}
/**
* <!-- begin-user-doc --> <!-- end-user-doc -->
*
* @generated
*/
@SuppressWarnings("unchecked")
@Override
public NotificationChain eInverseAdd(InternalEObject otherEnd, int featureID, NotificationChain msgs) {
switch (featureID) {
case IUIBindingsPackage.BINDING_CONTEXT__BINDINGS:
return ((InternalEList<InternalEObject>) (InternalEList<?>) getBindings()).basicAdd(otherEnd, msgs);
}
return super.eInverseAdd(otherEnd, featureID, msgs);
}
/**
* <!-- begin-user-doc --> <!-- end-user-doc -->
*
* @generated
*/
@Override
public NotificationChain eInverseRemove(InternalEObject otherEnd, int featureID, NotificationChain msgs) {
switch (featureID) {
case IUIBindingsPackage.BINDING_CONTEXT__BINDINGS:
return ((InternalEList<?>) getBindings()).basicRemove(otherEnd, msgs);
}
return super.eInverseRemove(otherEnd, featureID, msgs);
}
/**
* <!-- begin-user-doc --> <!-- end-user-doc -->
*
* @generated
*/
@Override
public Object eGet(int featureID, boolean resolve, boolean coreType) {
switch (featureID) {
case IUIBindingsPackage.BINDING_CONTEXT__BINDINGS:
return getBindings();
case IUIBindingsPackage.BINDING_CONTEXT__OK_BINDINGS:
return getOkBindings();
case IUIBindingsPackage.BINDING_CONTEXT__TOP:
return getTop();
case IUIBindingsPackage.BINDING_CONTEXT__DB_CONTEXT:
return getDbContext();
case IUIBindingsPackage.BINDING_CONTEXT__SERVICE_LOCATOR:
return getServiceLocator();
case IUIBindingsPackage.BINDING_CONTEXT__STATE:
return getState();
case IUIBindingsPackage.BINDING_CONTEXT__TEXT_COMMIT_STRATEGY:
return getTextCommitStrategy();
case IUIBindingsPackage.BINDING_CONTEXT__TEXT_COMMIT_STRATEGY_CALCULATED:
return getTextCommitStrategyCalculated();
case IUIBindingsPackage.BINDING_CONTEXT__EDITING_DOMAIN:
return getEditingDomain();
case IUIBindingsPackage.BINDING_CONTEXT__FINALIZERS:
return getFinalizers();
}
return super.eGet(featureID, resolve, coreType);
}
/**
* <!-- begin-user-doc --> <!-- end-user-doc -->
*
* @generated
*/
@SuppressWarnings("unchecked")
@Override
public void eSet(int featureID, Object newValue) {
switch (featureID) {
case IUIBindingsPackage.BINDING_CONTEXT__BINDINGS:
getBindings().clear();
getBindings().addAll((Collection<? extends IBinding>) newValue);
return;
case IUIBindingsPackage.BINDING_CONTEXT__OK_BINDINGS:
getOkBindings().clear();
getOkBindings().addAll((Collection<? extends IBinding>) newValue);
return;
case IUIBindingsPackage.BINDING_CONTEXT__TOP:
setTop((Composite) newValue);
return;
case IUIBindingsPackage.BINDING_CONTEXT__SERVICE_LOCATOR:
setServiceLocator((IServiceLocator) newValue);
return;
case IUIBindingsPackage.BINDING_CONTEXT__STATE:
setState((BindingState) newValue);
return;
case IUIBindingsPackage.BINDING_CONTEXT__TEXT_COMMIT_STRATEGY:
setTextCommitStrategy((TextCommitStrategy) newValue);
return;
case IUIBindingsPackage.BINDING_CONTEXT__EDITING_DOMAIN:
setEditingDomain((EditingDomain) newValue);
return;
case IUIBindingsPackage.BINDING_CONTEXT__FINALIZERS:
getFinalizers().clear();
getFinalizers().addAll((Collection<? extends IBindingContextFinalizer>) newValue);
return;
}
super.eSet(featureID, newValue);
}
/**
* <!-- begin-user-doc --> <!-- end-user-doc -->
*
* @generated
*/
@Override
public void eUnset(int featureID) {
switch (featureID) {
case IUIBindingsPackage.BINDING_CONTEXT__BINDINGS:
getBindings().clear();
return;
case IUIBindingsPackage.BINDING_CONTEXT__OK_BINDINGS:
getOkBindings().clear();
return;
case IUIBindingsPackage.BINDING_CONTEXT__TOP:
setTop(TOP_EDEFAULT);
return;
case IUIBindingsPackage.BINDING_CONTEXT__SERVICE_LOCATOR:
setServiceLocator(SERVICE_LOCATOR_EDEFAULT);
return;
case IUIBindingsPackage.BINDING_CONTEXT__STATE:
setState(STATE_EDEFAULT);
return;
case IUIBindingsPackage.BINDING_CONTEXT__TEXT_COMMIT_STRATEGY:
setTextCommitStrategy(TEXT_COMMIT_STRATEGY_EDEFAULT);
return;
case IUIBindingsPackage.BINDING_CONTEXT__EDITING_DOMAIN:
setEditingDomain(EDITING_DOMAIN_EDEFAULT);
return;
case IUIBindingsPackage.BINDING_CONTEXT__FINALIZERS:
getFinalizers().clear();
return;
}
super.eUnset(featureID);
}
/**
* <!-- begin-user-doc --> <!-- end-user-doc -->
*
* @generated
*/
@Override
public boolean eIsSet(int featureID) {
switch (featureID) {
case IUIBindingsPackage.BINDING_CONTEXT__BINDINGS:
return bindings != null && !bindings.isEmpty();
case IUIBindingsPackage.BINDING_CONTEXT__OK_BINDINGS:
return okBindings != null && !okBindings.isEmpty();
case IUIBindingsPackage.BINDING_CONTEXT__TOP:
return TOP_EDEFAULT == null ? top != null : !TOP_EDEFAULT.equals(top);
case IUIBindingsPackage.BINDING_CONTEXT__DB_CONTEXT:
return DB_CONTEXT_EDEFAULT == null ? dbContext != null : !DB_CONTEXT_EDEFAULT.equals(dbContext);
case IUIBindingsPackage.BINDING_CONTEXT__SERVICE_LOCATOR:
return SERVICE_LOCATOR_EDEFAULT == null ? serviceLocator != null : !SERVICE_LOCATOR_EDEFAULT
.equals(serviceLocator);
case IUIBindingsPackage.BINDING_CONTEXT__STATE:
return state != STATE_EDEFAULT;
case IUIBindingsPackage.BINDING_CONTEXT__TEXT_COMMIT_STRATEGY:
return textCommitStrategy != TEXT_COMMIT_STRATEGY_EDEFAULT;
case IUIBindingsPackage.BINDING_CONTEXT__TEXT_COMMIT_STRATEGY_CALCULATED:
return textCommitStrategyCalculated != TEXT_COMMIT_STRATEGY_CALCULATED_EDEFAULT;
case IUIBindingsPackage.BINDING_CONTEXT__EDITING_DOMAIN:
return EDITING_DOMAIN_EDEFAULT == null ? editingDomain != null : !EDITING_DOMAIN_EDEFAULT
.equals(editingDomain);
case IUIBindingsPackage.BINDING_CONTEXT__FINALIZERS:
return finalizers != null && !finalizers.isEmpty();
}
return super.eIsSet(featureID);
}
/**
* <!-- begin-user-doc --> <!-- end-user-doc -->
*
* @generated
*/
@Override
public String toString() {
if (eIsProxy()) return super.toString();
final StringBuffer result = new StringBuffer(super.toString());
result.append(" (top: "); //$NON-NLS-1$
result.append(top);
result.append(", dbContext: "); //$NON-NLS-1$
result.append(dbContext);
result.append(", serviceLocator: "); //$NON-NLS-1$
result.append(serviceLocator);
result.append(", state: "); //$NON-NLS-1$
result.append(state);
result.append(", textCommitStrategy: "); //$NON-NLS-1$
result.append(textCommitStrategy);
result.append(", textCommitStrategyCalculated: "); //$NON-NLS-1$
result.append(textCommitStrategyCalculated);
result.append(", editingDomain: "); //$NON-NLS-1$
result.append(editingDomain);
result.append(", finalizers: "); //$NON-NLS-1$
result.append(finalizers);
result.append(')');
return result.toString();
}
@Override
public IValueBinding addBinding() {
final IValueBinding binding = IUIBindingsFactory.eINSTANCE.createValueBinding();
binding.setContext(this);
return binding;
}
@Override
public IValueBinding addBinding(Widget widget, EObject object, EStructuralFeature feature) {
return addBinding().ui(widget).model(object, feature);
}
@Override
public IValueBinding addBinding(Widget widget, String attribute, EObject object, EStructuralFeature feature) {
return addBinding().ui(widget, attribute).model(object, feature);
}
@Override
public IValueBinding addBinding(Widget widget, IObservableValue object, EStructuralFeature feature) {
return addBinding().ui(widget).model(object, feature);
}
@Override
public IValueBinding addBinding(Widget widget, String attribute, IObservableValue object, EStructuralFeature feature) {
return addBinding().ui(widget, attribute).model(object, feature);
}
@Override
public IViewerBinding addViewer() {
final IViewerBinding binding = IUIBindingsFactory.eINSTANCE.createViewerBinding();
binding.setContext(this);
return binding;
}
@Override
public IViewerBinding addViewer(ColumnViewer viewer, EObject object, EReference reference) {
return addViewer().viewer(viewer).model(object, reference);
}
@Override
public IViewerBinding addViewer(Table table, EObject object, EReference reference) {
return addViewer().viewer(table).model(object, reference);
}
@Override
public IViewerBinding addViewer(Table table, IObservableValue object, EReference reference) {
return addViewer().viewer(table).model(object, reference);
}
@Override
public IViewerBinding addViewer(ColumnViewer viewer, IObservableValue object, EReference reference) {
return addViewer().viewer(viewer).model(object, reference);
}
@Override
public IViewerBinding addViewer(ColumnViewer viewer, IObservableList list) {
return addViewer().viewer(viewer).model(list);
// return new ViewerBinding(this, viewer, list);
}
/**
* Guards {@link #finish()}.
*/
private boolean isInFinish = false;
/**
* Set to <code>true</code> when all needed support has been hooked into the context in
* {@link #finish()}.
*/
private boolean hasSupportBeenAdded = false;
/**
* List of all new the bindings.
*/
protected final List<IBinding> myNewBindings = new ArrayList<IBinding>();
/**
* Shows whether {@link #finish()} has been deferred.
*/
protected boolean myFinishDeferred = false;
/**
* List of {@link TabFolder TabFolders} that hosts UI Bindings widgets.
* <p>
* Each of these have an extra listener used to ensure a tab item is {@link #reflow() reflowed}
* when made visible.
*/
private List<Control> myTabFolders = null;
/**
* Listener used to reflow tab items - see {@link #myTabFolders}.
*/
private Listener myTabFolderListener = null;
@Override
public void finish() {
finish(FinishOption.LAZY);
}
@Override
public void finish(FinishOption option) {
switch (option) {
case IF_ALREADY_FINISHED:
switch (getState()) {
case OK:
case PHASE1:
case PHASE2:
case PHASE3:
break;
default:
return;
}
//$FALL-THROUGH$ fallthrough
case LAZY:
finishDeferred();
// if (myFinishDeferred)
// return;
//
// getTop().getDisplay().asyncExec(new Runnable() {
// @Override
// public void run() {
// finishDeferred();
// }
// });
// myFinishDeferred = true;
break;
case FORCE:
default:
finishDeferred();
break;
}
}
/**
* Deferred version of {@link #finish()}.
*/
protected void finishDeferred() {
myFinishDeferred = false;
if (isInFinish) {
if (Activator.getDefault().TRACE_LIFECYCLE_BINDINGS) {
LogUtils.debug(this, "recursive finish"); //$NON-NLS-1$
}
return;
}
final ITimedTask task = ITimedTask.Factory.start("finish Defered");
try {
isInFinish = true;
if (Activator.getDefault().TRACE_LIFECYCLE_BINDINGS) {
LogUtils.debug(this, "finish start"); //$NON-NLS-1$
}
final List<IBinding> bindingsToProcess = new ArrayList<IBinding>();
while (myNewBindings.size() > 0) {
bindingsToProcess.addAll(myNewBindings);
myNewBindings.clear();
for (final IBinding b : bindingsToProcess) {
if (myNewBindings.size() > 0) {
break;
}
if (b.getState() == BindingState.INIT) {
setState(BindingState.PHASE1);
b.setState(BindingState.PHASE1);
try {
task.subTask("1:", b);
b.finish1();
} catch (final Exception ex) {
LogUtils.error(b, ex);
b.setState(BindingState.DISPOSE_PENDING);
continue;
}
}
}
for (final IBinding b : bindingsToProcess) {
if (myNewBindings.size() > 0) {
break;
}
if (b.getState() == BindingState.PHASE1) {
setState(BindingState.PHASE2);
b.setState(BindingState.PHASE2);
try {
task.subTask("2:", b);
b.finish2();
} catch (final Exception ex) {
LogUtils.error(b, ex);
b.setState(BindingState.DISPOSE_PENDING);
continue;
}
}
}
for (final IBinding b : bindingsToProcess) {
if (myNewBindings.size() > 0) {
break;
}
if (b.getState() == BindingState.PHASE2) {
setState(BindingState.PHASE3);
b.setState(BindingState.PHASE3);
try {
task.subTask("3:", b);
b.finish3();
} catch (final Exception ex) {
LogUtils.error(b, ex);
b.setState(BindingState.DISPOSE_PENDING);
continue;
}
b.setState(BindingState.OK);
getOkBindings().add(b);
}
}
}
for (final IBinding b : bindingsToProcess) {
if (b.getState() == BindingState.DISPOSE_PENDING) {
b.dispose();
continue;
}
/*
* Check for TabFolder - whenever a new selection is made in one of these, we reflow
* the context.
*/
for (Control c = b.getControl(); c != null && !(c instanceof Shell) && c != getTop(); c = c.getParent()) {
if (c instanceof TabFolder || c instanceof CTabFolder) {
if (myTabFolders != null && myTabFolders.contains(c)) {
/*
* If this TabFolder is already seen, the all parent TabFolders have
* been seen too.
*/
break;
}
if (myTabFolders == null) {
myTabFolders = new ArrayList<Control>();
myTabFolderListener = new Listener() {
@Override
public void handleEvent(Event event) {
if (event.type == SWT.Selection) {
reflow();
}
}
};
}
c.addListener(SWT.Selection, myTabFolderListener);
myTabFolders.add(c);
}
}
}
if (!hasSupportBeenAdded) {
if (myContextMessageDecoratorAdapter != null) {
new ContextMessageDecorator(this, myContextMessageDecoratorAdapter);
}
hasSupportBeenAdded = true;
}
} finally {
isInFinish = false;
if (Activator.getDefault().TRACE_LIFECYCLE_BINDINGS) {
LogUtils.debug(this, "finish end"); //$NON-NLS-1$
}
task.end();
}
setState(BindingState.OK);
}
/**
* Interface used to reflow the form/wizard/whatever that hosts this context.
*/
private interface IFormReflow {
/**
* Reflows the the form/wizard/whatever that hosts this context.
*/
void reflow();
}
/**
* The context adapter used by the messages decorator support.
*
* TODO move
*/
private IContextMessageDecoratorAdapter myContextMessageDecoratorAdapter;
/**
* Object used to reflow the form/wizard/whatever that hosts this context.
*/
private IFormReflow myFormReflow;
@Override
public void reflow() {
if (myFormReflow != null) {
myFormReflow.reflow();
}
}
private final DisposeListener myDisposeListener = new DisposeListener() {
@Override
public void widgetDisposed(DisposeEvent e) {
if (!(e.getSource() instanceof Control)) return;
final Control c = (Control) e.getSource();
/*
* There can be multiple bindings associated with a specific control and
* IBindingContext.Factory.getBindingForWidget(c) will only return the primary binding
* (with no attribute), if one exists.
*
* Here we want to find all the bindings that refer to the control...
*/
for (final IBinding b : getBindings().toArray(new IBinding[getBindings().size()])) {
if (b.getControl() != c) {
continue;
}
b.dispose();
}
if (getTop() == c && !getTop().isDisposed()) {
dispose();
return;
}
}
};
/**
* Adapter for the state of the bindings of the context.
* <p>
* Two jobs:
* <ul>
* <li>Adds new bindings to {@link #myNewBindings}.</li>
* <li>Adds and removed {@link #myDisposeListener} based on the current state of the binding.</li>
* </ul>
*/
private final AdapterImpl myAdapter = new AdapterImpl() {
@Override
public void notifyChanged(Notification msg) {
if (msg.isTouch()) return;
if (msg.getFeature() == IUIBindingsPackage.Literals.BINDING_CONTEXT__BINDINGS) {
IBinding b;
switch (msg.getEventType()) {
case Notification.ADD:
b = (IBinding) msg.getNewValue();
myNewBindings.add(b);
b.eAdapters().add(this);
break;
case Notification.REMOVE:
b = (IBinding) msg.getOldValue();
b.eAdapters().remove(this);
break;
default:
break;
}
return;
}
if (msg.getFeature() == IUIBindingsPackage.Literals.BINDING__STATE) {
final IBinding b = (IBinding) msg.getNotifier();
if (msg.getOldValue() == BindingState.OK) {
final Control c = b.getControl();
if (c != null && !c.isDisposed()) {
c.removeDisposeListener(myDisposeListener);
}
}
/*
* We add the dispose listener in this phase rather than OK to ensure it is very
* early in the listener sequence
*/
if (msg.getNewValue() == BindingState.PHASE1) {
final Control c = b.getControl();
if (c != null && !c.isDisposed()) {
c.addDisposeListener(myDisposeListener);
}
}
return;
}
}
};
@Override
public void dispose() {
setState(BindingState.DISPOSED);
IManagerRunnable.Factory.cancelAsyncExec("reflow", getTop());
final IManager manager = IManager.Factory.getManager();
manager.getContexts().remove(this);
manager.eAdapters().remove(myTextCommitStrategyAdapter);
disposeServices();
if (getTop() != null && !getTop().isDisposed()) {
getTop().removeDisposeListener(myDisposeListener);
}
/*
* Dispose all bindings in the context. Backwards...
*
* This is done as later bindings can reference earlier bindings, we therefore otherwise can
* get premature disposal problems...
*/
final IBinding[] ba = getBindings().toArray(new IBinding[getBindings().size()]);
for (int i = ba.length - 1; i >= 0; i--) {
ba[i].dispose();
}
try {
getDbContext().dispose();
} catch (final NullPointerException ex) {
LogUtils.error(this, ex);
}
}
@Override
public void updateBindings(Object[] objects) {
for (final IBinding b : getBindings()) {
b.updateBinding(objects);
}
}
} // BindingContextImpl