From 4601d5dfff3851dd0adddbb14cdacdc0edeb63b0 Mon Sep 17 00:00:00 2001 From: Benoit Maggi Date: Fri, 18 Apr 2014 17:03:16 +0200 Subject: Bug 430350 - [SysML block diagram] java.lang.NullPointerException when adding value property Conflicts: plugins/infra/emf/org.eclipse.papyrus.infra.emf/src/org/eclipse/papyrus/infra/emf/utils/ServiceUtilsForResource.java plugins/infra/emf/org.eclipse.papyrus.infra.emf/src/org/eclipse/papyrus/infra/emf/utils/ServiceUtilsForResourceSet.java Signed-off-by: Benoit Maggi Change-Id: I05a230cfe474cd0395df82d7846fa81a22b4035f--- .../papyrus/infra/emf/advice/RemovePageHelper.java | 110 +-- .../emf/databinding/AnnotationObservableValue.java | 612 ++++++------- .../infra/emf/databinding/EMFObservableValue.java | 204 ++--- .../emf/providers/EMFGraphicalContentProvider.java | 964 ++++++++++----------- .../strategy/SemanticEMFContentProvider.java | 433 ++++----- .../emf/resource/DependencyManagementHelper.java | 810 ++++++++--------- .../infra/emf/utils/ServiceUtilsForEObject.java | 90 +- .../infra/emf/utils/ServiceUtilsForHandlers.java | 200 ++--- .../utils/ServiceUtilsForIEvaluationContext.java | 214 ++--- .../infra/emf/utils/ServiceUtilsForResource.java | 140 +-- .../emf/utils/ServiceUtilsForResourceSet.java | 98 +-- .../infra/emf/utils/ServiceUtilsForSelection.java | 118 +-- .../infra/emf/utils/TextReferencesHelper.java | 436 +++++----- .../common/dialogs/CreateOrSelectTypeDialog.java | 2 + 14 files changed, 2217 insertions(+), 2214 deletions(-) diff --git a/plugins/infra/emf/org.eclipse.papyrus.infra.emf/src/org/eclipse/papyrus/infra/emf/advice/RemovePageHelper.java b/plugins/infra/emf/org.eclipse.papyrus.infra.emf/src/org/eclipse/papyrus/infra/emf/advice/RemovePageHelper.java index 2f55fda2fea..0a2c572e8ca 100644 --- a/plugins/infra/emf/org.eclipse.papyrus.infra.emf/src/org/eclipse/papyrus/infra/emf/advice/RemovePageHelper.java +++ b/plugins/infra/emf/org.eclipse.papyrus.infra.emf/src/org/eclipse/papyrus/infra/emf/advice/RemovePageHelper.java @@ -1,55 +1,55 @@ -/***************************************************************************** - * Copyright (c) 2013 CEA LIST. - * - * 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 - *****************************************************************************/ -package org.eclipse.papyrus.infra.emf.advice; - -import org.eclipse.core.commands.ExecutionException; -import org.eclipse.core.runtime.IAdaptable; -import org.eclipse.core.runtime.IProgressMonitor; -import org.eclipse.emf.ecore.EObject; -import org.eclipse.emf.transaction.TransactionalEditingDomain; -import org.eclipse.gmf.runtime.common.core.command.CommandResult; -import org.eclipse.gmf.runtime.common.core.command.ICommand; -import org.eclipse.gmf.runtime.emf.commands.core.command.AbstractTransactionalCommand; -import org.eclipse.papyrus.infra.core.sasheditor.contentprovider.IPageManager; -import org.eclipse.papyrus.infra.core.services.ServiceException; -import org.eclipse.papyrus.infra.emf.utils.ServiceUtilsForEObject; - -/** - * A Helper to build the command used to remove the page associated to the destroyed element - * - * @author Camille Letavernier - * - */ -public class RemovePageHelper { - - public static ICommand getRemovePageCommand(final TransactionalEditingDomain editingDomain, final EObject elementToDestroy) { - try { - final IPageManager pageManager = ServiceUtilsForEObject.getInstance().getIPageManager(elementToDestroy); - if(pageManager.allPages().contains(elementToDestroy)) { - return new AbstractTransactionalCommand(editingDomain, "Delete page", null) { - - @Override - protected CommandResult doExecuteWithResult(IProgressMonitor monitor, IAdaptable info) throws ExecutionException { - pageManager.removePage(elementToDestroy); - return CommandResult.newOKCommandResult(); - } - }; - } - } catch (ServiceException ex) { - //Ignore - } catch (Exception ex) { - //Ignore - } - - return null; - } -} +/***************************************************************************** + * Copyright (c) 2013 CEA LIST. + * + * 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 + *****************************************************************************/ +package org.eclipse.papyrus.infra.emf.advice; + +import org.eclipse.core.commands.ExecutionException; +import org.eclipse.core.runtime.IAdaptable; +import org.eclipse.core.runtime.IProgressMonitor; +import org.eclipse.emf.ecore.EObject; +import org.eclipse.emf.transaction.TransactionalEditingDomain; +import org.eclipse.gmf.runtime.common.core.command.CommandResult; +import org.eclipse.gmf.runtime.common.core.command.ICommand; +import org.eclipse.gmf.runtime.emf.commands.core.command.AbstractTransactionalCommand; +import org.eclipse.papyrus.infra.core.sasheditor.contentprovider.IPageManager; +import org.eclipse.papyrus.infra.core.services.ServiceException; +import org.eclipse.papyrus.infra.emf.utils.ServiceUtilsForEObject; + +/** + * A Helper to build the command used to remove the page associated to the destroyed element + * + * @author Camille Letavernier + * + */ +public class RemovePageHelper { + + public static ICommand getRemovePageCommand(final TransactionalEditingDomain editingDomain, final EObject elementToDestroy) { + try { + final IPageManager pageManager = ServiceUtilsForEObject.getInstance().getIPageManager(elementToDestroy); + if(pageManager.allPages().contains(elementToDestroy)) { + return new AbstractTransactionalCommand(editingDomain, "Delete page", null) { //$NON-NLS-1$ + + @Override + protected CommandResult doExecuteWithResult(IProgressMonitor monitor, IAdaptable info) throws ExecutionException { + pageManager.removePage(elementToDestroy); + return CommandResult.newOKCommandResult(); + } + }; + } + } catch (ServiceException ex) { + //Ignore + } catch (Exception ex) { + //Ignore + } + + return null; + } +} diff --git a/plugins/infra/emf/org.eclipse.papyrus.infra.emf/src/org/eclipse/papyrus/infra/emf/databinding/AnnotationObservableValue.java b/plugins/infra/emf/org.eclipse.papyrus.infra.emf/src/org/eclipse/papyrus/infra/emf/databinding/AnnotationObservableValue.java index 1e690d4c09a..d1cc29e49a5 100644 --- a/plugins/infra/emf/org.eclipse.papyrus.infra.emf/src/org/eclipse/papyrus/infra/emf/databinding/AnnotationObservableValue.java +++ b/plugins/infra/emf/org.eclipse.papyrus.infra.emf/src/org/eclipse/papyrus/infra/emf/databinding/AnnotationObservableValue.java @@ -1,306 +1,306 @@ -/***************************************************************************** - * Copyright (c) 2011 CEA LIST. - * - * 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 - *****************************************************************************/ -package org.eclipse.papyrus.infra.emf.databinding; - -import org.eclipse.core.databinding.observable.value.AbstractObservableValue; -import org.eclipse.emf.common.command.AbstractCommand; -import org.eclipse.emf.common.command.Command; -import org.eclipse.emf.common.command.CompoundCommand; -import org.eclipse.emf.ecore.EAnnotation; -import org.eclipse.emf.ecore.EModelElement; -import org.eclipse.emf.ecore.EcoreFactory; -import org.eclipse.emf.ecore.EcorePackage; -import org.eclipse.emf.edit.command.SetCommand; -import org.eclipse.emf.edit.domain.EditingDomain; - -/** - * An IObservableValue for editing EMF EAnnotations - * - * @author Camille Letavernier - */ -public class AnnotationObservableValue extends AbstractObservableValue { - - /** - * The EModelElement to edit. - */ - protected EModelElement source; - - /** - * The editing domain on which the commands will be executed - */ - protected EditingDomain domain; - - /** - * The name of the annotation to use - */ - protected String annotationName; - - /** - * The annotation key to edit - */ - protected String key; - - /** - * Whether the EAnnotation should be removed from the source when its last - * entry is removed (ie. value = null) - */ - protected boolean deleteWithLastEntry; - - /** - * Constructor. - * - * Creates an IObservableValue for the annotation. The annotation doesn't - * need to be created beforehand - * - * @param source - * The EObject owning the annotation - * @param domain - * The editing domain on which the commands will be executed - * @param annotationName - * The name of the annotation - * @param key - * The name of annotation's property to edit - */ - public AnnotationObservableValue(EModelElement source, EditingDomain domain, String annotationName, String key) { - this(source, domain, annotationName, key, false); - } - - /** - * Constructor. - * - * Creates an IObservableValue for the annotation. The annotation doesn't - * need to be created beforehand - * - * @param source - * The EObject owning the annotation - * @param domain - * The editing domain on which the commands will be executed - * @param annotationName - * The name of the annotation - * @param key - * The name of annotation's property to edit - * @param deleteWithLastEntry - * Whether the EAnnotation should be removed from the source when its - * last entry is removed (ie. value = null) - */ - public AnnotationObservableValue(EModelElement source, EditingDomain domain, String annotationName, String key, boolean deleteWithLastEntry) { - this.source = source; - this.domain = domain; - this.annotationName = annotationName; - this.key = key; - this.deleteWithLastEntry = deleteWithLastEntry; - } - - /** - * {@inheritDoc} - */ - public Object getValueType() { - return String.class; - } - - /** - * {@inheritDoc} - */ - @Override - protected Object doGetValue() { - EAnnotation annotation = getEAnnotation(); - if(annotation == null) { - return null; - } - - return annotation.getDetails().get(key); - } - - /** - * @return the observed EAnnotation - */ - protected EAnnotation getEAnnotation() { - return source.getEAnnotation(annotationName); - } - - /** - * {@inheritDoc} - */ - @Override - protected void doSetValue(Object value) { - Command emfCommand = getCommand(value); - if(emfCommand != null) { - domain.getCommandStack().execute(emfCommand); - } - } - - /** - * Returns the command used to edit the observed annotation, which the - * given value - * - * @param value - * @return - */ - protected Command getCommand(Object value) { - EAnnotation annotation = getEAnnotation(); - - if(value == null) { - //No change : the key is not defined ; we cannot remove it - if(annotation == null || !annotation.getDetails().containsKey(key)) { - return null; - } - } else { - if(!(value instanceof String)) { - return null; - } - } - - CompoundCommand emfCommand = new CompoundCommand("Set " + key) { - - @Override - public boolean prepare() { - if(this.isEmpty()) { - return false; - } - - return commandList.get(0).canExecute(); - } - - }; - - if(annotation == null) { - annotation = EcoreFactory.eINSTANCE.createEAnnotation(); - - SetCommand attachToSourceCommand = new SetCommand(domain, annotation, EcorePackage.eINSTANCE.getEAnnotation_EModelElement(), source); - attachToSourceCommand.setLabel("Attach to source"); - emfCommand.append(attachToSourceCommand); - - SetCommand nameCommand = new SetCommand(domain, annotation, EcorePackage.eINSTANCE.getEAnnotation_Source(), annotationName); - nameCommand.setLabel("Set name"); - emfCommand.append(nameCommand); - } - - if(value == null) { - if(annotation.getDetails().size() == 1 && annotation.getDetails().containsKey(key) && deleteWithLastEntry) { - //We removed the last key : delete the annotation - SetCommand deleteAnnotationCommand = new SetCommand(domain, annotation, EcorePackage.eINSTANCE.getEAnnotation_EModelElement(), null); - deleteAnnotationCommand.setLabel("Delete EAnnotation"); - emfCommand.append(deleteAnnotationCommand); - } else { - Command removeEntryCommand = new RemoveEntryCommand(annotation, key); - emfCommand.append(removeEntryCommand); - } - } else { - Command addEntryCommand = new AddEntryCommand(annotation, key, (String)value); - emfCommand.append(addEntryCommand); - } - - return emfCommand; - } - - /** - * A Command to remove an entry from an EAnnotation - * - * @author Camille Letavernier - * - */ - protected class RemoveEntryCommand extends AbstractCommand { - - private EAnnotation annotation; - - private String key; - - private String previousValue; - - private boolean undo = false; - - /** - * Constructor - * - * @param annotation - * The EAnnotation to edit - * @param key - * The EAnnotation's key to edit - */ - public RemoveEntryCommand(EAnnotation annotation, String key) { - this.annotation = annotation; - this.key = key; - } - - public void execute() { - undo = annotation.getDetails().containsKey(key); - if(undo) { - previousValue = annotation.getDetails().get(key); - annotation.getDetails().remove(key); - } - } - - public void redo() { - execute(); - } - - @Override - public boolean prepare() { - return true; - } - - @Override - public void undo() { - if(undo) { - annotation.getDetails().put(key, previousValue); - } - } - } - - /** - * A Command to set an EAnnotation's entry - * - * @author Camille Letavernier - */ - protected class AddEntryCommand extends AbstractCommand { - - private EAnnotation annotation; - - private String key; - - private String value; - - /** - * - * - * @param annotation - * The EAnnotation to edit - * @param key - * The EAnnotation's key to edit - * @param value - * The value to set - */ - public AddEntryCommand(EAnnotation annotation, String key, String value) { - this.annotation = annotation; - this.key = key; - this.value = value; - } - - public void execute() { - annotation.getDetails().put(key, value); - } - - public void redo() { - execute(); - } - - @Override - public void undo() { - annotation.getDetails().remove(key); - } - - @Override - public boolean prepare() { - return true; - } - } -} +/***************************************************************************** + * Copyright (c) 2011 CEA LIST. + * + * 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 + *****************************************************************************/ +package org.eclipse.papyrus.infra.emf.databinding; + +import org.eclipse.core.databinding.observable.value.AbstractObservableValue; +import org.eclipse.emf.common.command.AbstractCommand; +import org.eclipse.emf.common.command.Command; +import org.eclipse.emf.common.command.CompoundCommand; +import org.eclipse.emf.ecore.EAnnotation; +import org.eclipse.emf.ecore.EModelElement; +import org.eclipse.emf.ecore.EcoreFactory; +import org.eclipse.emf.ecore.EcorePackage; +import org.eclipse.emf.edit.command.SetCommand; +import org.eclipse.emf.edit.domain.EditingDomain; + +/** + * An IObservableValue for editing EMF EAnnotations + * + * @author Camille Letavernier + */ +public class AnnotationObservableValue extends AbstractObservableValue { + + /** + * The EModelElement to edit. + */ + protected EModelElement source; + + /** + * The editing domain on which the commands will be executed + */ + protected EditingDomain domain; + + /** + * The name of the annotation to use + */ + protected String annotationName; + + /** + * The annotation key to edit + */ + protected String key; + + /** + * Whether the EAnnotation should be removed from the source when its last + * entry is removed (ie. value = null) + */ + protected boolean deleteWithLastEntry; + + /** + * Constructor. + * + * Creates an IObservableValue for the annotation. The annotation doesn't + * need to be created beforehand + * + * @param source + * The EObject owning the annotation + * @param domain + * The editing domain on which the commands will be executed + * @param annotationName + * The name of the annotation + * @param key + * The name of annotation's property to edit + */ + public AnnotationObservableValue(EModelElement source, EditingDomain domain, String annotationName, String key) { + this(source, domain, annotationName, key, false); + } + + /** + * Constructor. + * + * Creates an IObservableValue for the annotation. The annotation doesn't + * need to be created beforehand + * + * @param source + * The EObject owning the annotation + * @param domain + * The editing domain on which the commands will be executed + * @param annotationName + * The name of the annotation + * @param key + * The name of annotation's property to edit + * @param deleteWithLastEntry + * Whether the EAnnotation should be removed from the source when its + * last entry is removed (ie. value = null) + */ + public AnnotationObservableValue(EModelElement source, EditingDomain domain, String annotationName, String key, boolean deleteWithLastEntry) { + this.source = source; + this.domain = domain; + this.annotationName = annotationName; + this.key = key; + this.deleteWithLastEntry = deleteWithLastEntry; + } + + /** + * {@inheritDoc} + */ + public Object getValueType() { + return String.class; + } + + /** + * {@inheritDoc} + */ + @Override + protected Object doGetValue() { + EAnnotation annotation = getEAnnotation(); + if(annotation == null) { + return null; + } + + return annotation.getDetails().get(key); + } + + /** + * @return the observed EAnnotation + */ + protected EAnnotation getEAnnotation() { + return source.getEAnnotation(annotationName); + } + + /** + * {@inheritDoc} + */ + @Override + protected void doSetValue(Object value) { + Command emfCommand = getCommand(value); + if(emfCommand != null) { + domain.getCommandStack().execute(emfCommand); + } + } + + /** + * Returns the command used to edit the observed annotation, which the + * given value + * + * @param value + * @return + */ + protected Command getCommand(Object value) { + EAnnotation annotation = getEAnnotation(); + + if(value == null) { + //No change : the key is not defined ; we cannot remove it + if(annotation == null || !annotation.getDetails().containsKey(key)) { + return null; + } + } else { + if(!(value instanceof String)) { + return null; + } + } + + CompoundCommand emfCommand = new CompoundCommand("Set " + key) { //$NON-NLS-1$ + + @Override + public boolean prepare() { + if(this.isEmpty()) { + return false; + } + + return commandList.get(0).canExecute(); + } + + }; + + if(annotation == null) { + annotation = EcoreFactory.eINSTANCE.createEAnnotation(); + + SetCommand attachToSourceCommand = new SetCommand(domain, annotation, EcorePackage.eINSTANCE.getEAnnotation_EModelElement(), source); + attachToSourceCommand.setLabel("Attach to source"); + emfCommand.append(attachToSourceCommand); + + SetCommand nameCommand = new SetCommand(domain, annotation, EcorePackage.eINSTANCE.getEAnnotation_Source(), annotationName); + nameCommand.setLabel("Set name"); + emfCommand.append(nameCommand); + } + + if(value == null) { + if(annotation.getDetails().size() == 1 && annotation.getDetails().containsKey(key) && deleteWithLastEntry) { + //We removed the last key : delete the annotation + SetCommand deleteAnnotationCommand = new SetCommand(domain, annotation, EcorePackage.eINSTANCE.getEAnnotation_EModelElement(), null); + deleteAnnotationCommand.setLabel("Delete EAnnotation"); + emfCommand.append(deleteAnnotationCommand); + } else { + Command removeEntryCommand = new RemoveEntryCommand(annotation, key); + emfCommand.append(removeEntryCommand); + } + } else { + Command addEntryCommand = new AddEntryCommand(annotation, key, (String)value); + emfCommand.append(addEntryCommand); + } + + return emfCommand; + } + + /** + * A Command to remove an entry from an EAnnotation + * + * @author Camille Letavernier + * + */ + protected class RemoveEntryCommand extends AbstractCommand { + + private EAnnotation annotation; + + private String key; + + private String previousValue; + + private boolean undo = false; + + /** + * Constructor + * + * @param annotation + * The EAnnotation to edit + * @param key + * The EAnnotation's key to edit + */ + public RemoveEntryCommand(EAnnotation annotation, String key) { + this.annotation = annotation; + this.key = key; + } + + public void execute() { + undo = annotation.getDetails().containsKey(key); + if(undo) { + previousValue = annotation.getDetails().get(key); + annotation.getDetails().remove(key); + } + } + + public void redo() { + execute(); + } + + @Override + public boolean prepare() { + return true; + } + + @Override + public void undo() { + if(undo) { + annotation.getDetails().put(key, previousValue); + } + } + } + + /** + * A Command to set an EAnnotation's entry + * + * @author Camille Letavernier + */ + protected class AddEntryCommand extends AbstractCommand { + + private EAnnotation annotation; + + private String key; + + private String value; + + /** + * + * + * @param annotation + * The EAnnotation to edit + * @param key + * The EAnnotation's key to edit + * @param value + * The value to set + */ + public AddEntryCommand(EAnnotation annotation, String key, String value) { + this.annotation = annotation; + this.key = key; + this.value = value; + } + + public void execute() { + annotation.getDetails().put(key, value); + } + + public void redo() { + execute(); + } + + @Override + public void undo() { + annotation.getDetails().remove(key); + } + + @Override + public boolean prepare() { + return true; + } + } +} diff --git a/plugins/infra/emf/org.eclipse.papyrus.infra.emf/src/org/eclipse/papyrus/infra/emf/databinding/EMFObservableValue.java b/plugins/infra/emf/org.eclipse.papyrus.infra.emf/src/org/eclipse/papyrus/infra/emf/databinding/EMFObservableValue.java index 6ddd393f854..547bb6e4165 100644 --- a/plugins/infra/emf/org.eclipse.papyrus.infra.emf/src/org/eclipse/papyrus/infra/emf/databinding/EMFObservableValue.java +++ b/plugins/infra/emf/org.eclipse.papyrus.infra.emf/src/org/eclipse/papyrus/infra/emf/databinding/EMFObservableValue.java @@ -1,102 +1,102 @@ -/***************************************************************************** - * Copyright (c) 2010 CEA LIST. - * - * 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 - *****************************************************************************/ -package org.eclipse.papyrus.infra.emf.databinding; - -import org.eclipse.core.databinding.observable.Realm; -import org.eclipse.emf.common.command.Command; -import org.eclipse.emf.common.command.CompoundCommand; -import org.eclipse.emf.databinding.EObjectObservableValue; -import org.eclipse.emf.ecore.EObject; -import org.eclipse.emf.ecore.EReference; -import org.eclipse.emf.ecore.EStructuralFeature; -import org.eclipse.emf.edit.command.DeleteCommand; -import org.eclipse.emf.edit.command.SetCommand; -import org.eclipse.emf.edit.domain.EditingDomain; -import org.eclipse.papyrus.infra.emf.utils.EMFHelper; - -/** - * An Observable value to edit EMF values through EMF commands. - * - * @author Camille Letavernier - */ -public class EMFObservableValue extends EObjectObservableValue { - - /** - * The editing domain on which the commands will be executed - */ - protected EditingDomain domain; - - /** - * - * Constructor. - * - * @param eObject - * The eObject being edited - * @param eStructuralFeature - * The structuralFeature being edited - * @param domain - * The Editing domain on which the commands will be executed - */ - public EMFObservableValue(EObject eObject, EStructuralFeature eStructuralFeature, EditingDomain domain) { - this(Realm.getDefault(), eObject, eStructuralFeature, domain); - } - - /** - * - * Constructor. - * - * @param realm - * @param eObject - * The eObject being edited - * @param eStructuralFeature - * The structuralFeature being edited - * @param domain - * The Editing domain on which the commands will be executed - */ - public EMFObservableValue(Realm realm, EObject eObject, EStructuralFeature eStructuralFeature, EditingDomain domain) { - super(realm, eObject, eStructuralFeature); - this.domain = domain; - } - - @Override - protected void doSetValue(Object value) { - EObject eObject = EMFHelper.getEObject(value); - if(eObject != null) { - value = eObject; - } - - Command command = getSetCommand(value); - domain.getCommandStack().execute(command); - } - - /** - * Returns the command used to edit the value - * - * @param value - * The new value - * @return - * The Set command used to edit the value - */ - protected Command getSetCommand(Object value) { - Object oldValue = getValue(); - - CompoundCommand cc = new CompoundCommand("Edit value"); - - if (oldValue instanceof EObject && eStructuralFeature instanceof EReference && ((EReference)eStructuralFeature).isContainment()) { - cc.append(DeleteCommand.create(domain, (EObject)oldValue)); - } - - cc.append(new SetCommand(domain, eObject, eStructuralFeature, value)); - - return cc; - } -} +/***************************************************************************** + * Copyright (c) 2010 CEA LIST. + * + * 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 + *****************************************************************************/ +package org.eclipse.papyrus.infra.emf.databinding; + +import org.eclipse.core.databinding.observable.Realm; +import org.eclipse.emf.common.command.Command; +import org.eclipse.emf.common.command.CompoundCommand; +import org.eclipse.emf.databinding.EObjectObservableValue; +import org.eclipse.emf.ecore.EObject; +import org.eclipse.emf.ecore.EReference; +import org.eclipse.emf.ecore.EStructuralFeature; +import org.eclipse.emf.edit.command.DeleteCommand; +import org.eclipse.emf.edit.command.SetCommand; +import org.eclipse.emf.edit.domain.EditingDomain; +import org.eclipse.papyrus.infra.emf.utils.EMFHelper; + +/** + * An Observable value to edit EMF values through EMF commands. + * + * @author Camille Letavernier + */ +public class EMFObservableValue extends EObjectObservableValue { + + /** + * The editing domain on which the commands will be executed + */ + protected EditingDomain domain; + + /** + * + * Constructor. + * + * @param eObject + * The eObject being edited + * @param eStructuralFeature + * The structuralFeature being edited + * @param domain + * The Editing domain on which the commands will be executed + */ + public EMFObservableValue(EObject eObject, EStructuralFeature eStructuralFeature, EditingDomain domain) { + this(Realm.getDefault(), eObject, eStructuralFeature, domain); + } + + /** + * + * Constructor. + * + * @param realm + * @param eObject + * The eObject being edited + * @param eStructuralFeature + * The structuralFeature being edited + * @param domain + * The Editing domain on which the commands will be executed + */ + public EMFObservableValue(Realm realm, EObject eObject, EStructuralFeature eStructuralFeature, EditingDomain domain) { + super(realm, eObject, eStructuralFeature); + this.domain = domain; + } + + @Override + protected void doSetValue(Object value) { + EObject eObject = EMFHelper.getEObject(value); + if(eObject != null) { + value = eObject; + } + + Command command = getSetCommand(value); + domain.getCommandStack().execute(command); + } + + /** + * Returns the command used to edit the value + * + * @param value + * The new value + * @return + * The Set command used to edit the value + */ + protected Command getSetCommand(Object value) { + Object oldValue = getValue(); + + CompoundCommand cc = new CompoundCommand("Edit value"); //$NON-NLS-1$ + + if (oldValue instanceof EObject && eStructuralFeature instanceof EReference && ((EReference)eStructuralFeature).isContainment()) { + cc.append(DeleteCommand.create(domain, (EObject)oldValue)); + } + + cc.append(new SetCommand(domain, eObject, eStructuralFeature, value)); + + return cc; + } +} diff --git a/plugins/infra/emf/org.eclipse.papyrus.infra.emf/src/org/eclipse/papyrus/infra/emf/providers/EMFGraphicalContentProvider.java b/plugins/infra/emf/org.eclipse.papyrus.infra.emf/src/org/eclipse/papyrus/infra/emf/providers/EMFGraphicalContentProvider.java index 16cc0586c3a..bea0471d57d 100644 --- a/plugins/infra/emf/org.eclipse.papyrus.infra.emf/src/org/eclipse/papyrus/infra/emf/providers/EMFGraphicalContentProvider.java +++ b/plugins/infra/emf/org.eclipse.papyrus.infra.emf/src/org/eclipse/papyrus/infra/emf/providers/EMFGraphicalContentProvider.java @@ -1,482 +1,482 @@ -/***************************************************************************** - * Copyright (c) 2010 CEA LIST. - * - * - * 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: - * Patrick Tessier (CEA LIST) Patrick.tessier@cea.fr - Initial API and implementation - * Camille Letavernier (CEA LIST) camille.letavernier@cea.fr - Added graphic contributions for the filters - * Remi Schnekenburger (CEA LIST) remi.schnekenburger@cea.fr - Initial History implementation - * Camille Letavernier (CEA LIST) camille.letavernier@cea.fr - History integration - * - *****************************************************************************/ -package org.eclipse.papyrus.infra.emf.providers; - -import java.util.ArrayList; -import java.util.Arrays; -import java.util.Collection; -import java.util.Collections; -import java.util.Iterator; -import java.util.LinkedHashSet; -import java.util.LinkedList; -import java.util.List; -import java.util.Set; - -import org.eclipse.emf.common.util.URI; -import org.eclipse.emf.ecore.EObject; -import org.eclipse.emf.ecore.resource.ResourceSet; -import org.eclipse.emf.ecore.util.EcoreUtil; -import org.eclipse.jface.dialogs.IDialogSettings; -import org.eclipse.jface.viewers.ILabelProvider; -import org.eclipse.jface.viewers.ISelectionChangedListener; -import org.eclipse.jface.viewers.IStructuredContentProvider; -import org.eclipse.jface.viewers.IStructuredSelection; -import org.eclipse.jface.viewers.SelectionChangedEvent; -import org.eclipse.jface.viewers.StructuredViewer; -import org.eclipse.jface.viewers.TableViewer; -import org.eclipse.jface.viewers.Viewer; -import org.eclipse.jface.viewers.ViewerFilter; -import org.eclipse.papyrus.infra.emf.Activator; -import org.eclipse.papyrus.infra.services.labelprovider.service.IDetailLabelProvider; -import org.eclipse.papyrus.infra.widgets.editors.AbstractEditor; -import org.eclipse.papyrus.infra.widgets.editors.ICommitListener; -import org.eclipse.papyrus.infra.widgets.editors.StringEditor; -import org.eclipse.papyrus.infra.widgets.providers.CollectionContentProvider; -import org.eclipse.papyrus.infra.widgets.providers.EncapsulatedContentProvider; -import org.eclipse.papyrus.infra.widgets.providers.PatternViewerFilter; -import org.eclipse.swt.SWT; -import org.eclipse.swt.custom.CLabel; -import org.eclipse.swt.layout.GridData; -import org.eclipse.swt.layout.GridLayout; -import org.eclipse.swt.widgets.Composite; -import org.eclipse.swt.widgets.Group; -import org.eclipse.swt.widgets.Table; - -/** - * This providers adds a text-filter and an History to EMF-based content providers - */ -//TODO : Extend (Abstract)FilteredContentProvider -public class EMFGraphicalContentProvider extends EncapsulatedContentProvider implements ISelectionChangedListener { - - private static final String DIALOG_SETTINGS = EMFGraphicalContentProvider.class.getName(); - - protected String historyId; - - //Unused (yet) - //TODO : Add a preference or a collapsible composite for this feature (Or both) - // - // /** - // * The current metaclass viewer filter - // */ - // protected ViewerFilter currentMetaclassViewerFilter; - - protected ViewerFilter patternFilter; - - private static final String HISTORY_SETTINGS = "History"; //$NON-NLS-1$ - - private static final String PREVIOUS_SELECTION = "PreviousSelection"; - - protected List selectionHistory; - - protected CLabel detailLabel; - - protected Object selectedObject; - - protected StructuredViewer viewer; - - protected ResourceSet resourceSet; - - private static final int HISTORY_MAX_SIZE = 5; - - private String currentFilterPattern; - - private TableViewer historyViewer; - - /** - * the wanted root of the contentprovider - */ - - /** - * the constructor - */ - public EMFGraphicalContentProvider(IStructuredContentProvider semanticProvider, ResourceSet resourceSet, String historyId) { - super(semanticProvider); - this.historyId = historyId; - this.resourceSet = resourceSet; - } - - /** - * {@inheritDoc} - */ - @Override - public void createBefore(Composite parent) { - createPatternFilter(parent); - } - - protected void createPatternFilter(Composite parent) { - StringEditor editor = new StringEditor(parent, SWT.NONE); - editor.setLabel("Filter:"); - editor.setToolTipText("Enter the name of the element you're looking for. You can use * as a wildcard"); - editor.setValidateOnDelay(true); - patternFilter = new PatternViewerFilter(); - currentFilterPattern = ""; //$NON-NLS-1$ - ((PatternViewerFilter)patternFilter).setPattern(currentFilterPattern); - - editor.addCommitListener(new ICommitListener() { - - public void commit(AbstractEditor editor) { - String filterPattern = (String)((StringEditor)editor).getValue(); - ((PatternViewerFilter)patternFilter).setPattern(filterPattern); - viewer.refresh(); - if(!("".equals(filterPattern) || currentFilterPattern.equals(filterPattern))) { - - //FIXME: The reveal first match algorithm is not compatible with infinite trees and had bad performances - //Object firstMatch = getFirstMatchingElement(null); - //if(firstMatch != null) { - // revealSemanticElement(Collections.singletonList(firstMatch)); - //} - - currentFilterPattern = filterPattern; - } - } - - }); - - List filters = new LinkedList(Arrays.asList(viewer.getFilters())); - filters.add(patternFilter); - viewer.setFilters(filters.toArray(new ViewerFilter[filters.size()])); - } - - /** - * Returns the first (encapsulated) element matching the current filters - * - * @return - */ - protected Object getFirstMatchingElement(Object parent) { - //Browse from the root element - if(parent == null) { - for(Object parentElement : getElements(viewer.getInput())) { - Object firstMatch = getFirstMatchingElement(parentElement); - if(firstMatch != null) { - return firstMatch; - } - } - return null; - } - - for(ViewerFilter filter : viewer.getFilters()) { - if(!filter.select(viewer, getParent(parent), parent)) { - return null; - } - } - - //Test the current element - if(isValidValue(parent)) { - return parent; - } - - //Browse the child elements - for(Object childElement : getChildren(parent)) { - Object firstMatch = getFirstMatchingElement(childElement); - if(firstMatch != null) { - return firstMatch; - } - } - - //No match found - return null; - } - - /** - * {@inheritDoc} - */ - @Override - public void createAfter(Composite parent) { - parent.setLayout(new GridLayout(1, false)); - // createMetaclassFilter(parent); //Disabled - createHistory(parent); - createDetailArea(parent); - } - - /** - * Creates a widget referencing the recently selected elements - * - * @param parent - * The composite in which the widget will be created - */ - protected void createHistory(Composite parent) { - initSelectionHistory(); - - Group historyGroup = new Group(parent, SWT.NONE); - historyGroup.setText("Recent selections"); - historyGroup.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, false, 1, 1)); - historyGroup.setLayout(new GridLayout(1, true)); - - // table - Table historyTable = new Table(historyGroup, SWT.BORDER | SWT.SINGLE); - GridData data = new GridData(SWT.FILL, SWT.FILL, true, false); - data.heightHint = 70; - historyTable.setLayoutData(data); - historyViewer = new TableViewer(historyTable); - historyViewer.setContentProvider(CollectionContentProvider.instance); - historyViewer.setLabelProvider(viewer.getLabelProvider()); - historyViewer.setInput(selectionHistory); - historyViewer.addSelectionChangedListener(new ISelectionChangedListener() { - - /** - * {@inheritDoc} - */ - public void selectionChanged(SelectionChangedEvent event) { - IStructuredSelection selection = (IStructuredSelection)historyViewer.getSelection(); - Object selectedObject = selection.getFirstElement(); - if(selectedObject instanceof EObject) { - EObject eObject = ((EObject)selectedObject); - revealSemanticElement(Collections.singletonList(eObject)); - } - } - }); - } - - /** - * Inits the History - */ - protected void initSelectionHistory() { - selectionHistory = new ArrayList(HISTORY_MAX_SIZE + 1); - - IDialogSettings historySettings = getDialogSettings().getSection(HISTORY_SETTINGS); - if(historySettings != null && resourceSet != null) { - String[] uriHistory = historySettings.getArray(PREVIOUS_SELECTION); - // for each element in the list, try to get the EObject by its URI - if(uriHistory != null) { - for(String uri : uriHistory) { - try { - EObject object = resourceSet.getEObject(URI.createURI(uri), true); - if(object != null && !selectionHistory.contains(object)) { - selectionHistory.add(object); - } - } catch (Exception ex) { - //Ignore : if the resource doesn't exist anymore, we just skip it - } - } - } - } - } - - /** - * Creates a widget to filter the tree according to the selected - * metaclass. - * - * @param parent - * The Composite in which the widgets will be created - * @deprecated - */ - @Deprecated - protected void createMetaclassFilter(Composite parent) { - // if(semanticRoot == null) { - // return; - // } - // - // Composite container = new Composite(parent, SWT.NONE); - // container.setLayout(new GridLayout(2, false)); - // container.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, false)); - // - // ResourceSet resourceSet = semanticRoot.eResource().getResourceSet(); - // EcoreUtil.resolveAll(resourceSet); - // - // Label metamodelLabel = new Label(container, SWT.NONE); - // metamodelLabel.setText("Metamodel:"); - // - // ComboViewer metamodelViewer = new ComboViewer(container); - // metamodelViewer.setContentProvider(getMetamodelContentProvider()); - // metamodelViewer.setLabelProvider(new EMFLabelProvider()); - // metamodelViewer.setInput(semanticRoot); - // metamodelViewer.getCombo().setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, false)); - // - // Label metaclassLabel = new Label(container, SWT.NONE); - // metaclassLabel.setText("Metaclass:"); - // - // final ComboViewer metaclassViewer = new ComboViewer(container); - // IStructuredContentProvider metaclassProvider = getMetaclassContentProvider(); - // metaclassViewer.setContentProvider(metaclassProvider); - // metaclassViewer.setLabelProvider(new EMFLabelProvider()); - // metaclassViewer.getCombo().setEnabled(false); - // metaclassViewer.getCombo().setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, false)); - // - // metamodelViewer.setFilters(new ViewerFilter[]{ new MetamodelContentFilter(metaclassProvider) }); - // - // metamodelViewer.addSelectionChangedListener(new ISelectionChangedListener() { - // - // public void selectionChanged(SelectionChangedEvent event) { - // metaclassViewer.setInput(((IStructuredSelection)event.getSelection()).getFirstElement()); - // metaclassViewer.getCombo().setEnabled(true); - // } - // }); - // - // metaclassViewer.addSelectionChangedListener(new ISelectionChangedListener() { - // - // public void selectionChanged(SelectionChangedEvent event) { - // if(!event.getSelection().isEmpty()) { - // Object selectedObject = ((IStructuredSelection)event.getSelection()).getFirstElement(); - // List filters = new LinkedList(Arrays.asList(viewer.getFilters())); - // filters.remove(currentMetaclassViewerFilter); - // currentMetaclassViewerFilter = getMetaclassViewerFilter(selectedObject); - // filters.add(currentMetaclassViewerFilter); - // viewer.setFilters(filters.toArray(new ViewerFilter[filters.size()])); - // viewer.refresh(); - // } - // } - // }); - } - - /** - * Creates a label widget to display detailed information on the - * current value (Such as fully qualified name, ...) - * - * @param parent - * The composite in which the widget will be created - */ - protected void createDetailArea(Composite parent) { - detailLabel = new CLabel(parent, SWT.BORDER); - detailLabel.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, false)); - updateDetailLabel(); - } - - // @Deprecated - // protected IStructuredContentProvider getMetamodelContentProvider() { - // return new MetamodelContentProvider(); - // } - // - // @Deprecated - // protected IStructuredContentProvider getMetaclassContentProvider() { - // return new MetaclassContentProvider((EClass)this.metaClassWanted, this.metaClassNotWantedList); - // } - // - // @Deprecated - // protected ILabelProvider getLabelProvider() { - // return new EMFObjectLabelProvider(); - // } - // - // @Deprecated - // protected ViewerFilter getMetaclassViewerFilter(Object selectedMetaClass) { - // return new MetaclassViewerFilter(selectedMetaClass); - // } - - /** - * Returns the dialog settings. Returned object can't be null. - * - * @return dialog settings for this dialog - */ - protected IDialogSettings getDialogSettings() { - IDialogSettings settings = Activator.getDefault().getDialogSettings().getSection(getDialogSettingsIdentifier()); - if(settings == null) { - settings = Activator.getDefault().getDialogSettings().addNewSection(getDialogSettingsIdentifier()); - } - return settings; - } - - private String getDialogSettingsIdentifier() { - return DIALOG_SETTINGS + "_" + historyId; - } - - /** - * Stores dialog settings. - * - * @param settings - * settings used to store dialog - */ - protected void storeDialog(IDialogSettings settings, Collection newValues) { - selectionHistory.removeAll(newValues); - - selectionHistory.addAll(0, newValues); - - //Truncate the history: only keep a sublist of size HISTORY_MAX_SIZE - if(selectionHistory.size() > HISTORY_MAX_SIZE) { - selectionHistory = selectionHistory.subList(0, HISTORY_MAX_SIZE); - } - - List uriList = new ArrayList(); - - // convert list of EObject into URI string list - for(EObject object : selectionHistory) { - URI uri = EcoreUtil.getURI(object); - uriList.add(uri.toString()); - } - - IDialogSettings historySettings = settings.getSection(HISTORY_SETTINGS); - if(historySettings == null) { - historySettings = settings.addNewSection(HISTORY_SETTINGS); - } - historySettings.put(PREVIOUS_SELECTION, uriList.toArray(new String[uriList.size()])); - - historyViewer.setInput(selectionHistory); - } - - @Override - public void inputChanged(Viewer viewer, Object oldInput, Object newInput) { - encapsulated.inputChanged(viewer, oldInput, newInput); - - if(viewer instanceof StructuredViewer) { - this.viewer = (StructuredViewer)viewer; - if(newInput != null && viewer.getControl() != null && !viewer.getControl().isDisposed()) { - this.viewer.addSelectionChangedListener(this); - } - } else { - this.viewer = null; - } - } - - public void selectionChanged(SelectionChangedEvent event) { - selectedObject = ((IStructuredSelection)event.getSelection()).getFirstElement(); - updateDetailLabel(); - } - - private void updateDetailLabel() { - if(detailLabel == null || detailLabel.isDisposed()) { - return; - } - if(selectedObject == null) { - detailLabel.setText(""); - detailLabel.setImage(null); - } else { - ILabelProvider labelProvider = (ILabelProvider)viewer.getLabelProvider(); - String description; - if(labelProvider instanceof IDetailLabelProvider) { - description = ((IDetailLabelProvider)labelProvider).getDetail(selectedObject); - } else { - description = labelProvider.getText(selectedObject); - } - detailLabel.setText(description); - detailLabel.setImage(labelProvider.getImage(selectedObject)); - } - detailLabel.getParent().getParent().layout(); - } - - @Override - public void commit(AbstractEditor editor) { - Iterator selectionIterator = ((IStructuredSelection)viewer.getSelection()).iterator(); - Set eObjectsToStore = new LinkedHashSet(); - while(selectionIterator.hasNext()) { - Object selectedElement = selectionIterator.next(); - if(isValidValue(selectedElement)) { - Object semanticObject = getAdaptedValue(selectedElement); - if(semanticObject instanceof EObject) { - eObjectsToStore.add((EObject)semanticObject); - } - } - } - - if(!eObjectsToStore.isEmpty()) { - storeDialog(getDialogSettings(), eObjectsToStore); - } - } - - @Override - public void dispose() { - super.dispose(); - viewer.removeSelectionChangedListener(this); - } -} +/***************************************************************************** + * Copyright (c) 2010 CEA LIST. + * + * + * 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: + * Patrick Tessier (CEA LIST) Patrick.tessier@cea.fr - Initial API and implementation + * Camille Letavernier (CEA LIST) camille.letavernier@cea.fr - Added graphic contributions for the filters + * Remi Schnekenburger (CEA LIST) remi.schnekenburger@cea.fr - Initial History implementation + * Camille Letavernier (CEA LIST) camille.letavernier@cea.fr - History integration + * + *****************************************************************************/ +package org.eclipse.papyrus.infra.emf.providers; + +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Collection; +import java.util.Collections; +import java.util.Iterator; +import java.util.LinkedHashSet; +import java.util.LinkedList; +import java.util.List; +import java.util.Set; + +import org.eclipse.emf.common.util.URI; +import org.eclipse.emf.ecore.EObject; +import org.eclipse.emf.ecore.resource.ResourceSet; +import org.eclipse.emf.ecore.util.EcoreUtil; +import org.eclipse.jface.dialogs.IDialogSettings; +import org.eclipse.jface.viewers.ILabelProvider; +import org.eclipse.jface.viewers.ISelectionChangedListener; +import org.eclipse.jface.viewers.IStructuredContentProvider; +import org.eclipse.jface.viewers.IStructuredSelection; +import org.eclipse.jface.viewers.SelectionChangedEvent; +import org.eclipse.jface.viewers.StructuredViewer; +import org.eclipse.jface.viewers.TableViewer; +import org.eclipse.jface.viewers.Viewer; +import org.eclipse.jface.viewers.ViewerFilter; +import org.eclipse.papyrus.infra.emf.Activator; +import org.eclipse.papyrus.infra.services.labelprovider.service.IDetailLabelProvider; +import org.eclipse.papyrus.infra.widgets.editors.AbstractEditor; +import org.eclipse.papyrus.infra.widgets.editors.ICommitListener; +import org.eclipse.papyrus.infra.widgets.editors.StringEditor; +import org.eclipse.papyrus.infra.widgets.providers.CollectionContentProvider; +import org.eclipse.papyrus.infra.widgets.providers.EncapsulatedContentProvider; +import org.eclipse.papyrus.infra.widgets.providers.PatternViewerFilter; +import org.eclipse.swt.SWT; +import org.eclipse.swt.custom.CLabel; +import org.eclipse.swt.layout.GridData; +import org.eclipse.swt.layout.GridLayout; +import org.eclipse.swt.widgets.Composite; +import org.eclipse.swt.widgets.Group; +import org.eclipse.swt.widgets.Table; + +/** + * This providers adds a text-filter and an History to EMF-based content providers + */ +//TODO : Extend (Abstract)FilteredContentProvider +public class EMFGraphicalContentProvider extends EncapsulatedContentProvider implements ISelectionChangedListener { + + private static final String DIALOG_SETTINGS = EMFGraphicalContentProvider.class.getName(); + + protected String historyId; + + //Unused (yet) + //TODO : Add a preference or a collapsible composite for this feature (Or both) + // + // /** + // * The current metaclass viewer filter + // */ + // protected ViewerFilter currentMetaclassViewerFilter; + + protected ViewerFilter patternFilter; + + private static final String HISTORY_SETTINGS = "History"; //$NON-NLS-1$ + + private static final String PREVIOUS_SELECTION = "PreviousSelection"; //$NON-NLS-1$ + + protected List selectionHistory; + + protected CLabel detailLabel; + + protected Object selectedObject; + + protected StructuredViewer viewer; + + protected ResourceSet resourceSet; + + private static final int HISTORY_MAX_SIZE = 5; + + private String currentFilterPattern; + + private TableViewer historyViewer; + + /** + * the wanted root of the contentprovider + */ + + /** + * the constructor + */ + public EMFGraphicalContentProvider(IStructuredContentProvider semanticProvider, ResourceSet resourceSet, String historyId) { + super(semanticProvider); + this.historyId = historyId; + this.resourceSet = resourceSet; + } + + /** + * {@inheritDoc} + */ + @Override + public void createBefore(Composite parent) { + createPatternFilter(parent); + } + + protected void createPatternFilter(Composite parent) { + StringEditor editor = new StringEditor(parent, SWT.NONE); + editor.setLabel("Filter:"); + editor.setToolTipText("Enter the name of the element you're looking for. You can use * as a wildcard"); + editor.setValidateOnDelay(true); + patternFilter = new PatternViewerFilter(); + currentFilterPattern = ""; //$NON-NLS-1$ + ((PatternViewerFilter)patternFilter).setPattern(currentFilterPattern); + + editor.addCommitListener(new ICommitListener() { + + public void commit(AbstractEditor editor) { + String filterPattern = (String)((StringEditor)editor).getValue(); + ((PatternViewerFilter)patternFilter).setPattern(filterPattern); + viewer.refresh(); + if(!("".equals(filterPattern) || currentFilterPattern.equals(filterPattern))) { + + //FIXME: The reveal first match algorithm is not compatible with infinite trees and had bad performances + //Object firstMatch = getFirstMatchingElement(null); + //if(firstMatch != null) { + // revealSemanticElement(Collections.singletonList(firstMatch)); + //} + + currentFilterPattern = filterPattern; + } + } + + }); + + List filters = new LinkedList(Arrays.asList(viewer.getFilters())); + filters.add(patternFilter); + viewer.setFilters(filters.toArray(new ViewerFilter[filters.size()])); + } + + /** + * Returns the first (encapsulated) element matching the current filters + * + * @return + */ + protected Object getFirstMatchingElement(Object parent) { + //Browse from the root element + if(parent == null) { + for(Object parentElement : getElements(viewer.getInput())) { + Object firstMatch = getFirstMatchingElement(parentElement); + if(firstMatch != null) { + return firstMatch; + } + } + return null; + } + + for(ViewerFilter filter : viewer.getFilters()) { + if(!filter.select(viewer, getParent(parent), parent)) { + return null; + } + } + + //Test the current element + if(isValidValue(parent)) { + return parent; + } + + //Browse the child elements + for(Object childElement : getChildren(parent)) { + Object firstMatch = getFirstMatchingElement(childElement); + if(firstMatch != null) { + return firstMatch; + } + } + + //No match found + return null; + } + + /** + * {@inheritDoc} + */ + @Override + public void createAfter(Composite parent) { + parent.setLayout(new GridLayout(1, false)); + // createMetaclassFilter(parent); //Disabled + createHistory(parent); + createDetailArea(parent); + } + + /** + * Creates a widget referencing the recently selected elements + * + * @param parent + * The composite in which the widget will be created + */ + protected void createHistory(Composite parent) { + initSelectionHistory(); + + Group historyGroup = new Group(parent, SWT.NONE); + historyGroup.setText("Recent selections"); + historyGroup.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, false, 1, 1)); + historyGroup.setLayout(new GridLayout(1, true)); + + // table + Table historyTable = new Table(historyGroup, SWT.BORDER | SWT.SINGLE); + GridData data = new GridData(SWT.FILL, SWT.FILL, true, false); + data.heightHint = 70; + historyTable.setLayoutData(data); + historyViewer = new TableViewer(historyTable); + historyViewer.setContentProvider(CollectionContentProvider.instance); + historyViewer.setLabelProvider(viewer.getLabelProvider()); + historyViewer.setInput(selectionHistory); + historyViewer.addSelectionChangedListener(new ISelectionChangedListener() { + + /** + * {@inheritDoc} + */ + public void selectionChanged(SelectionChangedEvent event) { + IStructuredSelection selection = (IStructuredSelection)historyViewer.getSelection(); + Object selectedObject = selection.getFirstElement(); + if(selectedObject instanceof EObject) { + EObject eObject = ((EObject)selectedObject); + revealSemanticElement(Collections.singletonList(eObject)); + } + } + }); + } + + /** + * Inits the History + */ + protected void initSelectionHistory() { + selectionHistory = new ArrayList(HISTORY_MAX_SIZE + 1); + + IDialogSettings historySettings = getDialogSettings().getSection(HISTORY_SETTINGS); + if(historySettings != null && resourceSet != null) { + String[] uriHistory = historySettings.getArray(PREVIOUS_SELECTION); + // for each element in the list, try to get the EObject by its URI + if(uriHistory != null) { + for(String uri : uriHistory) { + try { + EObject object = resourceSet.getEObject(URI.createURI(uri), true); + if(object != null && !selectionHistory.contains(object)) { + selectionHistory.add(object); + } + } catch (Exception ex) { + //Ignore : if the resource doesn't exist anymore, we just skip it + } + } + } + } + } + + /** + * Creates a widget to filter the tree according to the selected + * metaclass. + * + * @param parent + * The Composite in which the widgets will be created + * @deprecated + */ + @Deprecated + protected void createMetaclassFilter(Composite parent) { + // if(semanticRoot == null) { + // return; + // } + // + // Composite container = new Composite(parent, SWT.NONE); + // container.setLayout(new GridLayout(2, false)); + // container.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, false)); + // + // ResourceSet resourceSet = semanticRoot.eResource().getResourceSet(); + // EcoreUtil.resolveAll(resourceSet); + // + // Label metamodelLabel = new Label(container, SWT.NONE); + // metamodelLabel.setText("Metamodel:"); + // + // ComboViewer metamodelViewer = new ComboViewer(container); + // metamodelViewer.setContentProvider(getMetamodelContentProvider()); + // metamodelViewer.setLabelProvider(new EMFLabelProvider()); + // metamodelViewer.setInput(semanticRoot); + // metamodelViewer.getCombo().setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, false)); + // + // Label metaclassLabel = new Label(container, SWT.NONE); + // metaclassLabel.setText("Metaclass:"); + // + // final ComboViewer metaclassViewer = new ComboViewer(container); + // IStructuredContentProvider metaclassProvider = getMetaclassContentProvider(); + // metaclassViewer.setContentProvider(metaclassProvider); + // metaclassViewer.setLabelProvider(new EMFLabelProvider()); + // metaclassViewer.getCombo().setEnabled(false); + // metaclassViewer.getCombo().setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, false)); + // + // metamodelViewer.setFilters(new ViewerFilter[]{ new MetamodelContentFilter(metaclassProvider) }); + // + // metamodelViewer.addSelectionChangedListener(new ISelectionChangedListener() { + // + // public void selectionChanged(SelectionChangedEvent event) { + // metaclassViewer.setInput(((IStructuredSelection)event.getSelection()).getFirstElement()); + // metaclassViewer.getCombo().setEnabled(true); + // } + // }); + // + // metaclassViewer.addSelectionChangedListener(new ISelectionChangedListener() { + // + // public void selectionChanged(SelectionChangedEvent event) { + // if(!event.getSelection().isEmpty()) { + // Object selectedObject = ((IStructuredSelection)event.getSelection()).getFirstElement(); + // List filters = new LinkedList(Arrays.asList(viewer.getFilters())); + // filters.remove(currentMetaclassViewerFilter); + // currentMetaclassViewerFilter = getMetaclassViewerFilter(selectedObject); + // filters.add(currentMetaclassViewerFilter); + // viewer.setFilters(filters.toArray(new ViewerFilter[filters.size()])); + // viewer.refresh(); + // } + // } + // }); + } + + /** + * Creates a label widget to display detailed information on the + * current value (Such as fully qualified name, ...) + * + * @param parent + * The composite in which the widget will be created + */ + protected void createDetailArea(Composite parent) { + detailLabel = new CLabel(parent, SWT.BORDER); + detailLabel.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, false)); + updateDetailLabel(); + } + + // @Deprecated + // protected IStructuredContentProvider getMetamodelContentProvider() { + // return new MetamodelContentProvider(); + // } + // + // @Deprecated + // protected IStructuredContentProvider getMetaclassContentProvider() { + // return new MetaclassContentProvider((EClass)this.metaClassWanted, this.metaClassNotWantedList); + // } + // + // @Deprecated + // protected ILabelProvider getLabelProvider() { + // return new EMFObjectLabelProvider(); + // } + // + // @Deprecated + // protected ViewerFilter getMetaclassViewerFilter(Object selectedMetaClass) { + // return new MetaclassViewerFilter(selectedMetaClass); + // } + + /** + * Returns the dialog settings. Returned object can't be null. + * + * @return dialog settings for this dialog + */ + protected IDialogSettings getDialogSettings() { + IDialogSettings settings = Activator.getDefault().getDialogSettings().getSection(getDialogSettingsIdentifier()); + if(settings == null) { + settings = Activator.getDefault().getDialogSettings().addNewSection(getDialogSettingsIdentifier()); + } + return settings; + } + + private String getDialogSettingsIdentifier() { + return DIALOG_SETTINGS + "_" + historyId; + } + + /** + * Stores dialog settings. + * + * @param settings + * settings used to store dialog + */ + protected void storeDialog(IDialogSettings settings, Collection newValues) { + selectionHistory.removeAll(newValues); + + selectionHistory.addAll(0, newValues); + + //Truncate the history: only keep a sublist of size HISTORY_MAX_SIZE + if(selectionHistory.size() > HISTORY_MAX_SIZE) { + selectionHistory = selectionHistory.subList(0, HISTORY_MAX_SIZE); + } + + List uriList = new ArrayList(); + + // convert list of EObject into URI string list + for(EObject object : selectionHistory) { + URI uri = EcoreUtil.getURI(object); + uriList.add(uri.toString()); + } + + IDialogSettings historySettings = settings.getSection(HISTORY_SETTINGS); + if(historySettings == null) { + historySettings = settings.addNewSection(HISTORY_SETTINGS); + } + historySettings.put(PREVIOUS_SELECTION, uriList.toArray(new String[uriList.size()])); + + historyViewer.setInput(selectionHistory); + } + + @Override + public void inputChanged(Viewer viewer, Object oldInput, Object newInput) { + encapsulated.inputChanged(viewer, oldInput, newInput); + + if(viewer instanceof StructuredViewer) { + this.viewer = (StructuredViewer)viewer; + if(newInput != null && viewer.getControl() != null && !viewer.getControl().isDisposed()) { + this.viewer.addSelectionChangedListener(this); + } + } else { + this.viewer = null; + } + } + + public void selectionChanged(SelectionChangedEvent event) { + selectedObject = ((IStructuredSelection)event.getSelection()).getFirstElement(); + updateDetailLabel(); + } + + private void updateDetailLabel() { + if(detailLabel == null || detailLabel.isDisposed()) { + return; + } + if(selectedObject == null) { + detailLabel.setText(""); + detailLabel.setImage(null); + } else { + ILabelProvider labelProvider = (ILabelProvider)viewer.getLabelProvider(); + String description; + if(labelProvider instanceof IDetailLabelProvider) { + description = ((IDetailLabelProvider)labelProvider).getDetail(selectedObject); + } else { + description = labelProvider.getText(selectedObject); + } + detailLabel.setText(description); + detailLabel.setImage(labelProvider.getImage(selectedObject)); + } + detailLabel.getParent().getParent().layout(); + } + + @Override + public void commit(AbstractEditor editor) { + Iterator selectionIterator = ((IStructuredSelection)viewer.getSelection()).iterator(); + Set eObjectsToStore = new LinkedHashSet(); + while(selectionIterator.hasNext()) { + Object selectedElement = selectionIterator.next(); + if(isValidValue(selectedElement)) { + Object semanticObject = getAdaptedValue(selectedElement); + if(semanticObject instanceof EObject) { + eObjectsToStore.add((EObject)semanticObject); + } + } + } + + if(!eObjectsToStore.isEmpty()) { + storeDialog(getDialogSettings(), eObjectsToStore); + } + } + + @Override + public void dispose() { + super.dispose(); + viewer.removeSelectionChangedListener(this); + } +} diff --git a/plugins/infra/emf/org.eclipse.papyrus.infra.emf/src/org/eclipse/papyrus/infra/emf/providers/strategy/SemanticEMFContentProvider.java b/plugins/infra/emf/org.eclipse.papyrus.infra.emf/src/org/eclipse/papyrus/infra/emf/providers/strategy/SemanticEMFContentProvider.java index ced8e99148f..c9e4d63fbfc 100644 --- a/plugins/infra/emf/org.eclipse.papyrus.infra.emf/src/org/eclipse/papyrus/infra/emf/providers/strategy/SemanticEMFContentProvider.java +++ b/plugins/infra/emf/org.eclipse.papyrus.infra.emf/src/org/eclipse/papyrus/infra/emf/providers/strategy/SemanticEMFContentProvider.java @@ -1,216 +1,217 @@ -/***************************************************************************** - * Copyright (c) 2012, 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 - * Christian W. Damus (CEA) - bug 410346 - * - *****************************************************************************/ -package org.eclipse.papyrus.infra.emf.providers.strategy; - -import java.util.Collections; -import java.util.LinkedList; -import java.util.List; - -import org.eclipse.emf.common.notify.AdapterFactory; -import org.eclipse.emf.ecore.EClassifier; -import org.eclipse.emf.ecore.EObject; -import org.eclipse.emf.ecore.EReference; -import org.eclipse.emf.ecore.EStructuralFeature; -import org.eclipse.emf.ecore.resource.Resource; -import org.eclipse.emf.ecore.resource.ResourceSet; -import org.eclipse.emf.edit.provider.ComposedAdapterFactory; -import org.eclipse.emf.edit.provider.IDisposable; -import org.eclipse.papyrus.emf.facet.custom.core.ICustomizationManager; -import org.eclipse.papyrus.emf.facet.custom.ui.internal.CustomizedTreeContentProvider; -import org.eclipse.papyrus.infra.emf.Activator; -import org.eclipse.papyrus.infra.emf.utils.EMFHelper; -import org.eclipse.papyrus.infra.widgets.providers.IAdaptableContentProvider; -import org.eclipse.papyrus.infra.widgets.providers.IHierarchicContentProvider; -import org.eclipse.papyrus.infra.widgets.providers.IStaticContentProvider; - - -public class SemanticEMFContentProvider extends CustomizedTreeContentProvider implements IAdaptableContentProvider, IHierarchicContentProvider, IStaticContentProvider { - - protected EObject[] roots; - - protected List metaclasses = new LinkedList(); - - protected List notWantedMetaclasses = new LinkedList(); - - protected EObject eObject; - - protected EStructuralFeature feature; - - protected AdapterFactory factory = new ComposedAdapterFactory(ComposedAdapterFactory.Descriptor.Registry.INSTANCE); - - protected SemanticEMFContentProvider() { - super(Activator.getDefault().getCustomizationManager()); - } - - public SemanticEMFContentProvider(EObject editedEObject, EStructuralFeature feature, EObject[] roots, ICustomizationManager customizationManager) { - super(customizationManager); - this.roots = roots; - - configureMetaclasses(feature); - - this.eObject = editedEObject; - this.feature = feature; - } - - public SemanticEMFContentProvider(EObject editedEObject, EStructuralFeature feature, EObject[] roots) { - this(editedEObject, feature, roots, Activator.getDefault().getCustomizationManager()); - } - - protected void configureMetaclasses(EStructuralFeature feature) { - if(feature != null) { - setWantedMetaclasses(Collections.singletonList(feature.getEType())); - } - } - - public SemanticEMFContentProvider(EObject editedEObject, EStructuralFeature feature) { - this(editedEObject, feature, findRoots(editedEObject)); - } - - public SemanticEMFContentProvider(EObject[] roots) { - this(null, null, roots); - } - - public SemanticEMFContentProvider(EObject[] roots, ICustomizationManager customizationManager) { - this(null, null, roots, customizationManager); - } - - public SemanticEMFContentProvider(ResourceSet root) { - this(null, null, root); - } - - public SemanticEMFContentProvider(EObject editedEObject, EStructuralFeature feature, ResourceSet root) { - this(editedEObject, feature, getRoots(root)); - } - - @Override - public void dispose() { - try { - // Because we created this adapter factory, we must dispose it - if(factory instanceof IDisposable) { - ((IDisposable)factory).dispose(); - } - } finally { - super.dispose(); - } - } - - protected static EObject[] getRoots(ResourceSet root) { - List roots = new LinkedList(); - if(root != null) { - for(Resource resource : root.getResources()) { - roots.addAll(resource.getContents()); - } - } - return roots.toArray(new EObject[roots.size()]); - } - - protected static EObject[] findRoots(EObject source) { - - //The EObject is not contained in a resource : we return the top-level EObject - if(source.eResource() == null) { - while(source.eContainer() != null) { - source = source.eContainer(); - } - - return new EObject[]{ source }; - } - - //The resource is not contained in a resource set : we return the resource's contents - if(source.eResource().getResourceSet() == null) { - return source.eResource().getContents().toArray(new EObject[0]); - } - - //We have a full resourceSet : we return its contents - return getRoots(source.eResource().getResourceSet()); - } - - @Override - public EObject[] getRootElements(final Object inputElement) { - return roots; - } - - public Object getAdaptedValue(Object containerElement) { - return EMFHelper.getEObject(containerElement); - } - - @Override - public boolean hasChildren(Object parent) { - //May be expensive - Object[] children = getChildren(parent); - return children != null && children.length > 0; - } - - public boolean isValidValue(Object containerElement) { - // get the semantic object form the element - Object semanticObject = getAdaptedValue(containerElement); - - //return false for EReference and non-semantic objects - if(semanticObject instanceof EReference || semanticObject == null) { - return false; - } - - //Tests whether the element is compatible with at least one metaclass - if(metaclasses != null && !metaclasses.isEmpty()) { - boolean compatible = false; - - for(Object metaclass : metaclasses) { - if(isCompatibleMetaclass(containerElement, metaclass)) { - compatible = true; - break; - } - } - - if(!compatible) { - return false; - } - } - - //If the element is compatible with at least one metaclass from notWanted, then it is not valid - for(Object metaclass : notWantedMetaclasses) { - if(isCompatibleMetaclass(containerElement, metaclass)) { - return false; - } - } - - return true; - } - - protected boolean isCompatibleMetaclass(Object containerElement, Object metaclass) { - if(metaclass instanceof EClassifier) { - Object semanticElement = getAdaptedValue(containerElement); - return ((EClassifier)metaclass).isInstance(semanticElement); - } - return false; - } - - public void setWantedMetaclasses(List metaclasses) { - this.metaclasses = metaclasses; - } - - public void setNotWantedMetaclasses(List notWantedMetaclasses) { - this.notWantedMetaclasses = notWantedMetaclasses; - } - - public Object[] getElements() { - return super.getElements(null); - } - - public List getWantedMetaclasses() { - return metaclasses; - } - - public List getNotWantedMetaclasses() { - return notWantedMetaclasses; - } -} +/***************************************************************************** + * Copyright (c) 2012, 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 + * Christian W. Damus (CEA) - bug 410346 + * + *****************************************************************************/ +package org.eclipse.papyrus.infra.emf.providers.strategy; + +import java.util.Collections; +import java.util.LinkedList; +import java.util.List; + +import org.eclipse.emf.common.notify.AdapterFactory; +import org.eclipse.emf.ecore.EClassifier; +import org.eclipse.emf.ecore.EObject; +import org.eclipse.emf.ecore.EReference; +import org.eclipse.emf.ecore.EStructuralFeature; +import org.eclipse.emf.ecore.resource.Resource; +import org.eclipse.emf.ecore.resource.ResourceSet; +import org.eclipse.emf.edit.provider.ComposedAdapterFactory; +import org.eclipse.emf.edit.provider.IDisposable; +import org.eclipse.papyrus.emf.facet.custom.core.ICustomizationManager; +import org.eclipse.papyrus.emf.facet.custom.ui.internal.CustomizedTreeContentProvider; +import org.eclipse.papyrus.infra.emf.Activator; +import org.eclipse.papyrus.infra.emf.utils.EMFHelper; +import org.eclipse.papyrus.infra.widgets.providers.IAdaptableContentProvider; +import org.eclipse.papyrus.infra.widgets.providers.IHierarchicContentProvider; +import org.eclipse.papyrus.infra.widgets.providers.IStaticContentProvider; + + +public class SemanticEMFContentProvider extends CustomizedTreeContentProvider implements IAdaptableContentProvider, IHierarchicContentProvider, IStaticContentProvider { + + protected EObject[] roots; + + protected List metaclasses = new LinkedList(); + + protected List notWantedMetaclasses = new LinkedList(); + + protected EObject eObject; + + protected EStructuralFeature feature; + + protected AdapterFactory factory = new ComposedAdapterFactory(ComposedAdapterFactory.Descriptor.Registry.INSTANCE); + + protected SemanticEMFContentProvider() { + super(Activator.getDefault().getCustomizationManager()); + } + + public SemanticEMFContentProvider(EObject editedEObject, EStructuralFeature feature, EObject[] roots, ICustomizationManager customizationManager) { + super(customizationManager); + this.roots = roots; + + configureMetaclasses(feature); + + this.eObject = editedEObject; + this.feature = feature; + } + + public SemanticEMFContentProvider(EObject editedEObject, EStructuralFeature feature, EObject[] roots) { + this(editedEObject, feature, roots, Activator.getDefault().getCustomizationManager()); + } + + protected void configureMetaclasses(EStructuralFeature feature) { + if(feature != null) { + setWantedMetaclasses(Collections.singletonList(feature.getEType())); + } + } + + public SemanticEMFContentProvider(EObject editedEObject, EStructuralFeature feature) { + this(editedEObject, feature, findRoots(editedEObject)); + } + + public SemanticEMFContentProvider(EObject[] roots) { + this(null, null, roots); + } + + public SemanticEMFContentProvider(EObject[] roots, ICustomizationManager customizationManager) { + this(null, null, roots, customizationManager); + } + + public SemanticEMFContentProvider(ResourceSet root) { + this(null, null, root); + } + + public SemanticEMFContentProvider(EObject editedEObject, EStructuralFeature feature, ResourceSet root) { + this(editedEObject, feature, getRoots(root)); + } + + @Override + public void dispose() { + try { + // Because we created this adapter factory, we must dispose it + if(factory instanceof IDisposable) { + ((IDisposable)factory).dispose(); + } + } finally { + super.dispose(); + } + } + + protected static EObject[] getRoots(ResourceSet root) { + List roots = new LinkedList(); + if(root != null) { + for(Resource resource : root.getResources()) { + roots.addAll(resource.getContents()); + } + } + return roots.toArray(new EObject[roots.size()]); + } + + protected static EObject[] findRoots(EObject source) { + + //The EObject is not contained in a resource : we return the top-level EObject + if(source.eResource() == null) { + while(source.eContainer() != null) { + source = source.eContainer(); + } + + return new EObject[]{ source }; + } + + //The resource is not contained in a resource set : we return the resource's contents + if(source.eResource().getResourceSet() == null) { + return source.eResource().getContents().toArray(new EObject[0]); + } + + //We have a full resourceSet : we return its contents + return getRoots(source.eResource().getResourceSet()); + } + + @Override + public EObject[] getRootElements(final Object inputElement) { + return roots; + } + + public Object getAdaptedValue(Object containerElement) { + return EMFHelper.getEObject(containerElement); + } + + @Override + public boolean hasChildren(Object parent) { + //May be expensive + Object[] children = getChildren(parent); + return children != null && children.length > 0; + } + + public boolean isValidValue(Object containerElement) { + // get the semantic object form the element + Object semanticObject = getAdaptedValue(containerElement); + + //return false for EReference and non-semantic objects + if(semanticObject instanceof EReference || semanticObject == null) { + return false; + } + + //Tests whether the element is compatible with at least one metaclass + if(metaclasses != null && !metaclasses.isEmpty()) { + boolean compatible = false; + + for(Object metaclass : metaclasses) { + if(isCompatibleMetaclass(containerElement, metaclass)) { + compatible = true; + break; + } + } + + if(!compatible) { + return false; + } + } + + //If the element is compatible with at least one metaclass from notWanted, then it is not valid + for(Object metaclass : notWantedMetaclasses) { + if(isCompatibleMetaclass(containerElement, metaclass)) { + return false; + } + } + + return true; + } + + protected boolean isCompatibleMetaclass(Object containerElement, Object metaclass) { + if(metaclass instanceof EClassifier) { + Object semanticElement = getAdaptedValue(containerElement); + return ((EClassifier)metaclass).isInstance(semanticElement); + } + return false; + } + + public void setWantedMetaclasses(List metaclasses) { + this.metaclasses = metaclasses; + } + + public void setNotWantedMetaclasses(List notWantedMetaclasses) { + assert notWantedMetaclasses != null : "notWantedMetaclasses must be not null"; //$NON-NLS-1$ + this.notWantedMetaclasses = notWantedMetaclasses; + } + + public Object[] getElements() { + return super.getElements(null); + } + + public List getWantedMetaclasses() { + return metaclasses; + } + + public List getNotWantedMetaclasses() { + return notWantedMetaclasses; + } +} diff --git a/plugins/infra/emf/org.eclipse.papyrus.infra.emf/src/org/eclipse/papyrus/infra/emf/resource/DependencyManagementHelper.java b/plugins/infra/emf/org.eclipse.papyrus.infra.emf/src/org/eclipse/papyrus/infra/emf/resource/DependencyManagementHelper.java index 0ddb1cf4143..e97eb3d2477 100644 --- a/plugins/infra/emf/org.eclipse.papyrus.infra.emf/src/org/eclipse/papyrus/infra/emf/resource/DependencyManagementHelper.java +++ b/plugins/infra/emf/org.eclipse.papyrus.infra.emf/src/org/eclipse/papyrus/infra/emf/resource/DependencyManagementHelper.java @@ -1,405 +1,405 @@ -/***************************************************************************** - * Copyright (c) 2013 CEA LIST. - * - * 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 - *****************************************************************************/ -package org.eclipse.papyrus.infra.emf.resource; - -import java.util.Collection; -import java.util.HashMap; -import java.util.HashSet; -import java.util.Iterator; -import java.util.LinkedList; -import java.util.Map; -import java.util.Set; - -import org.eclipse.emf.common.util.URI; -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.DynamicEObjectImpl; -import org.eclipse.emf.ecore.resource.Resource; -import org.eclipse.emf.ecore.resource.ResourceSet; -import org.eclipse.emf.ecore.util.EcoreUtil; -import org.eclipse.emf.edit.domain.EditingDomain; -import org.eclipse.papyrus.infra.emf.Activator; -import org.eclipse.papyrus.infra.emf.utils.EMFHelper; - -/** - * A Helper to edit dependencies (URIs) between EMF Resources - * - * It replaces all references from a Resource A to a Resource B with references from A to B' - * - * B and B' must be "equivalent" (e.g. B is a copy of B' with or without modifications). - * - * @author Camille Letavernier - * - */ -public class DependencyManagementHelper { - - /** - * Replaces all references (dependencies) in the "fromResources" to the "uriToReplace" URI, with the "targetURI" - * - * Simplified pseudo code algorithm: fromResources.replaceAll(uriToReplace, targetURI) - * - * @param uriToReplace - * The URI of the resource which initially contains the referenced elements. May or may not exist. - * Must not be null - * @param targetURI - * The URI of the resource which contains the newly referenced elements. - * May or may not exist. In the later case, the values will be proxies to the un-existing target URI - * Must not be null - * @param fromResources - * The list of resources to edit. Only the objects of these resources will be modified. - * Must not be empty - * @param editingDomain - * The editing domain. May be null. - * - * @return - * The collection of replacements - */ - public static Collection updateDependencies(URI uriToReplace, URI targetURI, Collection fromResources, EditingDomain editingDomain) { - if(fromResources == null || fromResources.isEmpty()) { - throw new IllegalArgumentException("There is no resource to modify"); - } - - Collection replacements = new LinkedList(); - - for(Resource currentResource : fromResources) { - if(currentResource == null) { - continue; - } - - if(EMFHelper.isReadOnly(currentResource, editingDomain)) { - continue; - } - - replacements.addAll(updateDependencies(uriToReplace, targetURI, currentResource, editingDomain)); - } - - return replacements; - } - - /** - * Replaces all references (dependencies) in the "fromResources" to the "uriToReplace" URI, with the "targetURI" - * - * Simplified pseudo code algorithm: fromResources.replaceAll(uriToReplace, targetURI) - * - * @param uriToReplace - * The URI of the resource which initially contains the referenced elements. May or may not exist. - * Must not be null - * @param targetURI - * The URI of the resource which contains the newly referenced elements. - * May or may not exist. In the later case, the values will be proxies to the un-existing target URI - * Must not be null - * @param fromResource - * The resource to edit. Only the objects of this resource will be modified. - * Must not be null - * @param editingDomain - * The editing domain. May be null. - * @return - * The collection of replacements - */ - public static Collection updateDependencies(URI uriToReplace, URI targetURI, Resource fromResource, EditingDomain editingDomain) { - if(uriToReplace == null) { - throw new IllegalArgumentException("There is no URI to replace"); - } - - if(targetURI == null) { - throw new IllegalArgumentException("There is no target URI"); - } - - if(uriToReplace.equals(targetURI)) { - throw new IllegalArgumentException("The source and target URIs are identical"); - } - - if(fromResource == null) { - throw new IllegalArgumentException("The edited resource must not be null"); - } - - Iterator allContentsIterator = fromResource.getAllContents(); - - Collection replacements = new LinkedList(); - - while(allContentsIterator.hasNext()) { - EObject eObject = allContentsIterator.next(); - - for(EReference reference : eObject.eClass().getEAllReferences()) { - if(reference.isContainment()) { - continue; - } - - if(!reference.isChangeable()) { - continue; - } - - Object value = eObject.eGet(reference); - if(value instanceof EObject) { - EObject eObjectToReplace = (EObject)value; - - EObject newEObject = checkAndReplace(eObjectToReplace, uriToReplace, targetURI); - if(newEObject == null) { - continue; - } - - try { - //System.out.println("Replace " + EcoreUtil.getURI(eObjectToReplace) + " with " + EcoreUtil.getURI(newEObject)); - eObject.eSet(reference, newEObject); - replacements.add(new ReplacementImpl(eObject, reference, eObjectToReplace, newEObject)); - } catch (Exception ex) { - Activator.log.error(ex); - } - - } else if(value instanceof Collection) { - Map previousToNewValue = new HashMap(); - - Collection collection = (Collection)value; - - for(Object collectionElement : (Collection)value) { - if(collectionElement instanceof EObject) { - EObject eObjectToReplace = (EObject)collectionElement; - EObject newEObject = checkAndReplace(eObjectToReplace, uriToReplace, targetURI); - if(newEObject == null) { - continue; - } - - //System.out.println("Replace " + EcoreUtil.getURI(eObjectToReplace) + " with " + EcoreUtil.getURI(newEObject)); - previousToNewValue.put(eObjectToReplace, newEObject); - } - } - - if(previousToNewValue.isEmpty()) { - continue; - } - - if(collection instanceof EStructuralFeature.Setting) { - EStructuralFeature.Setting setting = (EStructuralFeature.Setting)collection; - for(Map.Entry entry : previousToNewValue.entrySet()) { - EcoreUtil.replace(setting, entry.getKey(), entry.getValue()); - replacements.add(new ReplacementImpl(eObject, reference, entry.getKey(), entry.getValue())); - } - } - } - } - } - - return replacements; - } - - /** - * Replaces the EObject (Which may be a proxy) by its equivalent in the given Resource's URI. - * Returns null if the "currentValueToReplace" doesn't belong to the resource represented by "uriToReplace". - * - * @param currentValueToReplace - * The current value, to be replaced. May be a proxy - * @param uriToReplace - * The URI of the resource to be replaced. - * @param targetURI - * The URI of the target resource (Which will contain the resulting EObject). - * The resource doesn't need to exist (and won't be created). If it doesn't exist, this method will return a Proxy - * @return - * The EObject equivalent to the replaced EObject, in the target resource. - */ - private static EObject checkAndReplace(EObject currentValueToReplace, URI uriToReplace, URI targetURI) { - URI eObjectURIToReplace = EcoreUtil.getURI(currentValueToReplace); - URI resourceURI = eObjectURIToReplace.trimFragment(); - - if(!uriToReplace.equals(resourceURI)) { - return null; - } - - return replace(currentValueToReplace, targetURI); - } - - /** - * Replaces the EObject (Which may be a proxy) by its equivalent in the given Resource's URI. - * - * @param currentValueToReplace - * The current value, to be replaced. May be a proxy - * @param targetURI - * The URI of the target resource (Which will contain the resulting EObject). - * The resource doesn't need to exist (and won't be created). If it doesn't exist, this method will return a Proxy - * @return - * The EObject equivalent to the replaced EObject, in the target resource. - */ - public static EObject replace(EObject currentValueToReplace, URI targetURI) { - URI eObjectURIToReplace = EcoreUtil.getURI(currentValueToReplace); - - EClass targetEClass = currentValueToReplace.eClass(); - - InternalEObject proxyEObject; - - //Try to instantiate the Proxy from the same EClass. - EObject newEObject = targetEClass.getEPackage().getEFactoryInstance().create(targetEClass); - if(newEObject instanceof InternalEObject) { - proxyEObject = (InternalEObject)newEObject; - } else { - //If the result is not an InternalEObject, create a basic EObject instead - proxyEObject = new DynamicEObjectImpl(targetEClass); - } - - String eObjectFragment = eObjectURIToReplace.fragment(); - URI eObjectURI = targetURI.appendFragment(eObjectFragment); - proxyEObject.eSetProxyURI(eObjectURI); - - return proxyEObject; - } - - /** - * Replaces all references (dependencies) in the "resourceSet" to the "uriToReplace" URI, with the "targetURI" - * - * Simplified pseudo code algorithm: resourceSet.getResources().replaceAll(uriToReplace, targetURI) - * - * @param uriToReplace - * The URI of the resource which initially contains the referenced elements. May or may not exist. - * Must not be null - * @param targetURI - * The URI of the resource which contains the newly referenced elements. - * May or may not exist. In the later case, the values will be proxies to the un-existing target URI - * Must not be null - * @param resourceSet - * The resourceSet to edit. Its resources will be modified. - * @param editingDomain - * The editing domain. May be null. - * @return - * The collection of replacements - */ - public static Collection updateDependencies(URI uriToReplace, URI targetURI, ResourceSet resourceSet, EditingDomain editingDomain) { - Set resourcesToEdit = new HashSet(resourceSet.getResources()); - Resource resourceToReplace = resourceSet.getResource(uriToReplace, false); - if(resourceToReplace != null) { - resourcesToEdit.remove(resourceToReplace); - } - return updateDependencies(uriToReplace, targetURI, resourcesToEdit, editingDomain); - } - - /** - * Replaces all references (dependencies) in the "fromResources" to the "uriToReplace" URI, with the "targetURI" - * - * Simplified pseudo code algorithm: fromResources.replaceAll(uriToReplace, targetURI) - * - * @param uriToReplace - * The URI of the resource which initially contains the referenced elements. May or may not exist. - * Must not be null - * @param targetURI - * The URI of the resource which contains the newly referenced elements. - * May or may not exist. In the later case, the values will be proxies to the un-existing target URI - * Must not be null - * @param fromResource - * The resource to edit. Only the objects of this resource will be modified. - * Must not be null - * @return - * The collection of replacements - */ - public static Collection updateDependencies(URI uriToReplace, URI targetURI, Collection fromResources) { - return updateDependencies(uriToReplace, targetURI, fromResources, null); - } - - /** - * Replaces all references (dependencies) in the "fromResource" to the "uriToReplace" URI, with the "targetURI" - * - * Simplified pseudo code algorithm: fromResource.replaceAll(uriToReplace, targetURI) - * - * @param uriToReplace - * The URI of the resource which initially contains the referenced elements. May or may not exist. - * Must not be null - * @param targetURI - * The URI of the resource which contains the newly referenced elements. - * May or may not exist. In the later case, the values will be proxies to the un-existing target URI - * Must not be null - * @param fromResource - * The resource to edit. Only the objects of this resource will be modified. - * Must not be null - * @return - * The collection of replacements - */ - public static Collection updateDependencies(URI uriToReplace, URI targetURI, Resource fromResource) { - return updateDependencies(uriToReplace, targetURI, fromResource, null); - } - - /** - * Replaces all references (dependencies) in the "resourceSet" to the "uriToReplace" URI, with the "targetURI" - * - * Simplified pseudo code algorithm: resourceSet.getResources().replaceAll(uriToReplace, targetURI) - * - * @param uriToReplace - * The URI of the resource which initially contains the referenced elements. May or may not exist. - * Must not be null - * @param targetURI - * The URI of the resource which contains the newly referenced elements. - * May or may not exist. In the later case, the values will be proxies to the un-existing target URI - * @param resourceSet - * The resourceSet to edit. Its resources will be modified. - * @return - * The collection of replacements - */ - public static Collection updateDependencies(URI uriToReplace, URI targetURI, ResourceSet resourceSet) { - Set resourcesToEdit = new HashSet(resourceSet.getResources()); - resourcesToEdit.remove(resourceSet.getResource(uriToReplace, false)); - return updateDependencies(uriToReplace, targetURI, resourcesToEdit, null); - } - - private static class ReplacementImpl implements Replacement { - - private EObject parent; - - private EStructuralFeature property; - - private EObject oldValue; - - private EObject newValue; - - public ReplacementImpl(EObject parent, EStructuralFeature property, EObject oldValue, EObject newValue) { - this.parent = parent; - this.property = property; - this.oldValue = oldValue; - this.newValue = newValue; - } - - public EObject getEObject() { - return parent; - } - - public EStructuralFeature getEStructuralFeature() { - return property; - } - - public EObject get(boolean resolve) { - if(resolve && newValue != null && newValue.eIsProxy()) { - newValue = EcoreUtil.resolve(newValue, parent); - } - - return newValue; - } - - public void set(Object newValue) { - throw new UnsupportedOperationException(); - } - - public boolean isSet() { - return newValue != null; - } - - public void unset() { - throw new UnsupportedOperationException(); - } - - public EObject getOldValue() { - return oldValue; - } - - @Override - public String toString() { - return String.format("%s replaced with %s", EcoreUtil.getURI(oldValue), EcoreUtil.getURI(newValue)); - } - } - -} +/***************************************************************************** + * Copyright (c) 2013 CEA LIST. + * + * 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 + *****************************************************************************/ +package org.eclipse.papyrus.infra.emf.resource; + +import java.util.Collection; +import java.util.HashMap; +import java.util.HashSet; +import java.util.Iterator; +import java.util.LinkedList; +import java.util.Map; +import java.util.Set; + +import org.eclipse.emf.common.util.URI; +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.DynamicEObjectImpl; +import org.eclipse.emf.ecore.resource.Resource; +import org.eclipse.emf.ecore.resource.ResourceSet; +import org.eclipse.emf.ecore.util.EcoreUtil; +import org.eclipse.emf.edit.domain.EditingDomain; +import org.eclipse.papyrus.infra.emf.Activator; +import org.eclipse.papyrus.infra.emf.utils.EMFHelper; + +/** + * A Helper to edit dependencies (URIs) between EMF Resources + * + * It replaces all references from a Resource A to a Resource B with references from A to B' + * + * B and B' must be "equivalent" (e.g. B is a copy of B' with or without modifications). + * + * @author Camille Letavernier + * + */ +public class DependencyManagementHelper { + + /** + * Replaces all references (dependencies) in the "fromResources" to the "uriToReplace" URI, with the "targetURI" + * + * Simplified pseudo code algorithm: fromResources.replaceAll(uriToReplace, targetURI) + * + * @param uriToReplace + * The URI of the resource which initially contains the referenced elements. May or may not exist. + * Must not be null + * @param targetURI + * The URI of the resource which contains the newly referenced elements. + * May or may not exist. In the later case, the values will be proxies to the un-existing target URI + * Must not be null + * @param fromResources + * The list of resources to edit. Only the objects of these resources will be modified. + * Must not be empty + * @param editingDomain + * The editing domain. May be null. + * + * @return + * The collection of replacements + */ + public static Collection updateDependencies(URI uriToReplace, URI targetURI, Collection fromResources, EditingDomain editingDomain) { + if(fromResources == null || fromResources.isEmpty()) { + throw new IllegalArgumentException("There is no resource to modify"); //$NON-NLS-1$ + } + + Collection replacements = new LinkedList(); + + for(Resource currentResource : fromResources) { + if(currentResource == null) { + continue; + } + + if(EMFHelper.isReadOnly(currentResource, editingDomain)) { + continue; + } + + replacements.addAll(updateDependencies(uriToReplace, targetURI, currentResource, editingDomain)); + } + + return replacements; + } + + /** + * Replaces all references (dependencies) in the "fromResources" to the "uriToReplace" URI, with the "targetURI" + * + * Simplified pseudo code algorithm: fromResources.replaceAll(uriToReplace, targetURI) + * + * @param uriToReplace + * The URI of the resource which initially contains the referenced elements. May or may not exist. + * Must not be null + * @param targetURI + * The URI of the resource which contains the newly referenced elements. + * May or may not exist. In the later case, the values will be proxies to the un-existing target URI + * Must not be null + * @param fromResource + * The resource to edit. Only the objects of this resource will be modified. + * Must not be null + * @param editingDomain + * The editing domain. May be null. + * @return + * The collection of replacements + */ + public static Collection updateDependencies(URI uriToReplace, URI targetURI, Resource fromResource, EditingDomain editingDomain) { + if(uriToReplace == null) { + throw new IllegalArgumentException("There is no URI to replace"); //$NON-NLS-1$ + } + + if(targetURI == null) { + throw new IllegalArgumentException("There is no target URI"); //$NON-NLS-1$ + } + + if(uriToReplace.equals(targetURI)) { + throw new IllegalArgumentException("The source and target URIs are identical"); //$NON-NLS-1$ + } + + if(fromResource == null) { + throw new IllegalArgumentException("The edited resource must not be null"); //$NON-NLS-1$ + } + + Iterator allContentsIterator = fromResource.getAllContents(); + + Collection replacements = new LinkedList(); + + while(allContentsIterator.hasNext()) { + EObject eObject = allContentsIterator.next(); + + for(EReference reference : eObject.eClass().getEAllReferences()) { + if(reference.isContainment()) { + continue; + } + + if(!reference.isChangeable()) { + continue; + } + + Object value = eObject.eGet(reference); + if(value instanceof EObject) { + EObject eObjectToReplace = (EObject)value; + + EObject newEObject = checkAndReplace(eObjectToReplace, uriToReplace, targetURI); + if(newEObject == null) { + continue; + } + + try { + //System.out.println("Replace " + EcoreUtil.getURI(eObjectToReplace) + " with " + EcoreUtil.getURI(newEObject)); + eObject.eSet(reference, newEObject); + replacements.add(new ReplacementImpl(eObject, reference, eObjectToReplace, newEObject)); + } catch (Exception ex) { + Activator.log.error(ex); + } + + } else if(value instanceof Collection) { + Map previousToNewValue = new HashMap(); + + Collection collection = (Collection)value; + + for(Object collectionElement : (Collection)value) { + if(collectionElement instanceof EObject) { + EObject eObjectToReplace = (EObject)collectionElement; + EObject newEObject = checkAndReplace(eObjectToReplace, uriToReplace, targetURI); + if(newEObject == null) { + continue; + } + + //System.out.println("Replace " + EcoreUtil.getURI(eObjectToReplace) + " with " + EcoreUtil.getURI(newEObject)); + previousToNewValue.put(eObjectToReplace, newEObject); + } + } + + if(previousToNewValue.isEmpty()) { + continue; + } + + if(collection instanceof EStructuralFeature.Setting) { + EStructuralFeature.Setting setting = (EStructuralFeature.Setting)collection; + for(Map.Entry entry : previousToNewValue.entrySet()) { + EcoreUtil.replace(setting, entry.getKey(), entry.getValue()); + replacements.add(new ReplacementImpl(eObject, reference, entry.getKey(), entry.getValue())); + } + } + } + } + } + + return replacements; + } + + /** + * Replaces the EObject (Which may be a proxy) by its equivalent in the given Resource's URI. + * Returns null if the "currentValueToReplace" doesn't belong to the resource represented by "uriToReplace". + * + * @param currentValueToReplace + * The current value, to be replaced. May be a proxy + * @param uriToReplace + * The URI of the resource to be replaced. + * @param targetURI + * The URI of the target resource (Which will contain the resulting EObject). + * The resource doesn't need to exist (and won't be created). If it doesn't exist, this method will return a Proxy + * @return + * The EObject equivalent to the replaced EObject, in the target resource. + */ + private static EObject checkAndReplace(EObject currentValueToReplace, URI uriToReplace, URI targetURI) { + URI eObjectURIToReplace = EcoreUtil.getURI(currentValueToReplace); + URI resourceURI = eObjectURIToReplace.trimFragment(); + + if(!uriToReplace.equals(resourceURI)) { + return null; + } + + return replace(currentValueToReplace, targetURI); + } + + /** + * Replaces the EObject (Which may be a proxy) by its equivalent in the given Resource's URI. + * + * @param currentValueToReplace + * The current value, to be replaced. May be a proxy + * @param targetURI + * The URI of the target resource (Which will contain the resulting EObject). + * The resource doesn't need to exist (and won't be created). If it doesn't exist, this method will return a Proxy + * @return + * The EObject equivalent to the replaced EObject, in the target resource. + */ + public static EObject replace(EObject currentValueToReplace, URI targetURI) { + URI eObjectURIToReplace = EcoreUtil.getURI(currentValueToReplace); + + EClass targetEClass = currentValueToReplace.eClass(); + + InternalEObject proxyEObject; + + //Try to instantiate the Proxy from the same EClass. + EObject newEObject = targetEClass.getEPackage().getEFactoryInstance().create(targetEClass); + if(newEObject instanceof InternalEObject) { + proxyEObject = (InternalEObject)newEObject; + } else { + //If the result is not an InternalEObject, create a basic EObject instead + proxyEObject = new DynamicEObjectImpl(targetEClass); + } + + String eObjectFragment = eObjectURIToReplace.fragment(); + URI eObjectURI = targetURI.appendFragment(eObjectFragment); + proxyEObject.eSetProxyURI(eObjectURI); + + return proxyEObject; + } + + /** + * Replaces all references (dependencies) in the "resourceSet" to the "uriToReplace" URI, with the "targetURI" + * + * Simplified pseudo code algorithm: resourceSet.getResources().replaceAll(uriToReplace, targetURI) + * + * @param uriToReplace + * The URI of the resource which initially contains the referenced elements. May or may not exist. + * Must not be null + * @param targetURI + * The URI of the resource which contains the newly referenced elements. + * May or may not exist. In the later case, the values will be proxies to the un-existing target URI + * Must not be null + * @param resourceSet + * The resourceSet to edit. Its resources will be modified. + * @param editingDomain + * The editing domain. May be null. + * @return + * The collection of replacements + */ + public static Collection updateDependencies(URI uriToReplace, URI targetURI, ResourceSet resourceSet, EditingDomain editingDomain) { + Set resourcesToEdit = new HashSet(resourceSet.getResources()); + Resource resourceToReplace = resourceSet.getResource(uriToReplace, false); + if(resourceToReplace != null) { + resourcesToEdit.remove(resourceToReplace); + } + return updateDependencies(uriToReplace, targetURI, resourcesToEdit, editingDomain); + } + + /** + * Replaces all references (dependencies) in the "fromResources" to the "uriToReplace" URI, with the "targetURI" + * + * Simplified pseudo code algorithm: fromResources.replaceAll(uriToReplace, targetURI) + * + * @param uriToReplace + * The URI of the resource which initially contains the referenced elements. May or may not exist. + * Must not be null + * @param targetURI + * The URI of the resource which contains the newly referenced elements. + * May or may not exist. In the later case, the values will be proxies to the un-existing target URI + * Must not be null + * @param fromResource + * The resource to edit. Only the objects of this resource will be modified. + * Must not be null + * @return + * The collection of replacements + */ + public static Collection updateDependencies(URI uriToReplace, URI targetURI, Collection fromResources) { + return updateDependencies(uriToReplace, targetURI, fromResources, null); + } + + /** + * Replaces all references (dependencies) in the "fromResource" to the "uriToReplace" URI, with the "targetURI" + * + * Simplified pseudo code algorithm: fromResource.replaceAll(uriToReplace, targetURI) + * + * @param uriToReplace + * The URI of the resource which initially contains the referenced elements. May or may not exist. + * Must not be null + * @param targetURI + * The URI of the resource which contains the newly referenced elements. + * May or may not exist. In the later case, the values will be proxies to the un-existing target URI + * Must not be null + * @param fromResource + * The resource to edit. Only the objects of this resource will be modified. + * Must not be null + * @return + * The collection of replacements + */ + public static Collection updateDependencies(URI uriToReplace, URI targetURI, Resource fromResource) { + return updateDependencies(uriToReplace, targetURI, fromResource, null); + } + + /** + * Replaces all references (dependencies) in the "resourceSet" to the "uriToReplace" URI, with the "targetURI" + * + * Simplified pseudo code algorithm: resourceSet.getResources().replaceAll(uriToReplace, targetURI) + * + * @param uriToReplace + * The URI of the resource which initially contains the referenced elements. May or may not exist. + * Must not be null + * @param targetURI + * The URI of the resource which contains the newly referenced elements. + * May or may not exist. In the later case, the values will be proxies to the un-existing target URI + * @param resourceSet + * The resourceSet to edit. Its resources will be modified. + * @return + * The collection of replacements + */ + public static Collection updateDependencies(URI uriToReplace, URI targetURI, ResourceSet resourceSet) { + Set resourcesToEdit = new HashSet(resourceSet.getResources()); + resourcesToEdit.remove(resourceSet.getResource(uriToReplace, false)); + return updateDependencies(uriToReplace, targetURI, resourcesToEdit, null); + } + + private static class ReplacementImpl implements Replacement { + + private EObject parent; + + private EStructuralFeature property; + + private EObject oldValue; + + private EObject newValue; + + public ReplacementImpl(EObject parent, EStructuralFeature property, EObject oldValue, EObject newValue) { + this.parent = parent; + this.property = property; + this.oldValue = oldValue; + this.newValue = newValue; + } + + public EObject getEObject() { + return parent; + } + + public EStructuralFeature getEStructuralFeature() { + return property; + } + + public EObject get(boolean resolve) { + if(resolve && newValue != null && newValue.eIsProxy()) { + newValue = EcoreUtil.resolve(newValue, parent); + } + + return newValue; + } + + public void set(Object newValue) { + throw new UnsupportedOperationException(); + } + + public boolean isSet() { + return newValue != null; + } + + public void unset() { + throw new UnsupportedOperationException(); + } + + public EObject getOldValue() { + return oldValue; + } + + @Override + public String toString() { + return String.format("%s replaced with %s", EcoreUtil.getURI(oldValue), EcoreUtil.getURI(newValue)); + } + } + +} diff --git a/plugins/infra/emf/org.eclipse.papyrus.infra.emf/src/org/eclipse/papyrus/infra/emf/utils/ServiceUtilsForEObject.java b/plugins/infra/emf/org.eclipse.papyrus.infra.emf/src/org/eclipse/papyrus/infra/emf/utils/ServiceUtilsForEObject.java index 32e3b45d222..3a6dba8b718 100644 --- a/plugins/infra/emf/org.eclipse.papyrus.infra.emf/src/org/eclipse/papyrus/infra/emf/utils/ServiceUtilsForEObject.java +++ b/plugins/infra/emf/org.eclipse.papyrus.infra.emf/src/org/eclipse/papyrus/infra/emf/utils/ServiceUtilsForEObject.java @@ -1,45 +1,45 @@ -/***************************************************************************** - * Copyright (c) 2012 CEA LIST. - * - * 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 - *****************************************************************************/ -package org.eclipse.papyrus.infra.emf.utils; - -import org.eclipse.emf.ecore.EObject; -import org.eclipse.papyrus.infra.core.services.ServiceException; -import org.eclipse.papyrus.infra.core.services.ServicesRegistry; -import org.eclipse.papyrus.infra.core.utils.AbstractServiceUtils; - -/** - * A ServiceUtils instance for manipulating Papyrus services on an EObject - * - * @author Camille Letavernier - * - */ -public class ServiceUtilsForEObject extends AbstractServiceUtils { - - private static ServiceUtilsForEObject instance = new ServiceUtilsForEObject(); - - public static ServiceUtilsForEObject getInstance() { - return instance; - } - - private ServiceUtilsForEObject() { - //Singleton - } - - @Override - public ServicesRegistry getServiceRegistry(EObject from) throws ServiceException { - if(from == null) { - throw new ServiceException("The selected EObject must not be null"); - } - - return ServiceUtilsForResource.getInstance().getServiceRegistry(from.eResource()); - } -} +/***************************************************************************** + * Copyright (c) 2012 CEA LIST. + * + * 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 + *****************************************************************************/ +package org.eclipse.papyrus.infra.emf.utils; + +import org.eclipse.emf.ecore.EObject; +import org.eclipse.papyrus.infra.core.services.ServiceException; +import org.eclipse.papyrus.infra.core.services.ServicesRegistry; +import org.eclipse.papyrus.infra.core.utils.AbstractServiceUtils; + +/** + * A ServiceUtils instance for manipulating Papyrus services on an EObject + * + * @author Camille Letavernier + * + */ +public class ServiceUtilsForEObject extends AbstractServiceUtils { + + private static ServiceUtilsForEObject instance = new ServiceUtilsForEObject(); + + public static ServiceUtilsForEObject getInstance() { + return instance; + } + + private ServiceUtilsForEObject() { + //Singleton + } + + @Override + public ServicesRegistry getServiceRegistry(EObject from) throws ServiceException { + if(from == null) { + throw new ServiceException("The selected EObject must not be null"); //$NON-NLS-1$ + } + + return ServiceUtilsForResource.getInstance().getServiceRegistry(from.eResource()); + } +} diff --git a/plugins/infra/emf/org.eclipse.papyrus.infra.emf/src/org/eclipse/papyrus/infra/emf/utils/ServiceUtilsForHandlers.java b/plugins/infra/emf/org.eclipse.papyrus.infra.emf/src/org/eclipse/papyrus/infra/emf/utils/ServiceUtilsForHandlers.java index cdf46c2d5be..158a3ca08b4 100644 --- a/plugins/infra/emf/org.eclipse.papyrus.infra.emf/src/org/eclipse/papyrus/infra/emf/utils/ServiceUtilsForHandlers.java +++ b/plugins/infra/emf/org.eclipse.papyrus.infra.emf/src/org/eclipse/papyrus/infra/emf/utils/ServiceUtilsForHandlers.java @@ -1,100 +1,100 @@ -/***************************************************************************** - * Copyright (c) 2012 CEA LIST. - * - * 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 - *****************************************************************************/ -package org.eclipse.papyrus.infra.emf.utils; - -import org.eclipse.core.commands.ExecutionEvent; -import org.eclipse.core.expressions.IEvaluationContext; -import org.eclipse.jface.viewers.ISelection; -import org.eclipse.papyrus.infra.core.services.ServiceException; -import org.eclipse.papyrus.infra.core.services.ServiceNotFoundException; -import org.eclipse.papyrus.infra.core.services.ServicesRegistry; -import org.eclipse.papyrus.infra.core.utils.AbstractServiceUtils; -import org.eclipse.ui.ISources; -import org.eclipse.ui.IWorkbenchPart; -import org.eclipse.ui.IWorkbenchPartSite; - -/** - * ServicesUtils based on the Handler's ExecutionEvent - * - * It first tests the current selection, then the IWorkbenchPart on which the handler is executed. - * The IWorkbenchPart is expected to be adaptable to a ServiceRegistry. - * - * @author Camille Letavernier - * - * @see ServiceUtilsForSelection - */ -public class ServiceUtilsForHandlers extends AbstractServiceUtils { - - private ServiceUtilsForHandlers() { - //Singleton - } - - @Override - public ServicesRegistry getServiceRegistry(ExecutionEvent from) throws ServiceException { - - Object context = from.getApplicationContext(); - - if(context instanceof IEvaluationContext) { - IEvaluationContext evaluationContext = (IEvaluationContext)context; - - //Search for the IWorkbenchPartSite from which the ExecutionEvent is sent (May be different that the Active one) - Object workbenchPartSite = evaluationContext.getVariable("org.eclipse.ui.IWorkbenchPartSite"); - if(workbenchPartSite instanceof IWorkbenchPartSite) { - IWorkbenchPartSite site = (IWorkbenchPartSite)workbenchPartSite; - Object registry = site.getAdapter(ServicesRegistry.class); - if(registry != null && registry instanceof ServicesRegistry) { - return (ServicesRegistry)registry; - } - - //Search for the IWorkbenchPart from which the ExecutionEvent is sent (May be different that the Active one) - IWorkbenchPart workbenchPart = site.getPart(); - registry = workbenchPart.getAdapter(ServicesRegistry.class); - if(registry != null && registry instanceof ServicesRegistry) { - return (ServicesRegistry)registry; - } - } - - Object selection = evaluationContext.getVariable(ISources.ACTIVE_CURRENT_SELECTION_NAME); - - ServicesRegistry registry; - - //Try to resolve the ServicesRegistry from the current selection - if(selection instanceof ISelection && !((ISelection)selection).isEmpty()) { - try { - registry = ServiceUtilsForSelection.getInstance().getServiceRegistry((ISelection)selection); - if(registry != null) { - return registry; - } - } catch (ServiceException ex) { - //Ignore and try another ServiceUtils - } - } - - //We couldn't retrieve the ServiceRegistry from the current selection. - - //Try to adapt the active part to the ServicesRegistry - IWorkbenchPart part = (IWorkbenchPart)evaluationContext.getVariable(ISources.ACTIVE_PART_NAME); - registry = (ServicesRegistry)(part).getAdapter(ServicesRegistry.class); - if(registry != null) { - return registry; - } - } - - throw new ServiceNotFoundException("The ServiceRegistry cannot be resolved"); - } - - public static ServiceUtilsForHandlers getInstance() { - return instance; - } - - private static final ServiceUtilsForHandlers instance = new ServiceUtilsForHandlers(); -} +/***************************************************************************** + * Copyright (c) 2012 CEA LIST. + * + * 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 + *****************************************************************************/ +package org.eclipse.papyrus.infra.emf.utils; + +import org.eclipse.core.commands.ExecutionEvent; +import org.eclipse.core.expressions.IEvaluationContext; +import org.eclipse.jface.viewers.ISelection; +import org.eclipse.papyrus.infra.core.services.ServiceException; +import org.eclipse.papyrus.infra.core.services.ServiceNotFoundException; +import org.eclipse.papyrus.infra.core.services.ServicesRegistry; +import org.eclipse.papyrus.infra.core.utils.AbstractServiceUtils; +import org.eclipse.ui.ISources; +import org.eclipse.ui.IWorkbenchPart; +import org.eclipse.ui.IWorkbenchPartSite; + +/** + * ServicesUtils based on the Handler's ExecutionEvent + * + * It first tests the current selection, then the IWorkbenchPart on which the handler is executed. + * The IWorkbenchPart is expected to be adaptable to a ServiceRegistry. + * + * @author Camille Letavernier + * + * @see ServiceUtilsForSelection + */ +public class ServiceUtilsForHandlers extends AbstractServiceUtils { + + private ServiceUtilsForHandlers() { + //Singleton + } + + @Override + public ServicesRegistry getServiceRegistry(ExecutionEvent from) throws ServiceException { + + Object context = from.getApplicationContext(); + + if(context instanceof IEvaluationContext) { + IEvaluationContext evaluationContext = (IEvaluationContext)context; + + //Search for the IWorkbenchPartSite from which the ExecutionEvent is sent (May be different that the Active one) + Object workbenchPartSite = evaluationContext.getVariable("org.eclipse.ui.IWorkbenchPartSite"); + if(workbenchPartSite instanceof IWorkbenchPartSite) { + IWorkbenchPartSite site = (IWorkbenchPartSite)workbenchPartSite; + Object registry = site.getAdapter(ServicesRegistry.class); + if(registry != null && registry instanceof ServicesRegistry) { + return (ServicesRegistry)registry; + } + + //Search for the IWorkbenchPart from which the ExecutionEvent is sent (May be different that the Active one) + IWorkbenchPart workbenchPart = site.getPart(); + registry = workbenchPart.getAdapter(ServicesRegistry.class); + if(registry != null && registry instanceof ServicesRegistry) { + return (ServicesRegistry)registry; + } + } + + Object selection = evaluationContext.getVariable(ISources.ACTIVE_CURRENT_SELECTION_NAME); + + ServicesRegistry registry; + + //Try to resolve the ServicesRegistry from the current selection + if(selection instanceof ISelection && !((ISelection)selection).isEmpty()) { + try { + registry = ServiceUtilsForSelection.getInstance().getServiceRegistry((ISelection)selection); + if(registry != null) { + return registry; + } + } catch (ServiceException ex) { + //Ignore and try another ServiceUtils + } + } + + //We couldn't retrieve the ServiceRegistry from the current selection. + + //Try to adapt the active part to the ServicesRegistry + IWorkbenchPart part = (IWorkbenchPart)evaluationContext.getVariable(ISources.ACTIVE_PART_NAME); + registry = (ServicesRegistry)(part).getAdapter(ServicesRegistry.class); + if(registry != null) { + return registry; + } + } + + throw new ServiceNotFoundException("The ServiceRegistry cannot be resolved"); //$NON-NLS-1$ + } + + public static ServiceUtilsForHandlers getInstance() { + return instance; + } + + private static final ServiceUtilsForHandlers instance = new ServiceUtilsForHandlers(); +} diff --git a/plugins/infra/emf/org.eclipse.papyrus.infra.emf/src/org/eclipse/papyrus/infra/emf/utils/ServiceUtilsForIEvaluationContext.java b/plugins/infra/emf/org.eclipse.papyrus.infra.emf/src/org/eclipse/papyrus/infra/emf/utils/ServiceUtilsForIEvaluationContext.java index 183fd824911..769bed77a13 100644 --- a/plugins/infra/emf/org.eclipse.papyrus.infra.emf/src/org/eclipse/papyrus/infra/emf/utils/ServiceUtilsForIEvaluationContext.java +++ b/plugins/infra/emf/org.eclipse.papyrus.infra.emf/src/org/eclipse/papyrus/infra/emf/utils/ServiceUtilsForIEvaluationContext.java @@ -1,107 +1,107 @@ -/***************************************************************************** - * Copyright (c) 2012 Cedric Dumoulin. - * - * 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: - * Cedric Dumoulin - Initial API and implementation - *****************************************************************************/ -package org.eclipse.papyrus.infra.emf.utils; - -import org.eclipse.core.commands.AbstractHandler; -import org.eclipse.core.expressions.IEvaluationContext; -import org.eclipse.jface.viewers.ISelection; -import org.eclipse.papyrus.infra.core.services.ServiceException; -import org.eclipse.papyrus.infra.core.services.ServiceNotFoundException; -import org.eclipse.papyrus.infra.core.services.ServicesRegistry; -import org.eclipse.papyrus.infra.core.utils.AbstractServiceUtils; -import org.eclipse.ui.ISources; -import org.eclipse.ui.IWorkbenchPart; -import org.eclipse.ui.IWorkbenchPartSite; - -/** - * ServicesUtils based on the Handler's IEvaluationContext. - * This class can be used for both the {@link AbstractHandler#execute(org.eclipse.core.commands.ExecutionEvent)} and the {@link AbstractHandler#setEnabled(Object)} methods. - * - * - * @author Cedric Dumoulin - * - */ -public class ServiceUtilsForIEvaluationContext extends AbstractServiceUtils { - - private ServiceUtilsForIEvaluationContext() { - //Singleton - } - - /** - * - * @see org.eclipse.papyrus.infra.core.utils.AbstractServiceUtils#getServiceRegistry(java.lang.Object) - * - * @param from - * @return - * @throws ServiceException - */ - @Override - public ServicesRegistry getServiceRegistry(IEvaluationContext from) throws ServiceException { - - IEvaluationContext evaluationContext = from; - - //Search for the IWorkbenchPartSite from which the ExecutionEvent is sent (May be different that the Active one) - Object workbenchPartSite = evaluationContext.getVariable("org.eclipse.ui.IWorkbenchPartSite"); - if(workbenchPartSite instanceof IWorkbenchPartSite) { - IWorkbenchPartSite site = (IWorkbenchPartSite)workbenchPartSite; - Object registry = site.getAdapter(ServicesRegistry.class); - if(registry != null && registry instanceof ServicesRegistry) { - return (ServicesRegistry)registry; - } - - //Search for the IWorkbenchPart from which the ExecutionEvent is sent (May be different that the Active one) - IWorkbenchPart workbenchPart = site.getPart(); - registry = workbenchPart.getAdapter(ServicesRegistry.class); - if(registry != null && registry instanceof ServicesRegistry) { - return (ServicesRegistry)registry; - } - } - - Object selection = evaluationContext.getVariable(ISources.ACTIVE_CURRENT_SELECTION_NAME); - - ServicesRegistry registry; - - //Try to resolve the ServicesRegistry from the current selection - if(selection instanceof ISelection && !((ISelection)selection).isEmpty()) { - try { - registry = ServiceUtilsForSelection.getInstance().getServiceRegistry((ISelection)selection); - if(registry != null) { - return registry; - } - } catch (ServiceException ex) { - //Ignore and try another ServiceUtils - } - } - - //We couldn't retrieve the ServiceRegistry from the current selection. - - //Try to adapt the active part to the ServicesRegistry - Object _part = evaluationContext.getVariable(ISources.ACTIVE_PART_NAME); - if (_part instanceof IWorkbenchPart) { - IWorkbenchPart part = (IWorkbenchPart)_part; - registry = (ServicesRegistry)(part).getAdapter(ServicesRegistry.class); - if(registry != null) { - return registry; - } - } - - - // nothing found - throw new ServiceNotFoundException("The ServiceRegistry cannot be resolved"); - } - - public static ServiceUtilsForIEvaluationContext getInstance() { - return instance; - } - - private static final ServiceUtilsForIEvaluationContext instance = new ServiceUtilsForIEvaluationContext(); -} +/***************************************************************************** + * Copyright (c) 2012 Cedric Dumoulin. + * + * 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: + * Cedric Dumoulin - Initial API and implementation + *****************************************************************************/ +package org.eclipse.papyrus.infra.emf.utils; + +import org.eclipse.core.commands.AbstractHandler; +import org.eclipse.core.expressions.IEvaluationContext; +import org.eclipse.jface.viewers.ISelection; +import org.eclipse.papyrus.infra.core.services.ServiceException; +import org.eclipse.papyrus.infra.core.services.ServiceNotFoundException; +import org.eclipse.papyrus.infra.core.services.ServicesRegistry; +import org.eclipse.papyrus.infra.core.utils.AbstractServiceUtils; +import org.eclipse.ui.ISources; +import org.eclipse.ui.IWorkbenchPart; +import org.eclipse.ui.IWorkbenchPartSite; + +/** + * ServicesUtils based on the Handler's IEvaluationContext. + * This class can be used for both the {@link AbstractHandler#execute(org.eclipse.core.commands.ExecutionEvent)} and the {@link AbstractHandler#setEnabled(Object)} methods. + * + * + * @author Cedric Dumoulin + * + */ +public class ServiceUtilsForIEvaluationContext extends AbstractServiceUtils { + + private ServiceUtilsForIEvaluationContext() { + //Singleton + } + + /** + * + * @see org.eclipse.papyrus.infra.core.utils.AbstractServiceUtils#getServiceRegistry(java.lang.Object) + * + * @param from + * @return + * @throws ServiceException + */ + @Override + public ServicesRegistry getServiceRegistry(IEvaluationContext from) throws ServiceException { + + IEvaluationContext evaluationContext = from; + + //Search for the IWorkbenchPartSite from which the ExecutionEvent is sent (May be different that the Active one) + Object workbenchPartSite = evaluationContext.getVariable("org.eclipse.ui.IWorkbenchPartSite"); + if(workbenchPartSite instanceof IWorkbenchPartSite) { + IWorkbenchPartSite site = (IWorkbenchPartSite)workbenchPartSite; + Object registry = site.getAdapter(ServicesRegistry.class); + if(registry != null && registry instanceof ServicesRegistry) { + return (ServicesRegistry)registry; + } + + //Search for the IWorkbenchPart from which the ExecutionEvent is sent (May be different that the Active one) + IWorkbenchPart workbenchPart = site.getPart(); + registry = workbenchPart.getAdapter(ServicesRegistry.class); + if(registry != null && registry instanceof ServicesRegistry) { + return (ServicesRegistry)registry; + } + } + + Object selection = evaluationContext.getVariable(ISources.ACTIVE_CURRENT_SELECTION_NAME); + + ServicesRegistry registry; + + //Try to resolve the ServicesRegistry from the current selection + if(selection instanceof ISelection && !((ISelection)selection).isEmpty()) { + try { + registry = ServiceUtilsForSelection.getInstance().getServiceRegistry((ISelection)selection); + if(registry != null) { + return registry; + } + } catch (ServiceException ex) { + //Ignore and try another ServiceUtils + } + } + + //We couldn't retrieve the ServiceRegistry from the current selection. + + //Try to adapt the active part to the ServicesRegistry + Object _part = evaluationContext.getVariable(ISources.ACTIVE_PART_NAME); + if (_part instanceof IWorkbenchPart) { + IWorkbenchPart part = (IWorkbenchPart)_part; + registry = (ServicesRegistry)(part).getAdapter(ServicesRegistry.class); + if(registry != null) { + return registry; + } + } + + + // nothing found + throw new ServiceNotFoundException("The ServiceRegistry cannot be resolved"); //$NON-NLS-1$ + } + + public static ServiceUtilsForIEvaluationContext getInstance() { + return instance; + } + + private static final ServiceUtilsForIEvaluationContext instance = new ServiceUtilsForIEvaluationContext(); +} diff --git a/plugins/infra/emf/org.eclipse.papyrus.infra.emf/src/org/eclipse/papyrus/infra/emf/utils/ServiceUtilsForResource.java b/plugins/infra/emf/org.eclipse.papyrus.infra.emf/src/org/eclipse/papyrus/infra/emf/utils/ServiceUtilsForResource.java index 58d75bc2004..b064299981c 100644 --- a/plugins/infra/emf/org.eclipse.papyrus.infra.emf/src/org/eclipse/papyrus/infra/emf/utils/ServiceUtilsForResource.java +++ b/plugins/infra/emf/org.eclipse.papyrus.infra.emf/src/org/eclipse/papyrus/infra/emf/utils/ServiceUtilsForResource.java @@ -1,70 +1,70 @@ -/***************************************************************************** - * Copyright (c) 2012, 2014 Cedric Dumoulin, CEA, 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: - * Cedric Dumoulin Cedric.dumoulin@lifl.fr - Initial API and implementation - * Christian W. Damus (CEA) - bug 431953 (fix start-up of selective services to require only their dependencies) - * - *****************************************************************************/ - -package org.eclipse.papyrus.infra.emf.utils; - -import org.eclipse.emf.ecore.resource.Resource; -import org.eclipse.papyrus.infra.core.editor.ModelSetServiceFactory; -import org.eclipse.papyrus.infra.core.services.ServiceException; -import org.eclipse.papyrus.infra.core.services.ServiceNotFoundException; -import org.eclipse.papyrus.infra.core.services.ServicesRegistry; -import org.eclipse.papyrus.infra.core.utils.AbstractServiceUtils; - -/** - * Get the {@link ServicesRegistry} from a {@link EObject} or a {@link Resource}. - * This class allow to retrieve the {@code ServicesRegistry} associated to the {@link ResourceSet} owning the {@code Resource} - * containing the {@code EObject}. - *

- * To work properly, the EObject should be associated to a {@link Resource}, itself registered in a {@link ResourceSet}. - * Also, the {@code ServicesRegistry} should be associated to the {@code ResourceSet}. - * Normally, this is automatically done thanks to the {@link ModelSetServiceFactory} service. - * If you access this class from a service, you can ensure that the latter service is started by letting your service - * depend on the org.eclipse.papyrus.infra.core.editor.ModelSetServiceFactory. - *

- * - * @author cedric dumoulin - * - */ -public class ServiceUtilsForResource extends AbstractServiceUtils { - - private final static ServiceUtilsForResource instance = new ServiceUtilsForResource(); - - /** - * Get the singleton instance of the class. - * - * @return - */ - public static final ServiceUtilsForResource getInstance() { - return instance; - } - - /** - * Get the {@link ServicesRegistry} from a {@link Resource}. - * - * @param from - * The {@link Resource} from which we want the associated {@link ServicesRegistry}. - * @return - * @throws ServiceException - * If there is no {@link ServicesRegistry} associated to the {@link ResourceSet} owning the {@link Resource}. - */ - @Override - public ServicesRegistry getServiceRegistry(Resource from) throws ServiceException { - if(from == null) { - throw new ServiceNotFoundException("Can't find the ResourceSet needed retrieve the ServiceRegistry."); - } - return ServiceUtilsForResourceSet.getInstance().getServiceRegistry(from.getResourceSet()); - } - -} +/***************************************************************************** + * Copyright (c) 2012, 2014 Cedric Dumoulin, CEA, 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: + * Cedric Dumoulin Cedric.dumoulin@lifl.fr - Initial API and implementation + * Christian W. Damus (CEA) - bug 431953 (fix start-up of selective services to require only their dependencies) + * + *****************************************************************************/ + +package org.eclipse.papyrus.infra.emf.utils; + +import org.eclipse.emf.ecore.resource.Resource; +import org.eclipse.papyrus.infra.core.editor.ModelSetServiceFactory; +import org.eclipse.papyrus.infra.core.services.ServiceException; +import org.eclipse.papyrus.infra.core.services.ServiceNotFoundException; +import org.eclipse.papyrus.infra.core.services.ServicesRegistry; +import org.eclipse.papyrus.infra.core.utils.AbstractServiceUtils; + +/** + * Get the {@link ServicesRegistry} from a {@link EObject} or a {@link Resource}. + * This class allow to retrieve the {@code ServicesRegistry} associated to the {@link ResourceSet} owning the {@code Resource} + * containing the {@code EObject}. + *

+ * To work properly, the EObject should be associated to a {@link Resource}, itself registered in a {@link ResourceSet}. + * Also, the {@code ServicesRegistry} should be associated to the {@code ResourceSet}. + * Normally, this is automatically done thanks to the {@link ModelSetServiceFactory} service. + * If you access this class from a service, you can ensure that the latter service is started by letting your service + * depend on the org.eclipse.papyrus.infra.core.editor.ModelSetServiceFactory. + *

+ * + * @author cedric dumoulin + * + */ +public class ServiceUtilsForResource extends AbstractServiceUtils { + + private final static ServiceUtilsForResource instance = new ServiceUtilsForResource(); + + /** + * Get the singleton instance of the class. + * + * @return + */ + public static final ServiceUtilsForResource getInstance() { + return instance; + } + + /** + * Get the {@link ServicesRegistry} from a {@link Resource}. + * + * @param from + * The {@link Resource} from which we want the associated {@link ServicesRegistry}. + * @return + * @throws ServiceException + * If there is no {@link ServicesRegistry} associated to the {@link ResourceSet} owning the {@link Resource}. + */ + @Override + public ServicesRegistry getServiceRegistry(Resource from) throws ServiceException { + if(from == null) { + throw new ServiceNotFoundException("Can't find the ResourceSet needed retrieve the ServiceRegistry."); //$NON-NLS-1$ + } + return ServiceUtilsForResourceSet.getInstance().getServiceRegistry(from.getResourceSet()); + } + +} diff --git a/plugins/infra/emf/org.eclipse.papyrus.infra.emf/src/org/eclipse/papyrus/infra/emf/utils/ServiceUtilsForResourceSet.java b/plugins/infra/emf/org.eclipse.papyrus.infra.emf/src/org/eclipse/papyrus/infra/emf/utils/ServiceUtilsForResourceSet.java index 41b79e23822..ba444e61ddc 100644 --- a/plugins/infra/emf/org.eclipse.papyrus.infra.emf/src/org/eclipse/papyrus/infra/emf/utils/ServiceUtilsForResourceSet.java +++ b/plugins/infra/emf/org.eclipse.papyrus.infra.emf/src/org/eclipse/papyrus/infra/emf/utils/ServiceUtilsForResourceSet.java @@ -1,49 +1,49 @@ -/***************************************************************************** - * Copyright (c) 2013, 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 - * Christian W. Damus (CEA) - bug 431953 (pre-requisite refactoring of ModelSet service start-up) - * - *****************************************************************************/ -package org.eclipse.papyrus.infra.emf.utils; - -import org.eclipse.emf.ecore.resource.ResourceSet; -import org.eclipse.papyrus.infra.core.editor.ModelSetServiceFactory; -import org.eclipse.papyrus.infra.core.services.ServiceException; -import org.eclipse.papyrus.infra.core.services.ServiceNotFoundException; -import org.eclipse.papyrus.infra.core.services.ServicesRegistry; -import org.eclipse.papyrus.infra.core.utils.AbstractServiceUtils; - - -public class ServiceUtilsForResourceSet extends AbstractServiceUtils { - - private ServiceUtilsForResourceSet() { - //Singleton - } - - private static ServiceUtilsForResourceSet instance = new ServiceUtilsForResourceSet(); - - public static ServiceUtilsForResourceSet getInstance() { - return instance; - } - - @Override - public ServicesRegistry getServiceRegistry(ResourceSet from) throws ServiceException { - if(from == null) { - throw new ServiceNotFoundException("Can't find the ResourceSet needed retrieve the ServiceRegistry."); - } - - ServicesRegistry result = ModelSetServiceFactory.getServiceRegistry(from); - if(result == null) { - throw new ServiceNotFoundException("The resource set was not initialized as a service."); - } - return result; - } - -} +/***************************************************************************** + * Copyright (c) 2013, 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 + * Christian W. Damus (CEA) - bug 431953 (pre-requisite refactoring of ModelSet service start-up) + * + *****************************************************************************/ +package org.eclipse.papyrus.infra.emf.utils; + +import org.eclipse.emf.ecore.resource.ResourceSet; +import org.eclipse.papyrus.infra.core.editor.ModelSetServiceFactory; +import org.eclipse.papyrus.infra.core.services.ServiceException; +import org.eclipse.papyrus.infra.core.services.ServiceNotFoundException; +import org.eclipse.papyrus.infra.core.services.ServicesRegistry; +import org.eclipse.papyrus.infra.core.utils.AbstractServiceUtils; + + +public class ServiceUtilsForResourceSet extends AbstractServiceUtils { + + private ServiceUtilsForResourceSet() { + //Singleton + } + + private static ServiceUtilsForResourceSet instance = new ServiceUtilsForResourceSet(); + + public static ServiceUtilsForResourceSet getInstance() { + return instance; + } + + @Override + public ServicesRegistry getServiceRegistry(ResourceSet from) throws ServiceException { + if(from == null) { + throw new ServiceNotFoundException("Can't find the ResourceSet needed retrieve the ServiceRegistry."); //$NON-NLS-1$ + } + + ServicesRegistry result = ModelSetServiceFactory.getServiceRegistry(from); + if(result == null) { + throw new ServiceNotFoundException("The resource set was not initialized as a service."); //$NON-NLS-1$ + } + return result; + } + +} diff --git a/plugins/infra/emf/org.eclipse.papyrus.infra.emf/src/org/eclipse/papyrus/infra/emf/utils/ServiceUtilsForSelection.java b/plugins/infra/emf/org.eclipse.papyrus.infra.emf/src/org/eclipse/papyrus/infra/emf/utils/ServiceUtilsForSelection.java index 729668d4160..04de7290287 100644 --- a/plugins/infra/emf/org.eclipse.papyrus.infra.emf/src/org/eclipse/papyrus/infra/emf/utils/ServiceUtilsForSelection.java +++ b/plugins/infra/emf/org.eclipse.papyrus.infra.emf/src/org/eclipse/papyrus/infra/emf/utils/ServiceUtilsForSelection.java @@ -1,59 +1,59 @@ -/***************************************************************************** - * Copyright (c) 2012 CEA LIST. - * - * 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 - *****************************************************************************/ -package org.eclipse.papyrus.infra.emf.utils; - -import java.util.Iterator; - -import org.eclipse.emf.ecore.EObject; -import org.eclipse.jface.viewers.ISelection; -import org.eclipse.jface.viewers.IStructuredSelection; -import org.eclipse.papyrus.infra.core.services.ServiceException; -import org.eclipse.papyrus.infra.core.services.ServicesRegistry; -import org.eclipse.papyrus.infra.core.utils.AbstractServiceUtils; - -/** - * ServiceUtils based on an ISelection. - * - * Expects an IStructuredSelection containing at least one EObject (It then relies on ServiceUtilsForEObject to retrieve the ServicesRegistry) - * - * @author Camille Letavernier - */ -public class ServiceUtilsForSelection extends AbstractServiceUtils { - - private ServiceUtilsForSelection() { - //Singleton - } - - private static ServiceUtilsForSelection instance = new ServiceUtilsForSelection(); - - public static ServiceUtilsForSelection getInstance() { - return instance; - } - - @Override - public ServicesRegistry getServiceRegistry(ISelection from) throws ServiceException { - if(from instanceof IStructuredSelection) { - IStructuredSelection selection = (IStructuredSelection)from; - Iterator selectionIterator = selection.iterator(); - while(selectionIterator.hasNext()) { - Object selectedElement = selectionIterator.next(); - EObject selectedEObject = EMFHelper.getEObject(selectedElement); - if(selectedEObject != null) { - return ServiceUtilsForEObject.getInstance().getServiceRegistry(selectedEObject); - } - } - } - - throw new ServiceException("Cannot retrieve the ServiceRegistry"); - } - -} +/***************************************************************************** + * Copyright (c) 2012 CEA LIST. + * + * 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 + *****************************************************************************/ +package org.eclipse.papyrus.infra.emf.utils; + +import java.util.Iterator; + +import org.eclipse.emf.ecore.EObject; +import org.eclipse.jface.viewers.ISelection; +import org.eclipse.jface.viewers.IStructuredSelection; +import org.eclipse.papyrus.infra.core.services.ServiceException; +import org.eclipse.papyrus.infra.core.services.ServicesRegistry; +import org.eclipse.papyrus.infra.core.utils.AbstractServiceUtils; + +/** + * ServiceUtils based on an ISelection. + * + * Expects an IStructuredSelection containing at least one EObject (It then relies on ServiceUtilsForEObject to retrieve the ServicesRegistry) + * + * @author Camille Letavernier + */ +public class ServiceUtilsForSelection extends AbstractServiceUtils { + + private ServiceUtilsForSelection() { + //Singleton + } + + private static ServiceUtilsForSelection instance = new ServiceUtilsForSelection(); + + public static ServiceUtilsForSelection getInstance() { + return instance; + } + + @Override + public ServicesRegistry getServiceRegistry(ISelection from) throws ServiceException { + if(from instanceof IStructuredSelection) { + IStructuredSelection selection = (IStructuredSelection)from; + Iterator selectionIterator = selection.iterator(); + while(selectionIterator.hasNext()) { + Object selectedElement = selectionIterator.next(); + EObject selectedEObject = EMFHelper.getEObject(selectedElement); + if(selectedEObject != null) { + return ServiceUtilsForEObject.getInstance().getServiceRegistry(selectedEObject); + } + } + } + + throw new ServiceException("Cannot retrieve the ServiceRegistry"); //$NON-NLS-1$ + } + +} diff --git a/plugins/infra/emf/org.eclipse.papyrus.infra.emf/src/org/eclipse/papyrus/infra/emf/utils/TextReferencesHelper.java b/plugins/infra/emf/org.eclipse.papyrus.infra.emf/src/org/eclipse/papyrus/infra/emf/utils/TextReferencesHelper.java index e3ac8d92d7e..ece95494ed2 100644 --- a/plugins/infra/emf/org.eclipse.papyrus.infra.emf/src/org/eclipse/papyrus/infra/emf/utils/TextReferencesHelper.java +++ b/plugins/infra/emf/org.eclipse.papyrus.infra.emf/src/org/eclipse/papyrus/infra/emf/utils/TextReferencesHelper.java @@ -1,218 +1,218 @@ -/***************************************************************************** - * Copyright (c) 2013 CEA LIST. - * - * - * 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 (camille.letavernier@cea.fr) - Initial API and implementation - * - *****************************************************************************/ -package org.eclipse.papyrus.infra.emf.utils; - -import java.util.regex.Matcher; -import java.util.regex.Pattern; - -import org.eclipse.emf.common.util.URI; -import org.eclipse.emf.ecore.EObject; -import org.eclipse.emf.ecore.resource.Resource; -import org.eclipse.emf.ecore.resource.ResourceSet; -import org.eclipse.emf.ecore.util.EcoreUtil; -import org.eclipse.papyrus.infra.emf.Activator; - -/** - * An abstract helper to replace references to EObjects (represented by their URI) with a label (related to this EObject). - * - * It is typically used to introduce dynamic references to object's labels in free text areas (e.g. in a description) - * - * The reference can be introduced with {@link #insertReference(EObject, String, int)} - * - * The parsed string can be retrieved with {@link #replaceReferences(String)} - * - * @author Camille Letavernier - * - */ -public abstract class TextReferencesHelper { - - public static final String URI_CHARS = "[^#]"; //Almost everything is allowed in a URI. It's simpler to exclude the fragment separator - - public static final String FRAGMENT_CHARS = "[-A-Za-z0-9_/]"; //In Papyrus this is sufficient. Do we need a more complex expression? - - public static final String URI_REGEX = String.format("%s*#%s+", URI_CHARS, FRAGMENT_CHARS); //The base uri is optional. The fragment is required. - - public static String UNKNOWN_ELEMENT = "UNKNOWN"; //Replacement text for unknown elements - - public static String PROXY_ELEMENT = "PROXY"; //Replacement text for proxy elements - - protected Resource baseResource; - - protected ResourceSet resourceSet; - - protected TextReferencesHelper() { - //Empty - } - - /** - * - * @param baseResource - * The resource against which the link uris will be resolved - */ - protected TextReferencesHelper(Resource baseResource) { - - if(baseResource != null) { - this.baseResource = baseResource; - this.resourceSet = baseResource.getResourceSet(); - } - } - - /** - * Parses the specified text, and replace all references with their replacement String - * - * @param text - * @return - * - * @see {@link #getReplacement(EObject, String)} - */ - public String replaceReferences(String text) { - if(text == null) { - return null; - } - - if("".equals(text)) { - return text; - } - - //Javadoc-like @link tag - String replaceRegex = String.format("\\{@link (%s)(\\|([^}]*))?\\}", URI_REGEX); - - Pattern pattern = Pattern.compile(replaceRegex); - Matcher matcher = pattern.matcher(text); - - String newText = text; - - while(matcher.find()) { - String uriToReplace = matcher.group(1); //0 is the full pattern (e.g. {link myUri#myFragment}, 1 is the first group (e.g. myUri#myFragment) - String cachedValue = matcher.group(3); //group 2 is |CachedValue, group 3 is CachedValue - - String replacement = decorate(getReplacement(uriToReplace, cachedValue)); - - newText = matcher.replaceFirst(replacement); - matcher = pattern.matcher(newText); - } - - return newText; - } - - /** - * Insert a reference to the given element in the specified text, at the specified position - * - * @param toElement - * The element to reference - * @param inText - * The text in which the reference must be inserted - * @param atPosition - * The position at which the reference must be inserted. 0 is the beginning, while text.length() is the end. For all "invalid" indexes (<0 - * and > length()), the reference will be inserted at the end of the string - * @return - * The text containing the new reference - */ - public String insertReference(EObject toElement, String inText, int atPosition) { - String result = inText; - if(inText == null) { - return null; //No change - } - - if(toElement == null) { - return inText; //No change - } - - //Use a Javadoc-like @link tag - URI elementURI = EcoreUtil.getURI(toElement); - if(baseResource != null) { - URI baseURI = baseResource.getURI(); - if(baseURI != null) { - elementURI = elementURI.deresolve(baseURI); - } - } - String reference = "{@link " + elementURI + "}"; //The URI is already encoded - - if(atPosition == 0) { - return reference + result; //At the beginning - } - - if(atPosition < 0 || atPosition >= inText.length()) { - result += reference; //Insert at the end - } else { - //Hello, world - //The whitespace is the character at position 6. Insert the reference at position 7 to add it after the whitespace - //It will result in Hello, world - result = inText.substring(0, atPosition); //Include the "afterPosition" character - result += reference; //Add the reference - result += inText.substring(atPosition, inText.length()); //Complete the string (Exclude the afterPosition character, as it has already been copied in the first part of the result string) - } - - return result; - } - - /** - * Adds a (text) decoration to the replacement string. - * This can be used for e.g. html-based texts, to add tags around the replaced string - * - * The default implementation does nothing. - */ - protected String decorate(String text) { - return text; - } - - protected String getReplacement(String uriToReplace, String cachedValue) { - String uri, fragment; - - if(baseResource == null || resourceSet == null || baseResource.getURI() == null) { - return UNKNOWN_ELEMENT; - } - - if(uriToReplace.contains("#")) { - uri = uriToReplace.substring(0, uriToReplace.indexOf('#')); - fragment = uriToReplace.substring(uriToReplace.indexOf('#') + 1, uriToReplace.length()); - } else { - return UNKNOWN_ELEMENT; - } - - URI targetURI; - - URI resourceURI; - - resourceURI = baseResource.getURI(); - - targetURI = URI.createURI(uri); //The URI must already be encoded - - targetURI = targetURI.resolve(resourceURI); - - if(targetURI == null) { - return UNKNOWN_ELEMENT; - } - - targetURI = targetURI.appendFragment(fragment); - - return getReplacement(targetURI, cachedValue); - } - - protected String getReplacement(URI uriToReplace, String cachedValue) { - try { - EObject targetElement = resourceSet.getEObject(uriToReplace, true); - return getReplacement(targetElement, cachedValue); - } catch (Exception ex) { - //Log the error? If it happens once, it will happen many times (after each refresh). The UNKNOWN keyword may be enough. - //This error happens when the reference is broken (e.g. an element has been deleted). This is a "normal" behavior - Activator.log.debug("An error occurred while loading the following URI: " + uriToReplace + ". The reference cannot be replaced"); - } - - return UNKNOWN_ELEMENT; - } - - protected abstract String getReplacement(EObject elementToReplace, String cachedValue); - -} +/***************************************************************************** + * Copyright (c) 2013 CEA LIST. + * + * + * 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 (camille.letavernier@cea.fr) - Initial API and implementation + * + *****************************************************************************/ +package org.eclipse.papyrus.infra.emf.utils; + +import java.util.regex.Matcher; +import java.util.regex.Pattern; + +import org.eclipse.emf.common.util.URI; +import org.eclipse.emf.ecore.EObject; +import org.eclipse.emf.ecore.resource.Resource; +import org.eclipse.emf.ecore.resource.ResourceSet; +import org.eclipse.emf.ecore.util.EcoreUtil; +import org.eclipse.papyrus.infra.emf.Activator; + +/** + * An abstract helper to replace references to EObjects (represented by their URI) with a label (related to this EObject). + * + * It is typically used to introduce dynamic references to object's labels in free text areas (e.g. in a description) + * + * The reference can be introduced with {@link #insertReference(EObject, String, int)} + * + * The parsed string can be retrieved with {@link #replaceReferences(String)} + * + * @author Camille Letavernier + * + */ +public abstract class TextReferencesHelper { + + public static final String URI_CHARS = "[^#]"; //Almost everything is allowed in a URI. It's simpler to exclude the fragment separator + + public static final String FRAGMENT_CHARS = "[-A-Za-z0-9_/]"; //In Papyrus this is sufficient. Do we need a more complex expression? + + public static final String URI_REGEX = String.format("%s*#%s+", URI_CHARS, FRAGMENT_CHARS); //The base uri is optional. The fragment is required. + + public static String UNKNOWN_ELEMENT = "UNKNOWN"; //Replacement text for unknown elements + + public static String PROXY_ELEMENT = "PROXY"; //Replacement text for proxy elements + + protected Resource baseResource; + + protected ResourceSet resourceSet; + + protected TextReferencesHelper() { + //Empty + } + + /** + * + * @param baseResource + * The resource against which the link uris will be resolved + */ + protected TextReferencesHelper(Resource baseResource) { + + if(baseResource != null) { + this.baseResource = baseResource; + this.resourceSet = baseResource.getResourceSet(); + } + } + + /** + * Parses the specified text, and replace all references with their replacement String + * + * @param text + * @return + * + * @see {@link #getReplacement(EObject, String)} + */ + public String replaceReferences(String text) { + if(text == null) { + return null; + } + + if("".equals(text)) { + return text; + } + + //Javadoc-like @link tag + String replaceRegex = String.format("\\{@link (%s)(\\|([^}]*))?\\}", URI_REGEX); + + Pattern pattern = Pattern.compile(replaceRegex); + Matcher matcher = pattern.matcher(text); + + String newText = text; + + while(matcher.find()) { + String uriToReplace = matcher.group(1); //0 is the full pattern (e.g. {link myUri#myFragment}, 1 is the first group (e.g. myUri#myFragment) + String cachedValue = matcher.group(3); //group 2 is |CachedValue, group 3 is CachedValue + + String replacement = decorate(getReplacement(uriToReplace, cachedValue)); + + newText = matcher.replaceFirst(replacement); + matcher = pattern.matcher(newText); + } + + return newText; + } + + /** + * Insert a reference to the given element in the specified text, at the specified position + * + * @param toElement + * The element to reference + * @param inText + * The text in which the reference must be inserted + * @param atPosition + * The position at which the reference must be inserted. 0 is the beginning, while text.length() is the end. For all "invalid" indexes (<0 + * and > length()), the reference will be inserted at the end of the string + * @return + * The text containing the new reference + */ + public String insertReference(EObject toElement, String inText, int atPosition) { + String result = inText; + if(inText == null) { + return null; //No change + } + + if(toElement == null) { + return inText; //No change + } + + //Use a Javadoc-like @link tag + URI elementURI = EcoreUtil.getURI(toElement); + if(baseResource != null) { + URI baseURI = baseResource.getURI(); + if(baseURI != null) { + elementURI = elementURI.deresolve(baseURI); + } + } + String reference = "{@link " + elementURI + "}"; //The URI is already encoded + + if(atPosition == 0) { + return reference + result; //At the beginning + } + + if(atPosition < 0 || atPosition >= inText.length()) { + result += reference; //Insert at the end + } else { + //Hello, world + //The whitespace is the character at position 6. Insert the reference at position 7 to add it after the whitespace + //It will result in Hello, world + result = inText.substring(0, atPosition); //Include the "afterPosition" character + result += reference; //Add the reference + result += inText.substring(atPosition, inText.length()); //Complete the string (Exclude the afterPosition character, as it has already been copied in the first part of the result string) + } + + return result; + } + + /** + * Adds a (text) decoration to the replacement string. + * This can be used for e.g. html-based texts, to add tags around the replaced string + * + * The default implementation does nothing. + */ + protected String decorate(String text) { + return text; + } + + protected String getReplacement(String uriToReplace, String cachedValue) { + String uri, fragment; + + if(baseResource == null || resourceSet == null || baseResource.getURI() == null) { + return UNKNOWN_ELEMENT; + } + + if(uriToReplace.contains("#")) { + uri = uriToReplace.substring(0, uriToReplace.indexOf('#')); + fragment = uriToReplace.substring(uriToReplace.indexOf('#') + 1, uriToReplace.length()); + } else { + return UNKNOWN_ELEMENT; + } + + URI targetURI; + + URI resourceURI; + + resourceURI = baseResource.getURI(); + + targetURI = URI.createURI(uri); //The URI must already be encoded + + targetURI = targetURI.resolve(resourceURI); + + if(targetURI == null) { + return UNKNOWN_ELEMENT; + } + + targetURI = targetURI.appendFragment(fragment); + + return getReplacement(targetURI, cachedValue); + } + + protected String getReplacement(URI uriToReplace, String cachedValue) { + try { + EObject targetElement = resourceSet.getEObject(uriToReplace, true); + return getReplacement(targetElement, cachedValue); + } catch (Exception ex) { + //Log the error? If it happens once, it will happen many times (after each refresh). The UNKNOWN keyword may be enough. + //This error happens when the reference is broken (e.g. an element has been deleted). This is a "normal" behavior + Activator.log.debug("An error occurred while loading the following URI: " + uriToReplace + ". The reference cannot be replaced"); //$NON-NLS-1$ //$NON-NLS-2$ + } + + return UNKNOWN_ELEMENT; + } + + protected abstract String getReplacement(EObject elementToReplace, String cachedValue); + +} diff --git a/plugins/sysml/diagram/org.eclipse.papyrus.sysml.diagram.common/src-common-sysml/org/eclipse/papyrus/sysml/diagram/common/dialogs/CreateOrSelectTypeDialog.java b/plugins/sysml/diagram/org.eclipse.papyrus.sysml.diagram.common/src-common-sysml/org/eclipse/papyrus/sysml/diagram/common/dialogs/CreateOrSelectTypeDialog.java index 7dec5fecc70..67970e01766 100644 --- a/plugins/sysml/diagram/org.eclipse.papyrus.sysml.diagram.common/src-common-sysml/org/eclipse/papyrus/sysml/diagram/common/dialogs/CreateOrSelectTypeDialog.java +++ b/plugins/sysml/diagram/org.eclipse.papyrus.sysml.diagram.common/src-common-sysml/org/eclipse/papyrus/sysml/diagram/common/dialogs/CreateOrSelectTypeDialog.java @@ -13,6 +13,7 @@ *****************************************************************************/ package org.eclipse.papyrus.sysml.diagram.common.dialogs; +import java.util.LinkedList; import java.util.List; import org.eclipse.core.runtime.IAdaptable; @@ -122,6 +123,7 @@ public class CreateOrSelectTypeDialog extends FormDialog { this.containerFeature = containerFeature; this.containerEClass = containerEClass; this.labelProvider = new UMLLabelProvider(); + this.notWantedMetaclasses = new LinkedList(); } /** -- cgit v1.2.3