blob: a80b3c114a8691f06e8351ae7b3c46813a110e46 [file] [log] [blame]
/*******************************************************************************
* Copyright (c) 2011-2013 EclipseSource Muenchen GmbH 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:
* Eugen Neufeld - initial API and implementation
******************************************************************************/
package org.eclipse.emf.ecp.edit.spi;
import java.util.Locale;
import org.eclipse.core.databinding.DataBindingContext;
import org.eclipse.core.databinding.observable.IObserving;
import org.eclipse.core.databinding.observable.value.IObservableValue;
import org.eclipse.core.databinding.property.value.IValueProperty;
import org.eclipse.emf.common.notify.AdapterFactory;
import org.eclipse.emf.common.notify.Notifier;
import org.eclipse.emf.common.util.Diagnostic;
import org.eclipse.emf.databinding.EMFDataBindingContext;
import org.eclipse.emf.ecore.EStructuralFeature;
import org.eclipse.emf.ecore.EStructuralFeature.Setting;
import org.eclipse.emf.ecore.InternalEObject;
import org.eclipse.emf.ecp.internal.edit.Activator;
import org.eclipse.emf.ecp.view.model.common.edit.provider.CustomReflectiveItemProviderAdapterFactory;
import org.eclipse.emf.ecp.view.spi.context.ViewModelContext;
import org.eclipse.emf.ecp.view.spi.model.ModelChangeAddRemoveListener;
import org.eclipse.emf.ecp.view.spi.model.ModelChangeNotification;
import org.eclipse.emf.ecp.view.spi.model.VControl;
import org.eclipse.emf.ecp.view.spi.model.VDiagnostic;
import org.eclipse.emf.ecp.view.spi.model.VDomainModelReference;
import org.eclipse.emf.ecp.view.spi.model.VViewPackage;
import org.eclipse.emf.edit.domain.AdapterFactoryEditingDomain;
import org.eclipse.emf.edit.domain.EditingDomain;
import org.eclipse.emf.edit.provider.AdapterFactoryItemDelegator;
import org.eclipse.emf.edit.provider.ComposedAdapterFactory;
import org.eclipse.emf.edit.provider.IItemPropertyDescriptor;
import org.eclipse.emfforms.spi.core.services.databinding.DatabindingFailedException;
import org.eclipse.emfforms.spi.core.services.databinding.DatabindingFailedReport;
/**
* The {@link ECPAbstractControl} is the abstract class describing a control.
* This class provides the necessary common access methods.
*
* @author Eugen Neufeld
*
*/
@Deprecated
public abstract class ECPAbstractControl {
/**
* @author Jonas
*
*/
private final class ViewModelChangeListener implements ModelChangeAddRemoveListener {
private final VControl control;
/**
* @param control
*/
private ViewModelChangeListener(VControl control) {
this.control = control;
}
@Override
public void notifyRemove(Notifier notifier) {
// TODO Auto-generated method stub
}
@Override
public void notifyChange(ModelChangeNotification notification) {
if (notification.getNotifier() != ECPAbstractControl.this.control) {
return;
}
if (notification.getStructuralFeature() == VViewPackage.eINSTANCE
.getElement_Diagnostic()) {
applyValidation(control.getDiagnostic());
// TODO remove asap
backwardCompatibleHandleValidation();
}
if (notification.getStructuralFeature() == VViewPackage.eINSTANCE.getElement_Enabled()) {
enabledmentChanged(control.isEnabled());
}
}
@Override
public void notifyAdd(Notifier notifier) {
// TODO Auto-generated method stub
}
}
private boolean embedded;
private EMFDataBindingContext dataBindingContext;
private ComposedAdapterFactory composedAdapterFactory;
private AdapterFactoryItemDelegator adapterFactoryItemDelegator;
private ViewModelContext viewModelContext;
private VControl control;
private Setting firstSetting;
private EStructuralFeature firstFeature;
private ModelChangeAddRemoveListener viewChangeListener;
/**
* This method is called by the framework to instantiate the {@link ECPAbstractControl}.
*
* @param viewModelContext the {@link ViewModelContext} to use by this {@link ECPAbstractControl}.
* @param control the {@link VControl} of this control
* @since 1.2
*/
public final void init(ViewModelContext viewModelContext, final VControl control) {
this.viewModelContext = viewModelContext;
this.control = control;
composedAdapterFactory = new ComposedAdapterFactory(new AdapterFactory[] {
new CustomReflectiveItemProviderAdapterFactory(),
new ComposedAdapterFactory(ComposedAdapterFactory.Descriptor.Registry.INSTANCE) });
adapterFactoryItemDelegator = new AdapterFactoryItemDelegator(composedAdapterFactory);
viewChangeListener = new ViewModelChangeListener(control);
viewModelContext.registerViewChangeListener(viewChangeListener);
postInit();
}
/**
* Overwrite this method to implement control specific operations which must be executed after the init but before
* the rendering.
*
* @since 1.2
*/
protected void postInit() {
// do nothing
}
/**
* Notifies a control, that its enablement state has changed.
*
* @param enabled the new enablement value
* @since 1.2
*/
protected void enabledmentChanged(boolean enabled) {
setEditable(enabled);
}
/**
* Override this method in order to handle validation.
*
* @param diagnostic the current {@link VDiagnostic}
* @since 1.2
*/
protected void applyValidation(VDiagnostic diagnostic) {
// default case do nothing
}
/**
* Return the {@link IItemPropertyDescriptor} describing this {@link Setting}.
*
* @param setting the {@link Setting} to use for identifying the {@link IItemPropertyDescriptor}.
* @return the {@link IItemPropertyDescriptor}
* @since 1.2
*/
public IItemPropertyDescriptor getItemPropertyDescriptor(Setting setting) {
return adapterFactoryItemDelegator.getPropertyDescriptor(setting.getEObject(),
setting.getEStructuralFeature());
}
/**
* Return the {@link VControl}.
*
* @return the {@link VControl} of this control
* @since 1.2
*/
protected final VControl getControl() {
return control;
}
/**
* Return the {@link ViewModelContext}.
*
* @return the {@link ViewModelContext} of this control
* @since 1.2
*/
protected final ViewModelContext getViewModelContext() {
return viewModelContext;
}
/**
* Returns the first setting for this control.
*
* @return the first Setting or throws an {@link IllegalArgumentException} if no settings can be found
* @since 1.2
*/
public final Setting getFirstSetting() {
if (firstSetting == null) {
@SuppressWarnings("rawtypes")
IObservableValue observableValue;
try {
observableValue = Activator.getDefault().getEMFFormsDatabinding()
.getObservableValue(control.getDomainModelReference(), getViewModelContext().getDomainModel());
} catch (final DatabindingFailedException ex) {
Activator.getDefault().getReportService().report(new DatabindingFailedReport(ex));
throw new IllegalStateException("The databinding failed due to an incorrect VDomainModelReference: " //$NON-NLS-1$
+ ex.getMessage());
}
final InternalEObject internalEObject = (InternalEObject) ((IObserving) observableValue).getObserved();
final EStructuralFeature structuralFeature = (EStructuralFeature) observableValue.getValueType();
observableValue.dispose();
firstSetting = internalEObject.eSetting(structuralFeature);
return firstSetting;
}
return firstSetting;
}
/**
* Return the {@link EStructuralFeature} of this control.
*
* @return the {@link EStructuralFeature}
* @since 1.2
*/
public final EStructuralFeature getFirstStructuralFeature() {
if (firstFeature == null) {
@SuppressWarnings("rawtypes")
IValueProperty valueProperty;
try {
valueProperty = Activator.getDefault().getEMFFormsDatabinding()
.getValueProperty(control.getDomainModelReference(), viewModelContext.getDomainModel());
} catch (final DatabindingFailedException ex) {
throw new IllegalArgumentException(
"The passed VDomainModelReference resolves to no EStructuralFeature."); //$NON-NLS-1$
}
firstFeature = (EStructuralFeature) valueProperty.getValueType();
}
return firstFeature;
}
/**
* Returns a {@link DataBindingContext} for this control.
*
* @return the {@link DataBindingContext}
* @since 1.1
*/
public final DataBindingContext getDataBindingContext() {
if (dataBindingContext == null) {
dataBindingContext = new EMFDataBindingContext();
}
return dataBindingContext;
}
/**
* Disposes the control.
* A control which needs specific dispose handling must still call super.dispose.
*
* @since 1.1
*/
public void dispose() {
if (composedAdapterFactory != null) {
composedAdapterFactory.dispose();
}
composedAdapterFactory = null;
adapterFactoryItemDelegator = null;
if (dataBindingContext != null) {
dataBindingContext.dispose();
}
dataBindingContext = null;
if (viewModelContext != null) {
viewModelContext.unregisterViewChangeListener(viewChangeListener);
}
viewModelContext = null;
viewChangeListener = null;
control = null;
firstFeature = null;
firstSetting = null;
}
/**
* Whether a control is embedded. An embedded control can be rendered in an other fashion then an not embedded
* version.
*
* @return true if the control is embedded in another control
*/
protected final boolean isEmbedded() {
return embedded;
}
/**
* Sets whether this control is used as an embedded control.
*
* @param embedded whether the control is used as an embedded control
*/
public final void setEmbedded(boolean embedded) {
this.embedded = embedded;
}
/**
* Returns the {@link EditingDomain} for the provided {@link Setting}.
*
* @param setting the provided {@link Setting}
* @return the {@link EditingDomain} of this {@link Setting}
* @since 1.2
*/
protected final EditingDomain getEditingDomain(Setting setting) {
return AdapterFactoryEditingDomain.getEditingDomainFor(setting.getEObject());
}
/**
* This method allows to get a service from the view model context.
*
* @param serviceClass the type of the service to get
* @return the service instance
* @param <T> the type of the service
* @since 1.2
*/
protected final <T> T getService(Class<T> serviceClass) {
return viewModelContext.getService(serviceClass);
}
// TODO need view model service
/**
* Returns the current Locale.
*
* @return the current {@link Locale}
* @since 1.2
*/
protected final Locale getLocale() {
final ViewLocaleService service = viewModelContext.getService(ViewLocaleService.class);
if (service != null) {
return service.getLocale();
}
return Locale.getDefault();
}
/**
* Returns the {@link VDomainModelReference} set for this control.
*
* @return the domainModelReference the {@link VDomainModelReference} of this control
* @since 1.2
*/
protected final VDomainModelReference getDomainModelReference() {
return control.getDomainModelReference();
}
/**
* Returns the {@link EditingDomain} for the set {@link VDomainModelReference}.
*
* @return the {@link EditingDomain} for this control
* @since 1.2
* @deprecated
*/
@Deprecated
protected final EditingDomain getEditingDomain() {
return getEditingDomain(getFirstSetting());
}
/**
* Helper method to keep the old validation. Does nothing.
*
* @since 1.2
*/
protected void backwardCompatibleHandleValidation() {
}
/**
* Handle live validation.
*
* @param diagnostic of type Diagnostic
* @deprecated
* @since 1.2
**/
@Deprecated
public void handleValidation(Diagnostic diagnostic) {
// do nothing
}
/**
* Reset the validation status 'ok'.
*
* @deprecated
* @since 1.2
*/
@Deprecated
public void resetValidation() {
// do nothing
}
/**
* Whether a label should be shown for this control.
*
* @return true if a label should be created, false otherwise
* @deprecated use the labelAlignment of the control model element
* @since 1.2
*/
@Deprecated
public boolean showLabel() {
return true;
}
/**
* Sets the state of the widget to be either editable or not.
*
* @param isEditable whether to set the widget editable
* @since 1.2
* @deprecated
*/
@Deprecated
public void setEditable(boolean isEditable) {
// do nothing
}
}