From 707d2aa9279a909e28c1e3d59eda32f929c952a3 Mon Sep 17 00:00:00 2001 From: Gabriel Pascual Date: Mon, 26 Jan 2015 09:17:29 +0100 Subject: 447698: [Property View] Name of elements may move from unset to empty string, resulting in a dirty model (and user confusion) Task-Url: https://bugs.eclipse.org/bugs/show_bug.cgi?id=447698 - Add more case for UnsettableValueString - Modify PapyrusObservableValue to manage a new case Change-Id: I0f17d0db5472d3d82b55ad85435dbf0b23c21b1e Signed-off-by: Gabriel Pascual --- .../tools/databinding/PapyrusObservableValue.java | 345 +++++++++++---------- .../tools/databinding/UnsettableStringValue.java | 19 +- 2 files changed, 191 insertions(+), 173 deletions(-) (limited to 'plugins') diff --git a/plugins/uml/tools/org.eclipse.papyrus.uml.tools/src/org/eclipse/papyrus/uml/tools/databinding/PapyrusObservableValue.java b/plugins/uml/tools/org.eclipse.papyrus.uml.tools/src/org/eclipse/papyrus/uml/tools/databinding/PapyrusObservableValue.java index 8d976679f6c..379da9600a1 100644 --- a/plugins/uml/tools/org.eclipse.papyrus.uml.tools/src/org/eclipse/papyrus/uml/tools/databinding/PapyrusObservableValue.java +++ b/plugins/uml/tools/org.eclipse.papyrus.uml.tools/src/org/eclipse/papyrus/uml/tools/databinding/PapyrusObservableValue.java @@ -1,169 +1,176 @@ -/***************************************************************************** - * Copyright (c) 2010, 2014 CEA LIST 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: - * Camille Letavernier (CEA LIST) camille.letavernier@cea.fr - Initial API and implementation - * Thibault Le Ouay t.leouay@sherpa-eng.com - Add binding implementation - * Christian W. Damus (CEA) - bug 440108 - * Christian W. Damus (CEA) - bug 417409 - * - *****************************************************************************/ -package org.eclipse.papyrus.uml.tools.databinding; - -import org.eclipse.core.databinding.observable.IObservable; -import org.eclipse.core.databinding.observable.Realm; -import org.eclipse.emf.common.command.Command; -import org.eclipse.emf.common.command.UnexecutableCommand; -import org.eclipse.emf.ecore.EObject; -import org.eclipse.emf.ecore.EReference; -import org.eclipse.emf.ecore.EStructuralFeature; -import org.eclipse.emf.edit.domain.EditingDomain; -import org.eclipse.emf.transaction.TransactionalEditingDomain; -import org.eclipse.gmf.runtime.common.core.command.CompositeCommand; -import org.eclipse.gmf.runtime.emf.type.core.requests.DestroyElementRequest; -import org.eclipse.gmf.runtime.emf.type.core.requests.IEditCommandRequest; -import org.eclipse.gmf.runtime.emf.type.core.requests.SetRequest; -import org.eclipse.papyrus.commands.wrappers.GMFtoEMFCommandWrapper; -import org.eclipse.papyrus.infra.emf.databinding.EMFObservableValue; -import org.eclipse.papyrus.infra.emf.utils.EMFHelper; -import org.eclipse.papyrus.infra.services.edit.service.ElementEditServiceUtils; -import org.eclipse.papyrus.infra.services.edit.service.IElementEditService; -import org.eclipse.papyrus.infra.tools.databinding.AggregatedObservable; -import org.eclipse.papyrus.infra.tools.databinding.ReferenceCountedObservable; -import org.eclipse.papyrus.uml.tools.Activator; - -/** - * An ObservableValue used to edit EObject properties through - * Papyrus commands - * - * @author Camille Letavernier - * - */ -public class PapyrusObservableValue extends EMFObservableValue implements AggregatedObservable, CommandBasedObservableValue, ReferenceCountedObservable { - - private final ReferenceCountedObservable.Support refCount = new ReferenceCountedObservable.Support(this); - - /** - * - * Constructor. - * - * @param eObject - * The EObject to edit - * @param eStructuralFeature - * The structural feature to edit - * @param domain - * The editing domain on which the commands will be executed - */ - public PapyrusObservableValue(EObject eObject, EStructuralFeature eStructuralFeature, EditingDomain domain) { - this(Realm.getDefault(), eObject, eStructuralFeature, domain); - } - - /** - * - * Constructor. - * - * @param realm - * @param eObject - * The EObject to edit - * @param eStructuralFeature - * The structural feature to edit - * @param domain - * The editing domain on which the commands will be executed - */ - public PapyrusObservableValue(Realm realm, EObject eObject, EStructuralFeature eStructuralFeature, EditingDomain domain) { - super(eObject, eStructuralFeature, domain); - } - - @Override - protected void doSetValue(Object value) { - - try { - Command emfCommand = getCommand(value); - domain.getCommandStack().execute(emfCommand); - } catch (Exception ex) { - // - } - // throw new IllegalArgumentException("an error occured"); - } - - /** - * {@inheritDoc} - */ - public Command getCommand(Object value) { - EObject eObjectValue = EMFHelper.getEObject(value); - if (eObjectValue != null) { - value = eObjectValue; - } - - Object oldValue = getValue(); - - try { - IElementEditService provider = ElementEditServiceUtils.getCommandProvider(getObserved()); - - if (provider != null) { - CompositeCommand cc = new CompositeCommand("Edit value"); - - if (oldValue instanceof EObject && eStructuralFeature instanceof EReference && ((EReference) eStructuralFeature).isContainment()) { - cc.add(provider.getEditCommand(new DestroyElementRequest((TransactionalEditingDomain) domain, (EObject) oldValue, false))); - } - - cc.add(provider.getEditCommand(createSetRequest((TransactionalEditingDomain) domain, eObject, eStructuralFeature, value))); - - return new GMFtoEMFCommandWrapper(cc); - } - } catch (Exception ex) { - Activator.log.error(ex); - } - - return UnexecutableCommand.INSTANCE; - } - - protected IEditCommandRequest createSetRequest(TransactionalEditingDomain domain, EObject owner, EStructuralFeature feature, Object value) { - return new SetRequest(domain, owner, feature, value); - } - - /** - * - * @return the {@link EStructuralFeature} observed by this object - */ - public EStructuralFeature getEStructuralFeature() { - return eStructuralFeature; - } - - /** - * - * @return the {@link EObject} observed by this object - */ - public EObject getEObject() { - return eObject; - } - - public AggregatedObservable aggregate(IObservable observable) { - try { - return new AggregatedPapyrusObservableValue(domain, this, observable); - } catch (IllegalArgumentException ex) { - return null; // The observable cannot be aggregated - } - } - - public boolean hasDifferentValues() { - return false; // The value is not aggregated yet - } - - public void retain() { - refCount.retain(); - } - - public void release() { - refCount.release(); - } - - public void autorelease() { - refCount.autorelease(); - } -} +/***************************************************************************** + * Copyright (c) 2010, 2014 CEA LIST 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: + * Camille Letavernier (CEA LIST) camille.letavernier@cea.fr - Initial API and implementation + * Thibault Le Ouay t.leouay@sherpa-eng.com - Add binding implementation + * Christian W. Damus (CEA) - bug 440108 + * Christian W. Damus (CEA) - bug 417409 + * Gabriel Pascual (ALL4TEC) gabriel.pascual@all4tec.net - bug 447698 + * + *****************************************************************************/ +package org.eclipse.papyrus.uml.tools.databinding; + +import org.eclipse.core.databinding.observable.IObservable; +import org.eclipse.core.databinding.observable.Realm; +import org.eclipse.emf.common.command.Command; +import org.eclipse.emf.common.command.UnexecutableCommand; +import org.eclipse.emf.ecore.EObject; +import org.eclipse.emf.ecore.EReference; +import org.eclipse.emf.ecore.EStructuralFeature; +import org.eclipse.emf.edit.domain.EditingDomain; +import org.eclipse.emf.transaction.TransactionalEditingDomain; +import org.eclipse.gmf.runtime.common.core.command.CompositeCommand; +import org.eclipse.gmf.runtime.emf.type.core.requests.DestroyElementRequest; +import org.eclipse.gmf.runtime.emf.type.core.requests.IEditCommandRequest; +import org.eclipse.gmf.runtime.emf.type.core.requests.SetRequest; +import org.eclipse.papyrus.commands.wrappers.GMFtoEMFCommandWrapper; +import org.eclipse.papyrus.infra.emf.databinding.EMFObservableValue; +import org.eclipse.papyrus.infra.emf.utils.EMFHelper; +import org.eclipse.papyrus.infra.services.edit.service.ElementEditServiceUtils; +import org.eclipse.papyrus.infra.services.edit.service.IElementEditService; +import org.eclipse.papyrus.infra.tools.databinding.AggregatedObservable; +import org.eclipse.papyrus.infra.tools.databinding.ReferenceCountedObservable; +import org.eclipse.papyrus.uml.tools.Activator; + +/** + * An ObservableValue used to edit EObject properties through + * Papyrus commands + * + * @author Camille Letavernier + * + */ +public class PapyrusObservableValue extends EMFObservableValue implements AggregatedObservable, CommandBasedObservableValue, ReferenceCountedObservable { + + private final ReferenceCountedObservable.Support refCount = new ReferenceCountedObservable.Support(this); + + /** + * + * Constructor. + * + * @param eObject + * The EObject to edit + * @param eStructuralFeature + * The structural feature to edit + * @param domain + * The editing domain on which the commands will be executed + */ + public PapyrusObservableValue(EObject eObject, EStructuralFeature eStructuralFeature, EditingDomain domain) { + this(Realm.getDefault(), eObject, eStructuralFeature, domain); + } + + /** + * + * Constructor. + * + * @param realm + * @param eObject + * The EObject to edit + * @param eStructuralFeature + * The structural feature to edit + * @param domain + * The editing domain on which the commands will be executed + */ + public PapyrusObservableValue(Realm realm, EObject eObject, EStructuralFeature eStructuralFeature, EditingDomain domain) { + super(eObject, eStructuralFeature, domain); + } + + @Override + protected void doSetValue(Object value) { + + try { + Command emfCommand = getCommand(value); + domain.getCommandStack().execute(emfCommand); + } catch (Exception ex) { + // + } + // throw new IllegalArgumentException("an error occured"); + } + + /** + * {@inheritDoc} + */ + public Command getCommand(Object value) { + EObject eObjectValue = EMFHelper.getEObject(value); + if (eObjectValue != null) { + value = eObjectValue; + } + + Object oldValue = getValue(); + + try { + IElementEditService provider = ElementEditServiceUtils.getCommandProvider(getObserved()); + + if (provider != null) { + CompositeCommand cc = new CompositeCommand("Edit value"); + + if (oldValue instanceof EObject && eStructuralFeature instanceof EReference && ((EReference) eStructuralFeature).isContainment()) { + cc.add(provider.getEditCommand(new DestroyElementRequest((TransactionalEditingDomain) domain, (EObject) oldValue, false))); + } + + IEditCommandRequest createSetRequest = createSetRequest((TransactionalEditingDomain) domain, eObject, eStructuralFeature, value); + + if (createSetRequest == null) { + return UnexecutableCommand.INSTANCE; + } + + cc.add(provider.getEditCommand(createSetRequest)); + + return new GMFtoEMFCommandWrapper(cc); + } + } catch (Exception ex) { + Activator.log.error(ex); + } + + return UnexecutableCommand.INSTANCE; + } + + protected IEditCommandRequest createSetRequest(TransactionalEditingDomain domain, EObject owner, EStructuralFeature feature, Object value) { + return new SetRequest(domain, owner, feature, value); + } + + /** + * + * @return the {@link EStructuralFeature} observed by this object + */ + public EStructuralFeature getEStructuralFeature() { + return eStructuralFeature; + } + + /** + * + * @return the {@link EObject} observed by this object + */ + public EObject getEObject() { + return eObject; + } + + public AggregatedObservable aggregate(IObservable observable) { + try { + return new AggregatedPapyrusObservableValue(domain, this, observable); + } catch (IllegalArgumentException ex) { + return null; // The observable cannot be aggregated + } + } + + public boolean hasDifferentValues() { + return false; // The value is not aggregated yet + } + + public void retain() { + refCount.retain(); + } + + public void release() { + refCount.release(); + } + + public void autorelease() { + refCount.autorelease(); + } +} diff --git a/plugins/uml/tools/org.eclipse.papyrus.uml.tools/src/org/eclipse/papyrus/uml/tools/databinding/UnsettableStringValue.java b/plugins/uml/tools/org.eclipse.papyrus.uml.tools/src/org/eclipse/papyrus/uml/tools/databinding/UnsettableStringValue.java index 4322ea03baf..2127c82d256 100644 --- a/plugins/uml/tools/org.eclipse.papyrus.uml.tools/src/org/eclipse/papyrus/uml/tools/databinding/UnsettableStringValue.java +++ b/plugins/uml/tools/org.eclipse.papyrus.uml.tools/src/org/eclipse/papyrus/uml/tools/databinding/UnsettableStringValue.java @@ -8,6 +8,7 @@ * * Contributors: * CEA LIST - Initial API and implementation + * Gabriel Pascual (ALL4TEC) gabriel.pascual@all4tec.net - bug 447698 * *****************************************************************************/ @@ -37,12 +38,22 @@ public class UnsettableStringValue extends PapyrusObservableValue { super(realm, eObject, eStructuralFeature, domain); } + @Override protected IEditCommandRequest createSetRequest(TransactionalEditingDomain domain, EObject owner, EStructuralFeature feature, Object value) { - if ("".equals(value) && (feature.getDefaultValue() == null)) { //$NON-NLS-1$ - // Unset the string attribute instead of making it an empty string - return new UnsetRequest(owner, feature); + + // Bug 447698 : It doesn't necessary to create UnsetRequest if the value is already null + if ("".equals(value)) {//$NON-NLS-1$ + + if ((feature.getDefaultValue() == null) && owner.eGet(eStructuralFeature) != null) { + // Unset the string attribute instead of making it an empty string + return new UnsetRequest(owner, feature); + } + + } else { + return super.createSetRequest(domain, owner, feature, value); } - return super.createSetRequest(domain, owner, feature, value); + + return null; } } -- cgit v1.2.3