diff options
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<EObject> 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<ViewerFilter> filters = new LinkedList<ViewerFilter>(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<EObject>(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<ViewerFilter> filters = new LinkedList<ViewerFilter>(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<EObject> 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<String> uriList = new ArrayList<String>();
-
- // 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<EObject> eObjectsToStore = new LinkedHashSet<EObject>();
- 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<EObject> 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<ViewerFilter> filters = new LinkedList<ViewerFilter>(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<EObject>(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<ViewerFilter> filters = new LinkedList<ViewerFilter>(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<EObject> 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<String> uriList = new ArrayList<String>(); + + // 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<EObject> eObjectsToStore = new LinkedHashSet<EObject>(); + 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<Object>();
-
- protected List<?> notWantedMetaclasses = new LinkedList<Object>();
-
- 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<EObject> roots = new LinkedList<EObject>();
- 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<Object>(); + + protected List<?> notWantedMetaclasses = new LinkedList<Object>(); + + 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<EObject> roots = new LinkedList<EObject>(); + 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<Replacement> updateDependencies(URI uriToReplace, URI targetURI, Collection<Resource> fromResources, EditingDomain editingDomain) {
- if(fromResources == null || fromResources.isEmpty()) {
- throw new IllegalArgumentException("There is no resource to modify");
- }
-
- Collection<Replacement> replacements = new LinkedList<Replacement>();
-
- 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<Replacement> 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<EObject> allContentsIterator = fromResource.getAllContents();
-
- Collection<Replacement> replacements = new LinkedList<Replacement>();
-
- 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<EObject, EObject> previousToNewValue = new HashMap<EObject, EObject>();
-
- 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<EObject, EObject> 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<Replacement> updateDependencies(URI uriToReplace, URI targetURI, ResourceSet resourceSet, EditingDomain editingDomain) {
- Set<Resource> resourcesToEdit = new HashSet<Resource>(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<Replacement> updateDependencies(URI uriToReplace, URI targetURI, Collection<Resource> 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<Replacement> 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<Replacement> updateDependencies(URI uriToReplace, URI targetURI, ResourceSet resourceSet) {
- Set<Resource> resourcesToEdit = new HashSet<Resource>(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<Replacement> updateDependencies(URI uriToReplace, URI targetURI, Collection<Resource> fromResources, EditingDomain editingDomain) { + if(fromResources == null || fromResources.isEmpty()) { + throw new IllegalArgumentException("There is no resource to modify"); //$NON-NLS-1$ + } + + Collection<Replacement> replacements = new LinkedList<Replacement>(); + + 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<Replacement> 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<EObject> allContentsIterator = fromResource.getAllContents(); + + Collection<Replacement> replacements = new LinkedList<Replacement>(); + + 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<EObject, EObject> previousToNewValue = new HashMap<EObject, EObject>(); + + 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<EObject, EObject> 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<Replacement> updateDependencies(URI uriToReplace, URI targetURI, ResourceSet resourceSet, EditingDomain editingDomain) { + Set<Resource> resourcesToEdit = new HashSet<Resource>(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<Replacement> updateDependencies(URI uriToReplace, URI targetURI, Collection<Resource> 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<Replacement> 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<Replacement> updateDependencies(URI uriToReplace, URI targetURI, ResourceSet resourceSet) { + Set<Resource> resourcesToEdit = new HashSet<Resource>(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<EObject> {
-
- 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<EObject> { + + 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<ExecutionEvent> {
-
- 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<ExecutionEvent> { + + 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<IEvaluationContext> {
-
- 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<IEvaluationContext> { + + 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}.
- * <p>
- * 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 <tt>org.eclipse.papyrus.infra.core.editor.ModelSetServiceFactory</tt>.
- * </p>
- *
- * @author cedric dumoulin
- *
- */
-public class ServiceUtilsForResource extends AbstractServiceUtils<Resource> {
-
- 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}. + * <p> + * 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 <tt>org.eclipse.papyrus.infra.core.editor.ModelSetServiceFactory</tt>. + * </p> + * + * @author cedric dumoulin + * + */ +public class ServiceUtilsForResource extends AbstractServiceUtils<Resource> { + + 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<ResourceSet> {
-
- 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<ResourceSet> { + + 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<ISelection> {
-
- 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<ISelection> { + + 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, <Replacement>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, <Replacement>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<Object>(); } /** |