From 6a4e668cc67173556e83a426bad9915b964eb653 Mon Sep 17 00:00:00 2001 From: vhemery Date: Wed, 1 Jun 2011 08:56:52 +0000 Subject: NEW - bug 320900: [General] No convenient renaming feature to consistently rename .di, .uml and .notation files https://bugs.eclipse.org/bugs/show_bug.cgi?id=320900 Thanks to this plugin if onethe file .uml,.di or .notation is renamed, moved or deleted then the others related file will be handled the same way Revision made by Arthur Daussy and checked by Hemery Vincent --- .../org.eclipse.papyrus.ui.resources/.classpath | 7 + incoming/org.eclipse.papyrus.ui.resources/.project | 28 ++ .../.settings/org.eclipse.jdt.core.prefs | 8 + .../META-INF/MANIFEST.MF | 13 + .../OSGI-INF/l10n/bundle.properties | 4 + .../org.eclipse.papyrus.ui.resources/about.html | 28 ++ .../build.properties | 12 + .../plugin.properties | 12 + .../org.eclipse.papyrus.ui.resources/plugin.xml | 48 ++++ .../eclipse/papyrus/ui/resources/Activator.java | 70 +++++ .../refactoring/DeleteModelParticipant.java | 147 +++++++++++ .../resources/refactoring/DirtyEditorChange.java | 146 +++++++++++ .../papyrus/ui/resources/refactoring/Messages.java | 50 ++++ .../refactoring/ModelParticipantHelpers.java | 127 +++++++++ .../refactoring/MoveModelParticipant.java | 117 +++++++++ .../resources/refactoring/RenameModelChange.java | 291 +++++++++++++++++++++ .../refactoring/RenameModelParticipant.java | 137 ++++++++++ .../ui/resources/refactoring/messages.properties | 11 + 18 files changed, 1256 insertions(+) create mode 100644 incoming/org.eclipse.papyrus.ui.resources/.classpath create mode 100644 incoming/org.eclipse.papyrus.ui.resources/.project create mode 100644 incoming/org.eclipse.papyrus.ui.resources/.settings/org.eclipse.jdt.core.prefs create mode 100644 incoming/org.eclipse.papyrus.ui.resources/META-INF/MANIFEST.MF create mode 100644 incoming/org.eclipse.papyrus.ui.resources/OSGI-INF/l10n/bundle.properties create mode 100644 incoming/org.eclipse.papyrus.ui.resources/about.html create mode 100644 incoming/org.eclipse.papyrus.ui.resources/build.properties create mode 100644 incoming/org.eclipse.papyrus.ui.resources/plugin.properties create mode 100644 incoming/org.eclipse.papyrus.ui.resources/plugin.xml create mode 100644 incoming/org.eclipse.papyrus.ui.resources/src/org/eclipse/papyrus/ui/resources/Activator.java create mode 100644 incoming/org.eclipse.papyrus.ui.resources/src/org/eclipse/papyrus/ui/resources/refactoring/DeleteModelParticipant.java create mode 100644 incoming/org.eclipse.papyrus.ui.resources/src/org/eclipse/papyrus/ui/resources/refactoring/DirtyEditorChange.java create mode 100644 incoming/org.eclipse.papyrus.ui.resources/src/org/eclipse/papyrus/ui/resources/refactoring/Messages.java create mode 100644 incoming/org.eclipse.papyrus.ui.resources/src/org/eclipse/papyrus/ui/resources/refactoring/ModelParticipantHelpers.java create mode 100644 incoming/org.eclipse.papyrus.ui.resources/src/org/eclipse/papyrus/ui/resources/refactoring/MoveModelParticipant.java create mode 100644 incoming/org.eclipse.papyrus.ui.resources/src/org/eclipse/papyrus/ui/resources/refactoring/RenameModelChange.java create mode 100644 incoming/org.eclipse.papyrus.ui.resources/src/org/eclipse/papyrus/ui/resources/refactoring/RenameModelParticipant.java create mode 100644 incoming/org.eclipse.papyrus.ui.resources/src/org/eclipse/papyrus/ui/resources/refactoring/messages.properties (limited to 'incoming') diff --git a/incoming/org.eclipse.papyrus.ui.resources/.classpath b/incoming/org.eclipse.papyrus.ui.resources/.classpath new file mode 100644 index 00000000000..2d1a4302f04 --- /dev/null +++ b/incoming/org.eclipse.papyrus.ui.resources/.classpath @@ -0,0 +1,7 @@ + + + + + + + diff --git a/incoming/org.eclipse.papyrus.ui.resources/.project b/incoming/org.eclipse.papyrus.ui.resources/.project new file mode 100644 index 00000000000..72f62f5283f --- /dev/null +++ b/incoming/org.eclipse.papyrus.ui.resources/.project @@ -0,0 +1,28 @@ + + + org.eclipse.papyrus.ui.resources + + + + + + org.eclipse.jdt.core.javabuilder + + + + + org.eclipse.pde.ManifestBuilder + + + + + org.eclipse.pde.SchemaBuilder + + + + + + org.eclipse.pde.PluginNature + org.eclipse.jdt.core.javanature + + diff --git a/incoming/org.eclipse.papyrus.ui.resources/.settings/org.eclipse.jdt.core.prefs b/incoming/org.eclipse.papyrus.ui.resources/.settings/org.eclipse.jdt.core.prefs new file mode 100644 index 00000000000..91065e4f9d7 --- /dev/null +++ b/incoming/org.eclipse.papyrus.ui.resources/.settings/org.eclipse.jdt.core.prefs @@ -0,0 +1,8 @@ +#Tue May 31 14:52:21 CEST 2011 +eclipse.preferences.version=1 +org.eclipse.jdt.core.compiler.codegen.inlineJsrBytecode=enabled +org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.5 +org.eclipse.jdt.core.compiler.compliance=1.5 +org.eclipse.jdt.core.compiler.problem.assertIdentifier=error +org.eclipse.jdt.core.compiler.problem.enumIdentifier=error +org.eclipse.jdt.core.compiler.source=1.5 diff --git a/incoming/org.eclipse.papyrus.ui.resources/META-INF/MANIFEST.MF b/incoming/org.eclipse.papyrus.ui.resources/META-INF/MANIFEST.MF new file mode 100644 index 00000000000..4149fbfdb7f --- /dev/null +++ b/incoming/org.eclipse.papyrus.ui.resources/META-INF/MANIFEST.MF @@ -0,0 +1,13 @@ +Manifest-Version: 1.0 +Bundle-ManifestVersion: 2 +Bundle-Name: %pluginName +Bundle-SymbolicName: org.eclipse.papyrus.ui.resources;singleton:=true +Bundle-Version: 0.8.0.qualifier +Bundle-Activator: org.eclipse.papyrus.ui.resources.Activator +Bundle-Vendor: %providerName +Require-Bundle: org.eclipse.ui, + org.eclipse.core.runtime, + org.eclipse.papyrus.core;bundle-version="0.8.0";visibility:=reexport, + org.eclipse.ltk.core.refactoring;bundle-version="3.5.200" +Bundle-RequiredExecutionEnvironment: J2SE-1.5 +Bundle-ActivationPolicy: lazy diff --git a/incoming/org.eclipse.papyrus.ui.resources/OSGI-INF/l10n/bundle.properties b/incoming/org.eclipse.papyrus.ui.resources/OSGI-INF/l10n/bundle.properties new file mode 100644 index 00000000000..b7cbe34891d --- /dev/null +++ b/incoming/org.eclipse.papyrus.ui.resources/OSGI-INF/l10n/bundle.properties @@ -0,0 +1,4 @@ +#Properties file for org.eclipse.papyrus.ui.resources +renameParticipant.name = Papyrus Model Renaming +deleteParticipant.name = Papyrus Model deleting +moveParticipant.name = Papyrus Model Moving \ No newline at end of file diff --git a/incoming/org.eclipse.papyrus.ui.resources/about.html b/incoming/org.eclipse.papyrus.ui.resources/about.html new file mode 100644 index 00000000000..209103075a7 --- /dev/null +++ b/incoming/org.eclipse.papyrus.ui.resources/about.html @@ -0,0 +1,28 @@ + + + + +About + + +

About This Content

+ +

November 14, 2008

+

License

+ +

The Eclipse Foundation makes available all content in this plug-in ("Content"). Unless otherwise +indicated below, the Content is provided to you under the terms and conditions of the +Eclipse Public License Version 1.0 ("EPL"). A copy of the EPL is available +at http://www.eclipse.org/legal/epl-v10.html. +For purposes of the EPL, "Program" will mean the Content.

+ +

If you did not receive this Content directly from the Eclipse Foundation, the Content is +being redistributed by another party ("Redistributor") and different terms and conditions may +apply to your use of any object code in the Content. Check the Redistributor's license that was +provided with the Content. If no such license exists, contact the Redistributor. Unless otherwise +indicated below, the terms and conditions of the EPL still apply to any source code in the Content +and such source code may be obtained at http://www.eclipse.org.

+ + + \ No newline at end of file diff --git a/incoming/org.eclipse.papyrus.ui.resources/build.properties b/incoming/org.eclipse.papyrus.ui.resources/build.properties new file mode 100644 index 00000000000..2cf007df061 --- /dev/null +++ b/incoming/org.eclipse.papyrus.ui.resources/build.properties @@ -0,0 +1,12 @@ +source.. = src/ +output.. = bin/ +bin.includes = META-INF/,\ + .,\ + plugin.properties,\ + plugin.xml,\ + about.html,\ + OSGI-INF/,\ + OSGI-INF/l10n/,\ + OSGI-INF/l10n/bundle.properties,\ + src/org/eclipse/papyrus/ui/resources/refactoring/messages.properties +src.includes = about.html diff --git a/incoming/org.eclipse.papyrus.ui.resources/plugin.properties b/incoming/org.eclipse.papyrus.ui.resources/plugin.properties new file mode 100644 index 00000000000..2c2ed53f763 --- /dev/null +++ b/incoming/org.eclipse.papyrus.ui.resources/plugin.properties @@ -0,0 +1,12 @@ +################################################################################# +# Copyright (c) 2011 Atos Origin. +# 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: +# Arthur Daussy arthur.daussy@atosorigin.com - Initial API and implementation +################################################################################## +pluginName=Papyrus plugin for refactoring resources (Incubation) +providerName=Eclipse Modeling Project \ No newline at end of file diff --git a/incoming/org.eclipse.papyrus.ui.resources/plugin.xml b/incoming/org.eclipse.papyrus.ui.resources/plugin.xml new file mode 100644 index 00000000000..f8a0401f551 --- /dev/null +++ b/incoming/org.eclipse.papyrus.ui.resources/plugin.xml @@ -0,0 +1,48 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/incoming/org.eclipse.papyrus.ui.resources/src/org/eclipse/papyrus/ui/resources/Activator.java b/incoming/org.eclipse.papyrus.ui.resources/src/org/eclipse/papyrus/ui/resources/Activator.java new file mode 100644 index 00000000000..705c2d89351 --- /dev/null +++ b/incoming/org.eclipse.papyrus.ui.resources/src/org/eclipse/papyrus/ui/resources/Activator.java @@ -0,0 +1,70 @@ +/***************************************************************************** + * Copyright (c) 2010 Atos Origin. + * + * + * 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: + * Atos Origin - Initial API and implementation + * + *****************************************************************************/ +package org.eclipse.papyrus.ui.resources; + +import org.eclipse.papyrus.log.LogHelper; +import org.eclipse.ui.plugin.AbstractUIPlugin; +import org.osgi.framework.BundleContext; + +/** + * The activator class controls the plug-in life cycle + */ +public class Activator extends AbstractUIPlugin { + + // The plug-in ID + public static final String PLUGIN_ID = "org.eclipse.papyrus.ui.resources"; //$NON-NLS-1$ + + // The shared instance + private static Activator plugin; + + /** The log service */ + public static LogHelper log; + + /** + * The constructor + */ + public Activator() { + } + + /* + * (non-Javadoc) + * + * @see org.eclipse.ui.plugin.AbstractUIPlugin#start(org.osgi.framework.BundleContext) + */ + public void start(BundleContext context) throws Exception { + super.start(context); + plugin = this; + log = new LogHelper(plugin); + } + + /* + * (non-Javadoc) + * + * @see org.eclipse.ui.plugin.AbstractUIPlugin#stop(org.osgi.framework.BundleContext) + */ + public void stop(BundleContext context) throws Exception { + plugin = null; + super.stop(context); + } + + /** + * Returns the shared instance + * + * @return the shared instance + */ + public static Activator getDefault() { + return plugin; + } + +} diff --git a/incoming/org.eclipse.papyrus.ui.resources/src/org/eclipse/papyrus/ui/resources/refactoring/DeleteModelParticipant.java b/incoming/org.eclipse.papyrus.ui.resources/src/org/eclipse/papyrus/ui/resources/refactoring/DeleteModelParticipant.java new file mode 100644 index 00000000000..b06dffd851e --- /dev/null +++ b/incoming/org.eclipse.papyrus.ui.resources/src/org/eclipse/papyrus/ui/resources/refactoring/DeleteModelParticipant.java @@ -0,0 +1,147 @@ +/***************************************************************************** + * Copyright (c) 2009 Atos Origin. + * + * + * 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: + * Thomas Szadel - Initial API and implementation + * + *****************************************************************************/ +package org.eclipse.papyrus.ui.resources.refactoring; + +import java.util.ArrayList; +import java.util.List; +import java.util.Set; + +import org.eclipse.core.resources.IFile; +import org.eclipse.core.resources.IResource; +import org.eclipse.core.runtime.CoreException; +import org.eclipse.core.runtime.IPath; +import org.eclipse.core.runtime.IProgressMonitor; +import org.eclipse.core.runtime.OperationCanceledException; +import org.eclipse.ltk.core.refactoring.Change; +import org.eclipse.ltk.core.refactoring.CompositeChange; +import org.eclipse.ltk.core.refactoring.NullChange; +import org.eclipse.ltk.core.refactoring.RefactoringStatus; +import org.eclipse.ltk.core.refactoring.participants.CheckConditionsContext; +import org.eclipse.ltk.core.refactoring.participants.DeleteParticipant; +import org.eclipse.ltk.core.refactoring.resource.DeleteResourceChange; + +/** + * The participant that is aware of file deletion. + * FIXME Integrate and create register to the extension point + * + * @author Thomas Szadel + * + */ +public class DeleteModelParticipant extends DeleteParticipant { + + /** action name */ + private static final String NAME = "Papyrus Model Deletion"; + + private Set filesToRemove; + + /** + * Overrides checkConditions. + * + * {@inheritDoc} + * + * @see org.eclipse.ltk.core.refactoring.participants.RefactoringParticipant#checkConditions(org.eclipse.core.runtime.IProgressMonitor, + * org.eclipse.ltk.core.refactoring.participants.CheckConditionsContext) + */ + @Override + public RefactoringStatus checkConditions(IProgressMonitor pm, CheckConditionsContext context) throws OperationCanceledException { + return new RefactoringStatus(); + } + + /** + * Overrides createChange. + * + * {@inheritDoc} + * + * @see org.eclipse.ltk.core.refactoring.participants.RefactoringParticipant#createChange(org.eclipse.core.runtime.IProgressMonitor) + */ + @Override + public Change createChange(IProgressMonitor pm) throws CoreException, OperationCanceledException { + List changes = new ArrayList(filesToRemove.size()); + for(IResource file : filesToRemove) { + if(file.exists()) { + changes.add(new InternalDeleteResourceChange(file.getFullPath(), true)); + } + } + if(changes.isEmpty()) { + return new NullChange(); + } else { + return new CompositeChange(getName(), changes.toArray(new Change[changes.size()])); + } + } + + /** + * Overrides getName. + * + * {@inheritDoc} + * + * @see org.eclipse.ltk.core.refactoring.participants.RefactoringParticipant#getName() + */ + @Override + public String getName() { + return NAME; + } + + /** + * Overrides initialize. + * + * {@inheritDoc} + * + * @see org.eclipse.ltk.core.refactoring.participants.RefactoringParticipant#initialize(java.lang.Object) + */ + @Override + protected boolean initialize(Object element) { + if(!(element instanceof IFile)) { + return false; + } + IFile file = (IFile)element; + + filesToRemove = ModelParticipantHelpers.getRelatedFiles(file); + return filesToRemove.size() > 0; + } + + + + private class InternalDeleteResourceChange extends DeleteResourceChange { + + /** + * Constructor. + * + * @param resourcePath + * The file to delete. + * @param forceOutOfSync + * Delete even if out of sync + */ + public InternalDeleteResourceChange(IPath resourcePath, boolean forceOutOfSync) { + super(resourcePath, forceOutOfSync); + } + + /** + * @see org.eclipse.ltk.core.refactoring.resource.DeleteResourceChange#perform(org.eclipse.core.runtime.IProgressMonitor) + * + * @param pm + * @return + * @throws CoreException + */ + + @Override + public Change perform(IProgressMonitor pm) throws CoreException { + IResource resource = getModifiedResource(); + // If the user selects the 3 resources, the delete fails. + if(resource == null || !resource.exists()) { + return new NullChange(); + } + return super.perform(pm); + } + } +} diff --git a/incoming/org.eclipse.papyrus.ui.resources/src/org/eclipse/papyrus/ui/resources/refactoring/DirtyEditorChange.java b/incoming/org.eclipse.papyrus.ui.resources/src/org/eclipse/papyrus/ui/resources/refactoring/DirtyEditorChange.java new file mode 100644 index 00000000000..505cbe6b2e0 --- /dev/null +++ b/incoming/org.eclipse.papyrus.ui.resources/src/org/eclipse/papyrus/ui/resources/refactoring/DirtyEditorChange.java @@ -0,0 +1,146 @@ +/***************************************************************************** + * Copyright (c) 2009 Atos Origin. + * + * + * 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: + * Thomas Szadel - Initial API and implementation + * + *****************************************************************************/ +package org.eclipse.papyrus.ui.resources.refactoring; + +import org.eclipse.core.resources.IFile; +import org.eclipse.core.runtime.CoreException; +import org.eclipse.core.runtime.IProgressMonitor; +import org.eclipse.core.runtime.OperationCanceledException; +import org.eclipse.jface.dialogs.MessageDialog; +import org.eclipse.ltk.core.refactoring.Change; +import org.eclipse.ltk.core.refactoring.RefactoringStatus; +import org.eclipse.papyrus.core.editor.IMultiDiagramEditor; +import org.eclipse.papyrus.core.utils.EditorUtils; +import org.eclipse.swt.widgets.Display; + + +/** + * A change that checks if an editor is actually editing the model and if it must be save. + * + * @author tszadel + * + */ +public class DirtyEditorChange extends Change { + + private final IFile oldFile; + + private final IFile newFile; + + /** + * Constructor. + * + * @param resourceSet + * The resource set being changed. + * @param oldFile + * The old file. + * @param newFile + * The new file. + */ + public DirtyEditorChange(IFile oldFile, IFile newFile) { + this.oldFile = oldFile; + this.newFile = newFile; + } + + /** + * @see org.eclipse.ltk.core.refactoring.Change#getModifiedElement() + * + * @return + */ + + @Override + public Object getModifiedElement() { + return oldFile; + } + + /** + * @see org.eclipse.ltk.core.refactoring.Change#getName() + * + * @return + */ + + @Override + public String getName() { + return "Check opened editors"; + } + + /** + * @see org.eclipse.ltk.core.refactoring.Change#initializeValidationData(org.eclipse.core.runtime.IProgressMonitor) + * + * @param pm + */ + + @Override + public void initializeValidationData(IProgressMonitor pm) { + // Nothing + } + + + private boolean hasDirtyEditors() { + IMultiDiagramEditor[] list = EditorUtils.getRelatedEditors(oldFile); + if(list != null && list.length > 0) { + for(IMultiDiagramEditor editor : list) { + if(editor.isDirty()) { + return true; + } + } + } + return false; + } + + /** + * @see org.eclipse.ltk.core.refactoring.Change#isValid(org.eclipse.core.runtime.IProgressMonitor) + * + * @param pm + * The progress monitor. + * @return The status. + * @throws CoreException + * Error. + * @throws OperationCanceledException + * Operation canceled. + */ + + @Override + public RefactoringStatus isValid(IProgressMonitor pm) throws CoreException, OperationCanceledException { + final RefactoringStatus status = new RefactoringStatus(); + // We need to get the current workbench... so we have to use the UI-Thread! + Display.getDefault().syncExec(new Runnable() { + + public void run() { + if(hasDirtyEditors()) { + if(!MessageDialog.openConfirm(Display.getDefault().getActiveShell(), "Confirm saving", "The related editor(s) must be saved to continue.")) { + status.addFatalError("User doesn't want to save the related editor(s)"); + } + } + } + }); + + return status; + } + + /** + * @see org.eclipse.ltk.core.refactoring.Change#perform(org.eclipse.core.runtime.IProgressMonitor) + * + * @param pm + * The progress monitor. + * @return The change used to undo. + * @throws CoreException + * Error. + */ + + @Override + public Change perform(IProgressMonitor pm) throws CoreException { + // Nothing to do + return new DirtyEditorChange(newFile, oldFile); + } +} diff --git a/incoming/org.eclipse.papyrus.ui.resources/src/org/eclipse/papyrus/ui/resources/refactoring/Messages.java b/incoming/org.eclipse.papyrus.ui.resources/src/org/eclipse/papyrus/ui/resources/refactoring/Messages.java new file mode 100644 index 00000000000..8ca262871dc --- /dev/null +++ b/incoming/org.eclipse.papyrus.ui.resources/src/org/eclipse/papyrus/ui/resources/refactoring/Messages.java @@ -0,0 +1,50 @@ +/***************************************************************************** + * Copyright (c) 2011 Atos Origin. + * + * + * 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: + * Arthur Daussy - Initial API and implementation + * + *****************************************************************************/ +package org.eclipse.papyrus.ui.resources.refactoring; + +import org.eclipse.osgi.util.NLS; + +public class Messages extends NLS { + + private static final String BUNDLE_NAME = "org.eclipse.papyrus.ui.resources.refactoring.messages"; //$NON-NLS-1$ + + public static String MoveModelParticipant_Name; + + public static String RenameModelChange_6; + + public static String RenameModelChange_Change; + + public static String RenameModelChange_DaveDirtyEditor; + + public static String RenameModelChange_ErrorLoading; + + public static String RenameModelChange_LoadingEMF; + + public static String RenameModelChange_ModifyURI; + + public static String RenameModelChange_Name; + + public static String RenameModelChange_RemoveOldFile; + + public static String RenameModelChange_savingResource; + + public static String RenameModelChange_Unloading; + static { + // initialize resource bundle + NLS.initializeMessages(BUNDLE_NAME, Messages.class); + } + + private Messages() { + } +} diff --git a/incoming/org.eclipse.papyrus.ui.resources/src/org/eclipse/papyrus/ui/resources/refactoring/ModelParticipantHelpers.java b/incoming/org.eclipse.papyrus.ui.resources/src/org/eclipse/papyrus/ui/resources/refactoring/ModelParticipantHelpers.java new file mode 100644 index 00000000000..c8c27037b5c --- /dev/null +++ b/incoming/org.eclipse.papyrus.ui.resources/src/org/eclipse/papyrus/ui/resources/refactoring/ModelParticipantHelpers.java @@ -0,0 +1,127 @@ +/***************************************************************************** + * Copyright (c) 2010 Atos Origin. + * + * + * 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: + * Thomas Szadel - Initial API and implementation + * + *****************************************************************************/ +package org.eclipse.papyrus.ui.resources.refactoring; + +import java.util.ArrayList; +import java.util.HashSet; +import java.util.List; +import java.util.Set; + +import org.eclipse.core.resources.IContainer; +import org.eclipse.core.resources.IFile; +import org.eclipse.core.resources.IResource; +import org.eclipse.core.resources.ResourcesPlugin; +import org.eclipse.core.runtime.CoreException; +import org.eclipse.core.runtime.IPath; +import org.eclipse.emf.common.util.URI; +import org.eclipse.emf.ecore.EObject; +import org.eclipse.emf.ecore.InternalEObject; +import org.eclipse.emf.ecore.resource.Resource; +import org.eclipse.emf.ecore.resource.ResourceSet; +import org.eclipse.emf.ecore.resource.impl.ResourceSetImpl; +import org.eclipse.gmf.runtime.notation.Diagram; +import org.eclipse.gmf.runtime.notation.NotationPackage; +import org.eclipse.papyrus.resource.notation.NotationModel; +import org.eclipse.papyrus.resource.sasheditor.DiModel; + +public class ModelParticipantHelpers { + + /** + * get the files related the initialFile which need to be modified/deleted + * if initialFile is modified/deleted + * + * @param initialFile + * @return a list of related files. Does not include initialFile. + */ + public static Set getRelatedFiles(IFile initialFile) { + + Set relatedFiles = new HashSet(); + + IContainer parent = initialFile.getParent(); + IPath initialPath = initialFile.getFullPath(); + + IPath diPath = null; + + if(DiModel.DI_FILE_EXTENSION.equalsIgnoreCase(initialPath.getFileExtension())) { + diPath = initialPath; + } else { + // try to find a di file with the same name + try { + for(IResource r : parent.members()) { + IPath p = r.getFullPath(); + if(DiModel.DI_FILE_EXTENSION.equalsIgnoreCase(p.getFileExtension()) && p.removeFileExtension().equals(initialPath.removeFileExtension())) { + diPath = p; + break; + } + } + } catch (CoreException e) { + } + } + + if(diPath != null) { + IFile diFile = parent.getFile(diPath.makeRelativeTo(parent.getFullPath())); + + if(diFile.exists()) { + relatedFiles.add(diFile); + + // add the notation file + IPath notationPath = initialPath.removeFileExtension().addFileExtension(NotationModel.NOTATION_FILE_EXTENSION); + IFile notationFile = parent.getFile(notationPath.makeRelativeTo(parent.getFullPath())); + + if(notationFile.exists()) { + relatedFiles.add(notationFile); + + // find the related model files referenced in the notation file + URI notationURI = URI.createPlatformResourceURI(notationPath.toString(), true); + ResourceSet rs = new ResourceSetImpl(); + Resource notationResource = rs.getResource(notationURI, true); + + if(notationResource != null) { + relatedFiles.addAll(getModelFilesFromNotationResource(notationResource)); + } + } + } + } + + // If the initialFile is contained in the list, we remove it + if(relatedFiles.contains(initialFile)) { + relatedFiles.remove(initialFile); + } + + return relatedFiles; + } + + private static List getModelFilesFromNotationResource(Resource notationResource) { + List modelFiles = new ArrayList(); + + // look for a model associated with a diagram in notation + for(EObject eObject : notationResource.getContents()) { + if(eObject instanceof Diagram) { + Diagram diagram = (Diagram)eObject; + InternalEObject element = (InternalEObject)diagram.eGet(NotationPackage.Literals.VIEW__ELEMENT, false); + if(element != null && element.eIsProxy()) { + URI modelURI = element.eProxyURI().trimFragment(); + if(modelURI.isPlatform()) { + IResource modelFile = ResourcesPlugin.getWorkspace().getRoot().findMember(modelURI.toPlatformString(true)); + if(modelFile != null) { + modelFiles.add(modelFile); + } + } + } + } + } + + return modelFiles; + } +} diff --git a/incoming/org.eclipse.papyrus.ui.resources/src/org/eclipse/papyrus/ui/resources/refactoring/MoveModelParticipant.java b/incoming/org.eclipse.papyrus.ui.resources/src/org/eclipse/papyrus/ui/resources/refactoring/MoveModelParticipant.java new file mode 100644 index 00000000000..503f8fbef19 --- /dev/null +++ b/incoming/org.eclipse.papyrus.ui.resources/src/org/eclipse/papyrus/ui/resources/refactoring/MoveModelParticipant.java @@ -0,0 +1,117 @@ +/***************************************************************************** + * Copyright (c) 2009 Atos Origin. + * + * + * 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: + * Thomas Szadel - Initial API and implementation + * Arthur Daussy - Correction of the move ( set the destination attribute) + *****************************************************************************/ +package org.eclipse.papyrus.ui.resources.refactoring; + +import java.util.ArrayList; +import java.util.HashSet; +import java.util.List; +import java.util.Set; + +import org.eclipse.core.resources.IContainer; +import org.eclipse.core.resources.IFile; +import org.eclipse.core.resources.IResource; +import org.eclipse.core.runtime.CoreException; +import org.eclipse.core.runtime.IProgressMonitor; +import org.eclipse.core.runtime.OperationCanceledException; +import org.eclipse.ltk.core.refactoring.Change; +import org.eclipse.ltk.core.refactoring.CompositeChange; +import org.eclipse.ltk.core.refactoring.NullChange; +import org.eclipse.ltk.core.refactoring.RefactoringStatus; +import org.eclipse.ltk.core.refactoring.participants.CheckConditionsContext; +import org.eclipse.ltk.core.refactoring.participants.MoveParticipant; +import org.eclipse.ltk.core.refactoring.resource.MoveResourceChange; + +/** + * Participant that is aware of model deletion. + * FIXME Integrate and create register to the extension point + * + * @author Thomas Szadel + * + */ +public class MoveModelParticipant extends MoveParticipant { + + private Set filesToMove = new HashSet(); + + private IContainer destination; + + /** + * Overrides checkConditions. + * + * {@inheritDoc} + * + * @see org.eclipse.ltk.core.refactoring.participants.RefactoringParticipant#checkConditions(org.eclipse.core.runtime.IProgressMonitor, + * org.eclipse.ltk.core.refactoring.participants.CheckConditionsContext) + */ + @Override + public RefactoringStatus checkConditions(IProgressMonitor pm, CheckConditionsContext context) throws OperationCanceledException { + return new RefactoringStatus(); + } + + /** + * Overrides createChange. + * + * {@inheritDoc} + * + * @see org.eclipse.ltk.core.refactoring.participants.RefactoringParticipant#createChange(org.eclipse.core.runtime.IProgressMonitor) + */ + @Override + public Change createChange(IProgressMonitor pm) throws CoreException, OperationCanceledException { + List changes = new ArrayList(filesToMove.size()); + + for(IResource path : filesToMove) { + if(path.exists()) { + changes.add(new MoveResourceChange(path, destination)); + } + } + if(changes.isEmpty()) { + return new NullChange(); + } else { + return new CompositeChange(getName(), changes.toArray(new Change[changes.size()])); + } + } + + /** + * Overrides getName. + * + * {@inheritDoc} + * + * @see org.eclipse.ltk.core.refactoring.participants.RefactoringParticipant#getName() + */ + @Override + public String getName() { + return Messages.MoveModelParticipant_Name; + } + + /** + * Overrides initialize. + * + * {@inheritDoc} + * + * @see org.eclipse.ltk.core.refactoring.participants.RefactoringParticipant#initialize(java.lang.Object) + */ + @Override + protected boolean initialize(Object element) { + if(!(element instanceof IFile)) { + return false; + } + IFile file = (IFile)element; + Object _destination = getArguments().getDestination(); + if(_destination instanceof IContainer) { + destination = (IContainer)_destination; + + } + filesToMove = ModelParticipantHelpers.getRelatedFiles(file); + return filesToMove.size() > 0; + } +} diff --git a/incoming/org.eclipse.papyrus.ui.resources/src/org/eclipse/papyrus/ui/resources/refactoring/RenameModelChange.java b/incoming/org.eclipse.papyrus.ui.resources/src/org/eclipse/papyrus/ui/resources/refactoring/RenameModelChange.java new file mode 100644 index 00000000000..51f529525f2 --- /dev/null +++ b/incoming/org.eclipse.papyrus.ui.resources/src/org/eclipse/papyrus/ui/resources/refactoring/RenameModelChange.java @@ -0,0 +1,291 @@ +/***************************************************************************** + * Copyright (c) 2009 Atos Origin. + * + * + * 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: + * Thomas Szadel - Initial API and implementation + * + *****************************************************************************/ +package org.eclipse.papyrus.ui.resources.refactoring; + +import static org.eclipse.papyrus.ui.resources.Activator.log; + +import java.io.IOException; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.Set; + +import org.eclipse.core.resources.IFile; +import org.eclipse.core.resources.IResource; +import org.eclipse.core.runtime.CoreException; +import org.eclipse.core.runtime.IPath; +import org.eclipse.core.runtime.IProgressMonitor; +import org.eclipse.core.runtime.NullProgressMonitor; +import org.eclipse.core.runtime.OperationCanceledException; +import org.eclipse.core.runtime.SubProgressMonitor; +import org.eclipse.emf.common.util.URI; +import org.eclipse.emf.ecore.resource.Resource; +import org.eclipse.emf.ecore.util.EcoreUtil; +import org.eclipse.ltk.core.refactoring.Change; +import org.eclipse.ltk.core.refactoring.RefactoringStatus; +import org.eclipse.ltk.core.refactoring.resource.RenameResourceChange; +import org.eclipse.papyrus.core.editor.IMultiDiagramEditor; +import org.eclipse.papyrus.core.services.ServiceException; +import org.eclipse.papyrus.core.utils.DiResourceSet; +import org.eclipse.papyrus.core.utils.EditorUtils; +import org.eclipse.papyrus.resource.ModelSet; +import org.eclipse.papyrus.resource.ModelsReader; +import org.eclipse.papyrus.resource.sasheditor.DiModelUtils; +import org.eclipse.swt.widgets.Display; +import org.eclipse.ui.part.FileEditorInput; + +/** + * Rename the model.
+ * Note: That change should be called inside a rename operation as it assumes that a {@link RenameResourceChange} occured. + * + * @author tszadel + * + */ +public class RenameModelChange extends Change { + + private final Map uriMap = new HashMap(); + + private final IFile oldFile; + + private final IFile newFile; + + private final Set relatedFiles; + + /** + * Constructor. + * + * @param resourceSet + * The resource set being changed. + * @param oldFile + * The old file. + * @param newFile + * The new file. + */ + public RenameModelChange(IFile oldFile, IFile newFile) { + this.oldFile = oldFile; + this.newFile = newFile; + + IPath newPathWithoutExt = newFile.getFullPath().removeFileExtension(); + + // Create the map of URI that are being modified in the resource set + relatedFiles = ModelParticipantHelpers.getRelatedFiles(oldFile); + relatedFiles.add(oldFile); + for(IResource file : relatedFiles) { + IPath path = file.getFullPath(); + URI oldURI = getPlatformURI(path); + URI newURI = getPlatformURI(newPathWithoutExt.addFileExtension(path.getFileExtension())); + uriMap.put(oldURI, newURI); + } + } + + /** + * Overrides getModifiedElement. + * + * {@inheritDoc} + * + * @see org.eclipse.ltk.core.refactoring.Change#getModifiedElement() + */ + @Override + public Object getModifiedElement() { + return oldFile; + } + + /** + * Overrides getName. + * + * {@inheritDoc} + * + * @see org.eclipse.ltk.core.refactoring.Change#getName() + */ + @Override + public String getName() { + return Messages.bind(Messages.RenameModelChange_Name, oldFile.getName()); + } + + /** + * Overrides initializeValidationData. + * + * {@inheritDoc} + * + * @see org.eclipse.ltk.core.refactoring.Change#initializeValidationData(org.eclipse.core.runtime.IProgressMonitor) + */ + @Override + public void initializeValidationData(IProgressMonitor pm) { + // Nothing + } + + /** + * Overrides isValid. + * + * {@inheritDoc} + * + * @see org.eclipse.ltk.core.refactoring.Change#isValid(org.eclipse.core.runtime.IProgressMonitor) + */ + @Override + public RefactoringStatus isValid(IProgressMonitor pm) throws CoreException, OperationCanceledException { + return new RefactoringStatus(); + } + + /** + * Get a platform resource URI of the given path + * + * @param path + * the path + * @return the uri + */ + private URI getPlatformURI(IPath path) { + return URI.createPlatformResourceURI(path.toString(), true); + } + + + /** + * Overrides perform. + * + * {@inheritDoc} + * + * @see org.eclipse.ltk.core.refactoring.Change#perform(org.eclipse.core.runtime.IProgressMonitor) + */ + @Override + public Change perform(IProgressMonitor pm) throws CoreException { + String lMsg = Messages.bind(Messages.RenameModelChange_Change, oldFile.getName(), newFile.getName()); + log.info(lMsg); + pm.beginTask(lMsg, 30); + try { + // That change assumes that the model resource has already been renamed + // So, the first thing to do is to get the new file, to restore it in order + // to change all the resources. + pm.subTask(Messages.RenameModelChange_LoadingEMF); + + boolean isUndoOperation = oldFile.exists() && !newFile.exists(); + if(!isUndoOperation) { + newFile.move(oldFile.getFullPath(), true, new SubProgressMonitor(pm, 1)); + } + // String extension= newFile.getFileExtension(); + // if( extension == null){ + // newFile.getFullPath().addFileExtension(oldFile.getFileExtension()); + // } + pm.subTask(Messages.RenameModelChange_DaveDirtyEditor); + // We need to get the current workbench... so we have to use the UI-Thread! + final List openedEditors = new ArrayList(); + Display.getDefault().syncExec(new Runnable() { + + public void run() { + IMultiDiagramEditor[] multiEditors = EditorUtils.getRelatedEditors(oldFile); + if(multiEditors != null) { + for(IMultiDiagramEditor editor : multiEditors) { + if(editor.isDirty()) { + editor.doSave(new NullProgressMonitor()); + } + openedEditors.add(editor); + } + } + } + }); + pm.worked(10); + + /* + * Load ModelSet + */ + ModelSet resourceSet = new ModelSet(); + try { + ModelsReader reader = new ModelsReader(); + reader.readModel(resourceSet); + resourceSet.loadModels(oldFile); + } catch (Exception e) { + e.printStackTrace(); + } + // Force EMF resolve and load all the resources + EcoreUtil.resolveAll(resourceSet); + pm.worked(4); + + // Change the URIs of modified resources + pm.subTask(Messages.RenameModelChange_ModifyURI); + for(Resource res : resourceSet.getResources()) { + if(res.getURI().isPlatformResource()) { + URI newURI = uriMap.get(res.getURI()); + if(newURI != null) { + if(log.isDebugEnabled()) { + log.debug(Messages.bind(Messages.RenameModelChange_6, Arrays.asList(res.getURI(), newURI))); + } + res.setURI(newURI); + } + } + + } + pm.worked(5); + + // Now, save all the resources + pm.subTask(Messages.RenameModelChange_savingResource); + for(Resource res : resourceSet.getResources()) { + if(res.getURI().isPlatformResource()) { + try { + res.save(null); + } catch (IOException e) { + log.error(Messages.bind(Messages.RenameModelChange_ErrorLoading, res.getURI()), e); + } + } + } + pm.worked(5); + + // Do not forget to unload all the resources to avoid memory leak + pm.subTask(Messages.RenameModelChange_Unloading); + resourceSet.unload(); + pm.worked(1); + + // Now, notify the editor of the change + if(!openedEditors.isEmpty()) { + Display.getDefault().syncExec(new Runnable() { + + public void run() { + // Get the DI file as the rename could occur on any model's file. + IFile newDiFile = DiModelUtils.getRelatedDiFile(newFile); + for(IMultiDiagramEditor editor : openedEditors) { + try { + DiResourceSet diRes = editor.getServicesRegistry().getService(DiResourceSet.class); + if(diRes != null) { + diRes.saveAs(newFile.getFullPath()); + } + editor.setEditorInput(new FileEditorInput(newDiFile)); + + } catch (ServiceException e) { + log.error(e); + } catch (IOException e) { + log.error(e); + } + } + } + }); + } + + // Then, remove the old model files + pm.subTask(Messages.RenameModelChange_RemoveOldFile); + for(IResource file : relatedFiles) { + if(file.exists()) { + file.delete(true, new NullProgressMonitor()); + } + } + pm.worked(4); + + if(isUndoOperation) { + newFile.move(oldFile.getFullPath(), true, new SubProgressMonitor(pm, 1)); + } + + return new RenameModelChange(newFile, oldFile); + } finally { + pm.done(); + } + } +} diff --git a/incoming/org.eclipse.papyrus.ui.resources/src/org/eclipse/papyrus/ui/resources/refactoring/RenameModelParticipant.java b/incoming/org.eclipse.papyrus.ui.resources/src/org/eclipse/papyrus/ui/resources/refactoring/RenameModelParticipant.java new file mode 100644 index 00000000000..8088879d721 --- /dev/null +++ b/incoming/org.eclipse.papyrus.ui.resources/src/org/eclipse/papyrus/ui/resources/refactoring/RenameModelParticipant.java @@ -0,0 +1,137 @@ +/***************************************************************************** + * Copyright (c) 2009 Atos Origin. + * + * + * 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: + * Thomas Szadel - Initial API and implementation + * + *****************************************************************************/ +package org.eclipse.papyrus.ui.resources.refactoring; + +import org.eclipse.core.resources.IContainer; +import org.eclipse.core.resources.IFile; +import org.eclipse.core.resources.IResource; +import org.eclipse.core.runtime.CoreException; +import org.eclipse.core.runtime.IPath; +import org.eclipse.core.runtime.IProgressMonitor; +import org.eclipse.core.runtime.OperationCanceledException; +import org.eclipse.ltk.core.refactoring.Change; +import org.eclipse.ltk.core.refactoring.RefactoringStatus; +import org.eclipse.ltk.core.refactoring.participants.CheckConditionsContext; +import org.eclipse.ltk.core.refactoring.participants.RenameParticipant; + +/** + * Participant that is aware of the renaming of a model. + * + * @author Thomas Szadel + * + */ +public class RenameModelParticipant extends RenameParticipant { + + private IFile fileToRename; + + private IFile newFile; + + /** + * @see org.eclipse.ltk.core.refactoring.participants.RefactoringParticipant#createPreChange(org.eclipse.core.runtime.IProgressMonitor) + * + * @param pm + * The progress monitor. + * @return The change. + * @throws CoreException + * @throws OperationCanceledException + */ + + @Override + public Change createPreChange(IProgressMonitor pm) throws CoreException, OperationCanceledException { + return new DirtyEditorChange(fileToRename, newFile); + } + + /** + * Overrides checkConditions. + * + * {@inheritDoc} + * + * @see org.eclipse.ltk.core.refactoring.participants.RefactoringParticipant#checkConditions(org.eclipse.core.runtime.IProgressMonitor, + * org.eclipse.ltk.core.refactoring.participants.CheckConditionsContext) + */ + @Override + public RefactoringStatus checkConditions(IProgressMonitor pm, CheckConditionsContext context) throws OperationCanceledException { + return new RefactoringStatus(); + } + + /** + * Overrides createChange. + * + * {@inheritDoc} + * + * @see org.eclipse.ltk.core.refactoring.participants.RefactoringParticipant#createChange(org.eclipse.core.runtime.IProgressMonitor) + */ + @Override + public Change createChange(IProgressMonitor pm) throws CoreException, OperationCanceledException { + return new RenameModelChange(fileToRename, newFile); + } + + /** + * Overrides getName. + * + * {@inheritDoc} + * + * @see org.eclipse.ltk.core.refactoring.participants.RefactoringParticipant#getName() + */ + @Override + public String getName() { + return "Papyrus Model Renaming"; + } + + /** + * Overrides initialize. + * + * {@inheritDoc} + * + * @see org.eclipse.ltk.core.refactoring.participants.RefactoringParticipant#initialize(java.lang.Object) + */ + @Override + protected boolean initialize(Object element) { + if(!(element instanceof IFile)) { + return false; + } + fileToRename = (IFile)element; + String ext = fileToRename.getFileExtension(); + + IContainer parent = fileToRename.getParent(); + String newName = getArguments().getNewName(); + int idx = newName.lastIndexOf('.'); + if(idx > 0) { + newName = newName.substring(0, idx); + } else { + newName = newName + '.' + ext; // Always append the extension + } + + boolean otherFiles = false; + for(IResource file : ModelParticipantHelpers.getRelatedFiles(fileToRename)) { + IPath path = file.getFullPath(); + // Only add the change if the resource exists + IFile renFile = parent.getFile(path.makeRelativeTo(parent.getFullPath())); + if(!path.equals(fileToRename.getFullPath()) && renFile.exists()) { + otherFiles = true; + break; + } + } + if(otherFiles) { + // Get the new file + IPath newDiPath = fileToRename.getFullPath().removeLastSegments(1); + newDiPath = newDiPath.append(newName).addFileExtension(ext); + newFile = parent.getFile(newDiPath.makeRelativeTo(parent.getFullPath())); + return true; + } else { + return false; + } + + } +} diff --git a/incoming/org.eclipse.papyrus.ui.resources/src/org/eclipse/papyrus/ui/resources/refactoring/messages.properties b/incoming/org.eclipse.papyrus.ui.resources/src/org/eclipse/papyrus/ui/resources/refactoring/messages.properties new file mode 100644 index 00000000000..9cb1039892d --- /dev/null +++ b/incoming/org.eclipse.papyrus.ui.resources/src/org/eclipse/papyrus/ui/resources/refactoring/messages.properties @@ -0,0 +1,11 @@ +MoveModelParticipant_Name=Papyrus Model Move +RenameModelChange_6=Changing URI {0} into {1} +RenameModelChange_Change=Rename {0} to {1} +RenameModelChange_DaveDirtyEditor=Saving dirty editors +RenameModelChange_ErrorLoading=Error while loading resource {0} +RenameModelChange_LoadingEMF=Loading EMF model into memory +RenameModelChange_ModifyURI=Modifying resources' URI +RenameModelChange_Name=Update all resources related to {0} +RenameModelChange_RemoveOldFile=Removing old files +RenameModelChange_savingResource=Saving resources +RenameModelChange_Unloading=Unloading model -- cgit v1.2.3