initial commit
diff --git a/org.eclipse.emf.refactor.refactoring.runtime/.classpath b/org.eclipse.emf.refactor.refactoring.runtime/.classpath new file mode 100644 index 0000000..ad32c83 --- /dev/null +++ b/org.eclipse.emf.refactor.refactoring.runtime/.classpath
@@ -0,0 +1,7 @@ +<?xml version="1.0" encoding="UTF-8"?> +<classpath> + <classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/JavaSE-1.6"/> + <classpathentry kind="con" path="org.eclipse.pde.core.requiredPlugins"/> + <classpathentry kind="src" path="src"/> + <classpathentry kind="output" path="bin"/> +</classpath>
diff --git a/org.eclipse.emf.refactor.refactoring.runtime/.project b/org.eclipse.emf.refactor.refactoring.runtime/.project new file mode 100644 index 0000000..6f9b974 --- /dev/null +++ b/org.eclipse.emf.refactor.refactoring.runtime/.project
@@ -0,0 +1,28 @@ +<?xml version="1.0" encoding="UTF-8"?> +<projectDescription> + <name>org.eclipse.emf.refactor.refactoring.runtime</name> + <comment></comment> + <projects> + </projects> + <buildSpec> + <buildCommand> + <name>org.eclipse.jdt.core.javabuilder</name> + <arguments> + </arguments> + </buildCommand> + <buildCommand> + <name>org.eclipse.pde.ManifestBuilder</name> + <arguments> + </arguments> + </buildCommand> + <buildCommand> + <name>org.eclipse.pde.SchemaBuilder</name> + <arguments> + </arguments> + </buildCommand> + </buildSpec> + <natures> + <nature>org.eclipse.pde.PluginNature</nature> + <nature>org.eclipse.jdt.core.javanature</nature> + </natures> +</projectDescription>
diff --git a/org.eclipse.emf.refactor.refactoring.runtime/.settings/org.eclipse.jdt.core.prefs b/org.eclipse.emf.refactor.refactoring.runtime/.settings/org.eclipse.jdt.core.prefs new file mode 100644 index 0000000..ec23e38 --- /dev/null +++ b/org.eclipse.emf.refactor.refactoring.runtime/.settings/org.eclipse.jdt.core.prefs
@@ -0,0 +1,8 @@ +#Thu Jul 01 19:59:32 CEST 2010 +eclipse.preferences.version=1 +org.eclipse.jdt.core.compiler.codegen.inlineJsrBytecode=enabled +org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.6 +org.eclipse.jdt.core.compiler.compliance=1.6 +org.eclipse.jdt.core.compiler.problem.assertIdentifier=error +org.eclipse.jdt.core.compiler.problem.enumIdentifier=error +org.eclipse.jdt.core.compiler.source=1.6
diff --git a/org.eclipse.emf.refactor.refactoring.runtime/META-INF/MANIFEST.MF b/org.eclipse.emf.refactor.refactoring.runtime/META-INF/MANIFEST.MF new file mode 100644 index 0000000..7975f77 --- /dev/null +++ b/org.eclipse.emf.refactor.refactoring.runtime/META-INF/MANIFEST.MF
@@ -0,0 +1,30 @@ +Manifest-Version: 1.0 +Bundle-ManifestVersion: 2 +Bundle-Name: RefactoringRuntime +Bundle-SymbolicName: org.eclipse.emf.refactor.refactoring.runtime;singleton:=true +Bundle-Version: 0.7.0.qualifier +Bundle-Activator: org.eclipse.emf.refactor.refactoring.runtime.Activator +Require-Bundle: org.eclipse.ui, + org.eclipse.core.resources;bundle-version="3.6.0", + org.eclipse.core.runtime, + org.eclipse.emf.compare;bundle-version="1.1.0", + org.eclipse.emf.compare.diff;bundle-version="1.1.0", + org.eclipse.emf.compare.match;bundle-version="1.1.0", + org.eclipse.emf.compare.ui;bundle-version="1.1.0", + org.eclipse.emf.ecore;bundle-version="2.6.0", + org.eclipse.emf.ecore.change;bundle-version="2.5.0", + org.eclipse.emf.ecore.xmi;bundle-version="2.5.0", + org.eclipse.emf.edit;bundle-version="2.6.0", + org.eclipse.emf.transaction;bundle-version="1.4.0", + org.eclipse.ltk.ui.refactoring;bundle-version="3.5.0", + org.eclipse.ltk.core.refactoring;bundle-version="3.5.100", + org.junit;bundle-version="4.8.1", + org.eclipse.emf.refactor.refactoring;bundle-version="0.7.0", + org.eclipse.emf.refactor.refactoring.configuration;bundle-version="0.7.0" +Bundle-ActivationPolicy: lazy +Bundle-RequiredExecutionEnvironment: JavaSE-1.6 +Import-Package: org.eclipse.ui +Export-Package: org.eclipse.emf.refactor.refactoring.runtime, + org.eclipse.emf.refactor.refactoring.runtime.ltk, + org.eclipse.emf.refactor.refactoring.runtime.ltk.ui, + org.eclipse.emf.refactor.refactoring.runtime.test
diff --git a/org.eclipse.emf.refactor.refactoring.runtime/build.properties b/org.eclipse.emf.refactor.refactoring.runtime/build.properties new file mode 100644 index 0000000..316d0b2 --- /dev/null +++ b/org.eclipse.emf.refactor.refactoring.runtime/build.properties
@@ -0,0 +1,7 @@ +source.. = src/ +output.. = bin/ +bin.includes = META-INF/,\ + .,\ + plugin.xml,\ + bin/,\ + src/
diff --git a/org.eclipse.emf.refactor.refactoring.runtime/plugin.xml b/org.eclipse.emf.refactor.refactoring.runtime/plugin.xml new file mode 100644 index 0000000..01af65f --- /dev/null +++ b/org.eclipse.emf.refactor.refactoring.runtime/plugin.xml
@@ -0,0 +1,19 @@ +<?xml version="1.0" encoding="UTF-8"?> +<?eclipse version="3.4"?> +<plugin> + <extension + point="org.eclipse.ui.menus"> + <menuContribution + allPopups="false" + locationURI="popup:org.eclipse.ui.popup.any"> + <menu + label="EMF Model Refactorings"> + <dynamic + class="org.eclipse.emf.refactor.refactoring.runtime.ui.ApplicationMenu" + id="org.eclipse.emf.refactor.runtime.dynamicmenu"> + </dynamic> + </menu> + </menuContribution> + </extension> + +</plugin>
diff --git a/org.eclipse.emf.refactor.refactoring.runtime/src/org/eclipse/emf/refactor/refactoring/runtime/Activator.java b/org.eclipse.emf.refactor.refactoring.runtime/src/org/eclipse/emf/refactor/refactoring/runtime/Activator.java new file mode 100644 index 0000000..ff4d5e2 --- /dev/null +++ b/org.eclipse.emf.refactor.refactoring.runtime/src/org/eclipse/emf/refactor/refactoring/runtime/Activator.java
@@ -0,0 +1,61 @@ +/******************************************************************************* + * Copyright (c) Philipps University of Marburg. 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: + * Philipps University of Marburg - initial API and implementation + *******************************************************************************/ +package org.eclipse.emf.refactor.refactoring.runtime; + +import org.eclipse.ui.plugin.AbstractUIPlugin; +import org.osgi.framework.BundleContext; + +/** + * Activator class of the org.eclipse.emf.refactor.runtime plugin. + * @generated + */ +public class Activator extends AbstractUIPlugin { + + /** + * @generated + */ + public static final String PLUGIN_ID = "org.eclipse.emf.refactor.runtime"; + + /** + * @generated + */ + private static Activator plugin; + + /** + * @generated + */ + public Activator() { + } + + /** + * @generated + */ + public void start(BundleContext context) throws Exception { + super.start(context); + plugin = this; + } + + /** + * @generated + */ + public void stop(BundleContext context) throws Exception { + plugin = null; + super.stop(context); + } + + /** + * @generated + */ + public static Activator getDefault() { + return plugin; + } + +}
diff --git a/org.eclipse.emf.refactor.refactoring.runtime/src/org/eclipse/emf/refactor/refactoring/runtime/DataManagementAdapter.java b/org.eclipse.emf.refactor.refactoring.runtime/src/org/eclipse/emf/refactor/refactoring/runtime/DataManagementAdapter.java new file mode 100644 index 0000000..e4f3100 --- /dev/null +++ b/org.eclipse.emf.refactor.refactoring.runtime/src/org/eclipse/emf/refactor/refactoring/runtime/DataManagementAdapter.java
@@ -0,0 +1,106 @@ +/******************************************************************************* + * Copyright (c) Philipps University of Marburg. 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: + * Philipps University of Marburg - initial API and implementation + *******************************************************************************/ +package org.eclipse.emf.refactor.refactoring.runtime; + +import java.util.Collections; +import java.util.HashSet; +import java.util.Set; + +import org.eclipse.emf.refactor.refactoring.core.Port; +import org.eclipse.emf.refactor.refactoring.interfaces.IDataManagement; + +/** + * Adapter class implementing interface IDataManagement used for + * EMF model refactorings. + * @generated NOT + * @author Florian Mantz + */ +public abstract class DataManagementAdapter implements IDataManagement { + + /** + * Set of EMF model refactoring input Ports. + */ + @SuppressWarnings("rawtypes") + protected Set<Port> inPorts = new HashSet<Port>(); + + /** + * Set of EMF model refactoring output Ports. + */ + @SuppressWarnings("rawtypes") + protected Set<Port> outPorts = new HashSet<Port>(); + + /** + * @see org.eclipse.emf.refactor.common.core.IDataManagement# + * getInPortByName(java.lang.String) + */ + @SuppressWarnings("rawtypes") + @Override + public Port getInPortByName(String name) { + return getPortByName(name,inPorts); + } + + /** + * @see org.eclipse.emf.refactor.common.core.IDataManagement# + * getOutPortByName(java.lang.String) + */ + @SuppressWarnings("rawtypes") + @Override + public Port getOutPortByName(String name) { + return getPortByName(name,outPorts); + } + + /** + * @see org.eclipse.emf.refactor.common.core.IDataManagement# + * getInPorts() + */ + @SuppressWarnings("rawtypes") + @Override + public Set<Port> getInPorts() { + return Collections.unmodifiableSet(inPorts); + } + + /** + * @see org.eclipse.emf.refactor.common.core.IDataManagement# + * getOutPorts() + */ + @SuppressWarnings("rawtypes") + @Override + public Set<Port> getOutPorts() { + return Collections.unmodifiableSet(outPorts); + } + + /** + * @see org.eclipse.emf.refactor.common.core.IDataManagement# + * initOutPorts() + */ + @Override + public void initOutPorts() { + System.err.println("No Outports are provided!"); + } + + /** + * Gets the port with the given name from the given list of ports. + * @param name Name of the port to be returned. + * @param ports List of ports. + * @return Port with the given name from the given list of ports. + */ + @SuppressWarnings("rawtypes") + private Port getPortByName(String name, Set<Port> ports) { + for(Port p:ports){ + if(p.getName().equals(name)){ + return p; + } + } + throw new IllegalArgumentException + ("Port with name '" + name + "' does not exits!"); + } + +}
diff --git a/org.eclipse.emf.refactor.refactoring.runtime/src/org/eclipse/emf/refactor/refactoring/runtime/config/RuntimeConfig.java b/org.eclipse.emf.refactor.refactoring.runtime/src/org/eclipse/emf/refactor/refactoring/runtime/config/RuntimeConfig.java new file mode 100644 index 0000000..2a59f84 --- /dev/null +++ b/org.eclipse.emf.refactor.refactoring.runtime/src/org/eclipse/emf/refactor/refactoring/runtime/config/RuntimeConfig.java
@@ -0,0 +1,141 @@ +/******************************************************************************* + * Copyright (c) Philipps University of Marburg. 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: + * Philipps University of Marburg - initial API and implementation + *******************************************************************************/ +package org.eclipse.emf.refactor.refactoring.runtime.config; + +import org.eclipse.core.resources.IProject; +import org.eclipse.ui.IEditorInput; +import org.eclipse.ui.IEditorPart; +import org.eclipse.ui.IFileEditorInput; +import org.eclipse.ui.IWorkbenchWindow; +import org.eclipse.ui.PlatformUI; + +/** + * Configuration class of the runtime module of EMF Refactor. + * @generated NOT + * @author Thorsten Arendt + */ +public class RuntimeConfig { + + /** + * Flag for supporting EMF model refactoring on GMF generated + * graphical editors. Default = true. + * TODO Configurable in Settings: + */ + private boolean supportGmfDiagramEditors = true; + + /** + * Flag for indicating whether the namespaceUri of the model + * has to be checked against the namespaceUri of the EMF model + * refactoring. Default = true. + * TODO Configurable in Settings: + */ + private boolean checkEmfVersion = true; + + /** + * Returns whether the namespaceUri of the model has to be checked + * against the namespaceUri of the EMF model refactoring. + * @return true if the namespaceUri of the model has to be checked + * against the namespaceUri of the EMF model refactoring, false + * otherwise. + */ + public boolean isCheckEmfVersion() { + return checkEmfVersion; + } + + /** + * Sets whether the namespaceUri of the model has to be checked + * against the namespaceUri of the EMF model refactoring. + * @param checkEmfVersion Flag for indicating whether the namespaceUri + * of the model has to be checked against the namespaceUri of the EMF + * model refactoring. + */ + public void setCheckEmfVersion(boolean checkEmfVersion) { + this.checkEmfVersion = checkEmfVersion; + } + + /** + * Returns whether GMF generated graphical editors are supported + * by EMF model refactorings. + * @return true if GMF generated graphical editors are supported, + * false otherwise. + */ + public boolean isSupportGmfDiagramEditors() { + return supportGmfDiagramEditors; + } + + /** + * Sets whether GMF generated graphical editors shall be supported + * by EMF model refactorings. + * @param supportUML2Tools Flag for supporting EMF model refactorings + * on GMF generated graphical editors. + */ + public void setSupportGmfDiagramEditors(boolean supportUML2Tools) { + this.supportGmfDiagramEditors = supportUML2Tools; + } + + /** + * Static method that returns the project in the workspace + * according to the actual editor in the workbench. + * @return Project in the workspace according to the actual + * editor in the workbench. + */ + @SuppressWarnings("finally") + public static IProject getActualProject(){ + IProject actualProject = null; + IWorkbenchWindow window = + PlatformUI.getWorkbench().getActiveWorkbenchWindow(); + try { + IEditorPart editorPart = window.getActivePage().getActiveEditor(); + if ( editorPart != null ) { + IEditorInput input = editorPart.getEditorInput(); + if (input instanceof IFileEditorInput) { + IFileEditorInput fileInput = (IFileEditorInput) input; + actualProject = fileInput.getFile().getProject(); + } + } + } catch (Exception e) { + e.printStackTrace(); + } finally { + return actualProject; + } + } + + /** + * Checks whether the given class has the given name or whether one + * of its interfaces has the given name. This method is expensive! + * Do not use it to often! + * @param cl Class to be checked. + * @param iname Name to be checked. + * @param isInterface Flag that indicates that the given name is a + * name of an interface. + * @return true if the given class has the given name or if one + * of its interfaces has the given name, false otherwise. + */ + public static boolean checkIsTypeOf + (Class<?> cl, String iname, boolean isInterface){ + Class<?> superclass = null; + if(cl.getName().equals(iname)){ + return true; + }else if(isInterface){ + for(Class<?> c:cl.getInterfaces()){ + if(checkIsTypeOf(c, iname, isInterface)){ + return true; + } + } + } + if(null != (superclass = cl.getSuperclass())){ + return checkIsTypeOf(superclass, iname, isInterface); + }else{ + return false; + } + } + +}
diff --git a/org.eclipse.emf.refactor.refactoring.runtime/src/org/eclipse/emf/refactor/refactoring/runtime/ltk/LtkEmfRefactoringProcessorAdapter.java b/org.eclipse.emf.refactor.refactoring.runtime/src/org/eclipse/emf/refactor/refactoring/runtime/ltk/LtkEmfRefactoringProcessorAdapter.java new file mode 100644 index 0000000..c0a6baf --- /dev/null +++ b/org.eclipse.emf.refactor.refactoring.runtime/src/org/eclipse/emf/refactor/refactoring/runtime/ltk/LtkEmfRefactoringProcessorAdapter.java
@@ -0,0 +1,296 @@ +/******************************************************************************* + * Copyright (c) Philipps University of Marburg. 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: + * Philipps University of Marburg - initial API and implementation + *******************************************************************************/ +package org.eclipse.emf.refactor.refactoring.runtime.ltk; + +import java.util.List; + +import org.eclipse.core.runtime.CoreException; +import org.eclipse.core.runtime.IProgressMonitor; +import org.eclipse.core.runtime.NullProgressMonitor; +import org.eclipse.core.runtime.OperationCanceledException; +import org.eclipse.emf.ecore.EObject; +import org.eclipse.emf.ecore.change.ChangeDescription; +import org.eclipse.emf.ecore.resource.ResourceSet; +import org.eclipse.emf.ecore.util.EcoreUtil; +import org.eclipse.emf.edit.domain.AdapterFactoryEditingDomain; +import org.eclipse.emf.edit.domain.EditingDomain; +import org.eclipse.emf.refactor.refactoring.core.Refactoring; +import org.eclipse.emf.refactor.refactoring.managers.RefactoringManager; +import org.eclipse.emf.refactor.refactoring.runtime.ltk.change.RefactoringChange; +import org.eclipse.emf.transaction.TransactionalEditingDomain; +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.RefactoringParticipant; +import org.eclipse.ltk.core.refactoring.participants.RefactoringProcessor; +import org.eclipse.ltk.core.refactoring.participants.SharableParticipants; + +/** + * Adapter class of a LTK RefactoringProcessor used for + * EMF model refactorings. + * @generated NOT + * @author Florian Mantz + */ +public class LtkEmfRefactoringProcessorAdapter + extends RefactoringProcessor { + + /** + * Id of the RefactoringProcessor. + */ + protected final String id; + + /** + * Runnable that executes the model refactoring. + */ + protected final Runnable refactoringAction; + + /** + * ChangeDescription object for model refactoring execution. + */ + protected final ChangeDescription changeDescription; + + /** + * Given selection objects the model refactoring shall + * be executed on. + */ + protected final List<EObject> selection; + + /** + * Root object of the EMF model. + */ + protected final EObject root; + + /** + * EditingDomain object of the EMF model. + */ + protected final EditingDomain editingDomain; + + /** + * Private constructor used by other constructors. + * @param refactoring EMF Model Refactoring to be executed. + * @param selection Given selection objects the model refactoring + * shall be executed on. + * @param refactoringAction Runnable that executes the model refactoring. + * @param changeDescription ChangeDescription object for model + * refactoring execution. + */ + private LtkEmfRefactoringProcessorAdapter + (Refactoring refactoring, List<EObject> selection, + Runnable refactoringAction, ChangeDescription changeDescription){ + this.id = (null!=refactoring)?refactoring.getId():null; + this.selection=selection; + this.root = EcoreUtil.getRootContainer(selection.get(0)); + this.editingDomain = initEditingDomain(selection); + this.refactoringAction = refactoringAction; + this.changeDescription = changeDescription; + if (null == this.selection || null == this.root + || null == this.editingDomain){ + throw new RuntimeException + ("RefactoringProcessor could not be created!"); + } + } + + /** + * Constructor using a Runnable that executes the model refactoring. + * @param refactoring EMF Model Refactoring to be executed. + * @param selection Given selection objects the model refactoring + * shall be executed on. + * @param refactoringAction Runnable that executes the model refactoring. + */ + protected LtkEmfRefactoringProcessorAdapter(Refactoring refactoring, + List<EObject> selection, Runnable refactoringAction){ + this(refactoring,selection,refactoringAction,null); + } + + + /** + * Constructor using a ChangeDescription object for model + * refactoring execution. + * @param refactoring EMF Model Refactoring to be executed. + * @param selection Given selection objects the model refactoring + * shall be executed on. + * @param changeDescription ChangeDescription object for model + * refactoring execution. + */ + protected LtkEmfRefactoringProcessorAdapter(Refactoring refactoring, + List<EObject> selection, ChangeDescription changeDescription){ + this(refactoring,selection,null,changeDescription); + } + + /** + * Static method that returns the EditingDomain of a given selection + * of EObjects. + * @param selection Given selection objects the model refactoring shall + * be executed on. + * @return EditingDomain of a given selection of EObjects. + */ + private static EditingDomain initEditingDomain(List<EObject> selection) { + if(null != selection && !selection.isEmpty()){ + EditingDomain editingDomain = + AdapterFactoryEditingDomain + .getEditingDomainFor(selection.get(0)); + if (null == editingDomain){ + ResourceSet rset = + selection.get(0).eResource().getResourceSet(); + editingDomain = TransactionalEditingDomain.Factory.INSTANCE + .getEditingDomain(rset); + } + if (null == editingDomain) { + ResourceSet rset = + selection.get(0).eResource().getResourceSet(); + editingDomain = TransactionalEditingDomain.Factory.INSTANCE + .createEditingDomain(rset); + } + return editingDomain; + } + throw new RuntimeException("EditingDomain could not be initialized!"); + } + + /** + * @see org.eclipse.ltk.core.refactoring.participants.RefactoringProcessor# + * getElements() + */ + @Override + public Object[] getElements() { + return this.selection.toArray(); + } + + /** + * @see org.eclipse.ltk.core.refactoring.participants.RefactoringProcessor# + * getIdentifier() + */ + @Override + public String getIdentifier() { + return getClass().getName(); + } + + /** + * @see org.eclipse.ltk.core.refactoring.participants.RefactoringProcessor# + * getProcessorName() + */ + @Override + public String getProcessorName() { + if (null == id) return "testCase"; + return RefactoringManager.getById(id).getName(); + } + + /** + * @see org.eclipse.ltk.core.refactoring.participants.RefactoringProcessor# + * isApplicable() + */ + @Override + public boolean isApplicable() throws CoreException { + return true; + } + + /** + * @see org.eclipse.ltk.core.refactoring.participants.RefactoringProcessor# + * checkInitialConditions(org.eclipse.core.runtime.IProgressMonitor) + */ + @Override + public RefactoringStatus checkInitialConditions(IProgressMonitor pm) + throws CoreException, OperationCanceledException { + return checkInitialConditions(); + } + + /** + * @see org.eclipse.ltk.core.refactoring.participants.RefactoringProcessor# + * checkInitialConditions(org.eclipse.core.runtime.IProgressMonitor) + */ + public RefactoringStatus checkInitialConditions() { + RefactoringStatus result = new RefactoringStatus(); + return result; + } + + /** + * @see org.eclipse.ltk.core.refactoring.participants.RefactoringProcessor# + * checkFinalConditions(org.eclipse.core.runtime.IProgressMonitor, + * org.eclipse.ltk.core.refactoring.participants.CheckConditionsContext) + */ + @Override + public RefactoringStatus checkFinalConditions(IProgressMonitor pm, + CheckConditionsContext context) throws CoreException, + OperationCanceledException { + return checkFinalConditions(); + } + + /** + * @see org.eclipse.ltk.core.refactoring.participants.RefactoringProcessor# + * checkFinalConditions(org.eclipse.core.runtime.IProgressMonitor, + * org.eclipse.ltk.core.refactoring.participants.CheckConditionsContext) + */ + public RefactoringStatus checkFinalConditions() { + RefactoringStatus result = new RefactoringStatus(); + return result; + } + + /** + * @see org.eclipse.ltk.core.refactoring.participants.RefactoringProcessor# + * createChange(org.eclipse.core.runtime.IProgressMonitor) + */ + @Override + public Change createChange(IProgressMonitor pm) throws CoreException, + OperationCanceledException { + return createChange(true); + } + + /** + * Creates a RefactoringChange object either with a Runnable object + * or a ChangeDescription object for executing a EMF model refactoring. + * @param enableChangeRecoder Flag whether the model refactoring + * execution shall be recorded. + * @return RefactoringChange object for executing a EMF model refactoring. + */ + private Change createChange(boolean enableChangeRecoder) { + RefactoringChange refactoringChange = null; + if (null != this.changeDescription){ + refactoringChange = + new RefactoringChange(this.getProcessorName(), this.root, + this.editingDomain, this.changeDescription, null, false); + } else { + refactoringChange = + new RefactoringChange(this.getProcessorName(), this.root, + this.editingDomain, null, this.refactoringAction, + enableChangeRecoder); + } + return refactoringChange; + } + + /** + * @see org.eclipse.ltk.core.refactoring.participants.RefactoringProcessor# + * loadParticipants(org.eclipse.ltk.core.refactoring.RefactoringStatus, + * org.eclipse.ltk.core.refactoring.participants.SharableParticipants) + */ + @Override + public RefactoringParticipant[] loadParticipants(RefactoringStatus status, + SharableParticipants sharedParticipants) throws CoreException { + return new RefactoringParticipant[0]; + } + + /** + * Method to invoke a model refactoring without recording its execution. + * @throws OperationCanceledException + * @throws CoreException + */ + public void runWithoutChangeRecorder() + throws OperationCanceledException, CoreException{ + createChange(false).perform(new NullProgressMonitor()); + } + + /** + * Checks the initial and final conditions of the refactoring. + * @return true if initial and final check do not return errors, false otherwise + */ + public boolean checkConditions(){ + return (checkInitialConditions().isOK() && checkFinalConditions().isOK()); + } + +}
diff --git a/org.eclipse.emf.refactor.refactoring.runtime/src/org/eclipse/emf/refactor/refactoring/runtime/ltk/change/RefactoringChange.java b/org.eclipse.emf.refactor.refactoring.runtime/src/org/eclipse/emf/refactor/refactoring/runtime/ltk/change/RefactoringChange.java new file mode 100644 index 0000000..f2b08b9 --- /dev/null +++ b/org.eclipse.emf.refactor.refactoring.runtime/src/org/eclipse/emf/refactor/refactoring/runtime/ltk/change/RefactoringChange.java
@@ -0,0 +1,165 @@ +/******************************************************************************* + * Copyright (c) Philipps University of Marburg. 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: + * Philipps University of Marburg - initial API and implementation + *******************************************************************************/ +package org.eclipse.emf.refactor.refactoring.runtime.ltk.change; + +import java.util.HashMap; +import java.util.Map; + +import org.eclipse.core.runtime.CoreException; +import org.eclipse.core.runtime.IProgressMonitor; +import org.eclipse.core.runtime.OperationCanceledException; +import org.eclipse.emf.compare.diff.metamodel.DiffModel; +import org.eclipse.emf.compare.diff.service.DiffService; +import org.eclipse.emf.compare.match.MatchOptions; +import org.eclipse.emf.compare.match.metamodel.MatchModel; +import org.eclipse.emf.compare.match.service.MatchService; +import org.eclipse.emf.compare.ui.IModelCompareInputProvider; +import org.eclipse.emf.compare.ui.ModelCompareInput; +import org.eclipse.emf.ecore.EObject; +import org.eclipse.emf.ecore.change.ChangeDescription; +import org.eclipse.emf.edit.domain.EditingDomain; +import org.eclipse.emf.refactor.refactoring.runtime.ltk.command.PreviewCommand; +import org.eclipse.emf.refactor.refactoring.runtime.ltk.command.RefactoringCommand; +import org.eclipse.ltk.core.refactoring.Change; +import org.eclipse.ltk.core.refactoring.RefactoringStatus; + +/** + * Class used for providing a LTK Change concerning the execution + * of a specific EMF model refactoring. + * @generated NOT + * @author Thorsten Arendt + */ +public class RefactoringChange extends Change + implements IModelCompareInputProvider{ + + /** + * Name of the RefactoringChange. + */ + private final String name; + + /** + * Root object of the EMF model. + */ + private final EObject root; + + /** + * EditingDomain object of the EMF model. + */ + private final EditingDomain editingDomain; + + /** + * Command that executes the EMF model refactoring. + */ + private final RefactoringCommand refactoringCommand; + + /** + * Default constructor. + * @param name Name of the RefactoringChange. + * @param root Root object of the EMF model. + * @param editingDomain EditingDomain object of the EMF model. + * @param changeDescription ChangeDescription object for model + * refactoring execution. + * @param refactoringToApply Runnable object for model refactoring + * execution. + * @param enableChangeRecorder Flag whether the model refactoring + * execution shall be recorded. + */ + public RefactoringChange(String name, EObject root, + EditingDomain editingDomain, ChangeDescription changeDescription, + Runnable refactoringToApply, boolean enableChangeRecorder) { + super(); + this.name = name; + this.root = root; + this.editingDomain=editingDomain; + if(null != changeDescription){ + refactoringCommand = new RefactoringCommand(name,changeDescription); + }else{ + refactoringCommand = new RefactoringCommand + (name, refactoringToApply, this.root, enableChangeRecorder); + } + } + + /** + * @see org.eclipse.ltk.core.refactoring.Change#getName() + */ + @Override + public String getName() { + return this.name; + } + + /** + * @see org.eclipse.ltk.core.refactoring.Change# + * initializeValidationData(org.eclipse.core.runtime.IProgressMonitor) + */ + @Override + public void initializeValidationData(IProgressMonitor pm) { + // do nothing + } + + /** + * @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(); + } + + /** + * @see org.eclipse.ltk.core.refactoring.Change# + * perform(org.eclipse.core.runtime.IProgressMonitor) + */ + @Override + public Change perform(IProgressMonitor pm) throws CoreException { + this.editingDomain.getCommandStack().execute(refactoringCommand); + return + new UndoRedoChange(refactoringCommand, editingDomain, name, root); + } + + /** + * @see org.eclipse.ltk.core.refactoring.Change#getModifiedElement() + */ + @Override + public Object getModifiedElement() { + return this.root; + } + + /** + * @see org.eclipse.emf.compare.ui.IModelCompareInputProvider# + * getModelCompareInput() + */ + @Override + public ModelCompareInput getModelCompareInput() { + try { + //Perform Refactoring + PreviewCommand previewCommand = + new PreviewCommand(refactoringCommand,this.root); + this.editingDomain.getCommandStack().execute(previewCommand); + //Generate DiffModel: + Map<String, Object> options = new HashMap<String, Object>(); + options.put(MatchOptions.OPTION_IGNORE_XMI_ID, new Boolean(true)); + MatchModel matchModel = null; + try { + matchModel = MatchService.doMatch(this.root, + previewCommand.getRootCopy(), options); + DiffModel diffModel = DiffService.doDiff(matchModel); + return new ModelCompareInput(matchModel, diffModel); + } catch (InterruptedException e) { + e.printStackTrace(); + } + } catch (Exception e) { + e.printStackTrace(); + } + throw new RuntimeException("Could not generate DiffModel"); + } + +}
diff --git a/org.eclipse.emf.refactor.refactoring.runtime/src/org/eclipse/emf/refactor/refactoring/runtime/ltk/change/UndoRedoChange.java b/org.eclipse.emf.refactor.refactoring.runtime/src/org/eclipse/emf/refactor/refactoring/runtime/ltk/change/UndoRedoChange.java new file mode 100644 index 0000000..72a82bf --- /dev/null +++ b/org.eclipse.emf.refactor.refactoring.runtime/src/org/eclipse/emf/refactor/refactoring/runtime/ltk/change/UndoRedoChange.java
@@ -0,0 +1,111 @@ +/******************************************************************************* + * Copyright (c) Philipps University of Marburg. 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: + * Philipps University of Marburg - initial API and implementation + *******************************************************************************/ +package org.eclipse.emf.refactor.refactoring.runtime.ltk.change; + +import org.eclipse.core.runtime.CoreException; +import org.eclipse.core.runtime.IProgressMonitor; +import org.eclipse.core.runtime.OperationCanceledException; +import org.eclipse.emf.ecore.EObject; +import org.eclipse.emf.edit.domain.EditingDomain; +import org.eclipse.emf.refactor.refactoring.runtime.ltk.command.RefactoringCommand; +import org.eclipse.ltk.core.refactoring.Change; +import org.eclipse.ltk.core.refactoring.RefactoringStatus; + +/** + * Class used for providing a LTK Change concerning redo + * and undo functionality. + * @generated NOT + * @author Florian Mantz + */ +public class UndoRedoChange extends Change { + + /** + * Command from which the Change has been invoked. + */ + final RefactoringCommand command; + + /** + * EditingDomain object of the EMF model. + */ + final EditingDomain editingDomain; + + /** + * Name of the UndoRedoChange. + */ + final String name; + + /** + * Root object of the EMF model. + */ + final EObject root; + + /** + * Default constructor. + * @param command Command from which the Change has been invoked. + * @param editingDomain EditingDomain object of the EMF model. + * @param name Name of the UndoRedoChange. + * @param root Root object of the EMF model. + */ + public UndoRedoChange(RefactoringCommand command, + EditingDomain editingDomain, String name, EObject root) { + super(); + this.command = command; + this.editingDomain = editingDomain; + this.name = name; + this.root = root; + } + + /** + * @see org.eclipse.ltk.core.refactoring.Change#getName() + */ + @Override + public String getName() { + return name; + } + + /** + * @see org.eclipse.ltk.core.refactoring.Change# + * initializeValidationData(org.eclipse.core.runtime.IProgressMonitor) + */ + @Override + public void initializeValidationData(IProgressMonitor pm) { + // do nothing + } + + /** + * @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(); + } + + /** + * @see org.eclipse.ltk.core.refactoring.Change# + * perform(org.eclipse.core.runtime.IProgressMonitor) + */ + @Override + public Change perform(IProgressMonitor pm) throws CoreException { + editingDomain.getCommandStack().execute(command); + return new UndoRedoChange(command, editingDomain, name, root); + } + + /** + * @see org.eclipse.ltk.core.refactoring.Change#getModifiedElement() + */ + @Override + public Object getModifiedElement() { + return root; + } + +}
diff --git a/org.eclipse.emf.refactor.refactoring.runtime/src/org/eclipse/emf/refactor/refactoring/runtime/ltk/command/PreviewCommand.java b/org.eclipse.emf.refactor.refactoring.runtime/src/org/eclipse/emf/refactor/refactoring/runtime/ltk/command/PreviewCommand.java new file mode 100644 index 0000000..8d2e3e3 --- /dev/null +++ b/org.eclipse.emf.refactor.refactoring.runtime/src/org/eclipse/emf/refactor/refactoring/runtime/ltk/command/PreviewCommand.java
@@ -0,0 +1,113 @@ +/******************************************************************************* + * Copyright (c) Philipps University of Marburg. 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: + * Philipps University of Marburg - initial API and implementation + *******************************************************************************/ +package org.eclipse.emf.refactor.refactoring.runtime.ltk.command; + +import org.eclipse.emf.common.command.AbstractCommand; +import org.eclipse.emf.common.util.URI; +import org.eclipse.emf.compare.util.ModelUtils; +import org.eclipse.emf.ecore.EObject; +import org.eclipse.emf.ecore.util.EcoreUtil.Copier; + +/** + * Class used for providing a command that provides + * a preview of the rfactored EMF model. + * @generated NOT + * @author Florian Mantz + */ +public class PreviewCommand extends AbstractCommand { + + /** + * Command that was the origin of the PreviewCommand. + */ + final RefactoringCommand command; + + /** + * Root element of the EMF model. + */ + private final EObject root; + + /** + * Copy of the root element of the model (temporary model). + */ + private EObject rootCopy; + + /** + * Default constructor using the origin RefactoringCommand and + * the root of the EMF model. + * @param command Origin RefactoringCommand. + * @param root Root element of the EMF model. + */ + public PreviewCommand(RefactoringCommand command, EObject root) { + super(); + this.command = command; + this.root = root; + } + + /** + * @see org.eclipse.emf.common.command.Command#execute() + */ + @Override + public void execute() { + this.command.execute(); + rootCopy = this.generateRootCopy(); + this.command.undo(); + } + + /** + * Generates a copy of the EMF model presented by the root + * element. + * @return Copy of the EMF model presented by the root + * element. + */ + private EObject generateRootCopy() { + Copier copier = new Copier(); + EObject rootCopy = copier.copy(this.root); + copier.copyReferences(); + URI rootUri = this.root.eResource().getURI(); + URI rootCopyUri = + URI.createURI(rootUri + "-tmp." + rootUri.fileExtension()); + ModelUtils.attachResource(rootCopyUri, rootCopy); + return rootCopy; + } + + /** + * @see org.eclipse.emf.common.command.Command#redo() + */ + @Override + public void redo() { + //do nothing + } + + /** + * @see org.eclipse.emf.common.command.AbstractCommand#canExecute() + */ + @Override + public boolean canExecute() { + return true; + } + + /** + * @see org.eclipse.emf.common.command.AbstractCommand#canUndo() + */ + @Override + public boolean canUndo() { + return false; //Important + } + + /** + * Gets a copy of the root element of the model (temporary model). + * @return Copy of the root element of the model (temporary model). + */ + public EObject getRootCopy() { + return rootCopy; + } + +}
diff --git a/org.eclipse.emf.refactor.refactoring.runtime/src/org/eclipse/emf/refactor/refactoring/runtime/ltk/command/RefactoringCommand.java b/org.eclipse.emf.refactor.refactoring.runtime/src/org/eclipse/emf/refactor/refactoring/runtime/ltk/command/RefactoringCommand.java new file mode 100644 index 0000000..aea4525 --- /dev/null +++ b/org.eclipse.emf.refactor.refactoring.runtime/src/org/eclipse/emf/refactor/refactoring/runtime/ltk/command/RefactoringCommand.java
@@ -0,0 +1,142 @@ +/******************************************************************************* + * Copyright (c) Philipps University of Marburg. 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: + * Philipps University of Marburg - initial API and implementation + *******************************************************************************/ +package org.eclipse.emf.refactor.refactoring.runtime.ltk.command; + +import org.eclipse.emf.common.command.AbstractCommand; +import org.eclipse.emf.ecore.EObject; +import org.eclipse.emf.ecore.change.ChangeDescription; +import org.eclipse.emf.ecore.change.util.ChangeRecorder; + +/** + * Class used for providing a command that executes + * a EMF model refactoring. + * @generated NOT + * @author Florian Mantz + */ +public class RefactoringCommand extends AbstractCommand { + + /** + * Root of the corresponding EMF model. + */ + private final EObject rootObject; + + /** + * Runnable that executes the model refactoring. + */ + private final Runnable refactoringToExecute; + + /** + * Flag that indicated whether the model refactoring + * execution shall be recorded. + */ + private final boolean enableChangeRecorder; + + /** + * Change description object for executing the model + * refactoring. If this object is not available before + * refactoring execution it will be get by recording + * the refactoring execution. + */ + private ChangeDescription changeDescription; + + /** + * Contructor creating a command using a Runnable object + * for model refactoring execution. + * @param name Name of the command. + * @param executeRefactoring Runnable object for model refactoring + * execution. + * @param rootObject Root of the corresponding emf model. + * @param enableChangeRecorder Flag whether the model refactoring + * execution shall be recorded. + */ + public RefactoringCommand(String name, Runnable executeRefactoring, + EObject rootObject, boolean enableChangeRecorder) { + super(name); + this.refactoringToExecute=executeRefactoring; + this.rootObject=rootObject; + this.enableChangeRecorder=enableChangeRecorder; + if(enableChangeRecorder && null == this.rootObject){ + throw new IllegalArgumentException + ("ChangeRecorder is enabled and rootObject is null!"); + } + } + + /** + * Constructor creating a command using a ChangeDescription object + * for model refactoring execution. + * @param name Name of the command. + * @param description ChangeDescription object for model refactoring + * execution. + */ + public RefactoringCommand(String name, ChangeDescription description) { + super(name); + this.changeDescription = description; + this.refactoringToExecute=null; + this.rootObject=null; + this.enableChangeRecorder=false; + } + + /** + * @see org.eclipse.emf.common.command.Command#execute() + */ + @Override + public void execute() { + if(null != this.changeDescription){ + this.changeDescription.applyAndReverse(); + }else{ + try { + ChangeRecorder changeRecorder = null; + if(enableChangeRecorder){ + changeRecorder = new ChangeRecorder(rootObject); + } + this.refactoringToExecute.run(); + if(enableChangeRecorder){ + this.changeDescription = changeRecorder.endRecording(); + } + } catch (Exception e) { + e.printStackTrace(); + } + } + } + + /** + * @see org.eclipse.emf.common.command.Command#redo() + */ + @Override + public void redo() { + this.changeDescription.applyAndReverse(); + } + + /** + * @see org.eclipse.emf.common.command.AbstractCommand#undo() + */ + @Override + public void undo() { + this.changeDescription.applyAndReverse(); + } + + /** + * @see org.eclipse.emf.common.command.AbstractCommand#canExecute() + */ + @Override + public boolean canExecute() { + return true; + } + + /** + * @see org.eclipse.emf.common.command.AbstractCommand#canUndo() + */ + @Override + public boolean canUndo() { + return null != this.changeDescription; + } + +}
diff --git a/org.eclipse.emf.refactor.refactoring.runtime/src/org/eclipse/emf/refactor/refactoring/runtime/ltk/ui/AbstractRefactoringWizard.java b/org.eclipse.emf.refactor.refactoring.runtime/src/org/eclipse/emf/refactor/refactoring/runtime/ltk/ui/AbstractRefactoringWizard.java new file mode 100644 index 0000000..8c90710 --- /dev/null +++ b/org.eclipse.emf.refactor.refactoring.runtime/src/org/eclipse/emf/refactor/refactoring/runtime/ltk/ui/AbstractRefactoringWizard.java
@@ -0,0 +1,41 @@ +/******************************************************************************* + * Copyright (c) Philipps University of Marburg. 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: + * Philipps University of Marburg - initial API and implementation + *******************************************************************************/ +package org.eclipse.emf.refactor.refactoring.runtime.ltk.ui; + +import org.eclipse.emf.refactor.refactoring.interfaces.IController; +import org.eclipse.ltk.core.refactoring.participants.ProcessorBasedRefactoring; +import org.eclipse.ltk.ui.refactoring.RefactoringWizard; + +/** + * Abstract class used for providing an implementation of an LTK + * RefactoringWizard in EMF Refactor. + * @generated NOT + * @author Florian Mantz + */ +public abstract class AbstractRefactoringWizard extends RefactoringWizard { + + /** + * Controller of the corresponding EMF model refactoring. + */ + protected final IController controller; + + /** + * Default constructor implementation. + * @param controller Controller of the EMF model refactoring. + */ + public AbstractRefactoringWizard(IController controller) { + super(new ProcessorBasedRefactoring + (controller.getLtkRefactoringProcessor()), + DIALOG_BASED_USER_INTERFACE); + this.controller = controller; + } + +}
diff --git a/org.eclipse.emf.refactor.refactoring.runtime/src/org/eclipse/emf/refactor/refactoring/runtime/test/EmfTestRefactoringCommand.java b/org.eclipse.emf.refactor.refactoring.runtime/src/org/eclipse/emf/refactor/refactoring/runtime/test/EmfTestRefactoringCommand.java new file mode 100644 index 0000000..071ecf6 --- /dev/null +++ b/org.eclipse.emf.refactor.refactoring.runtime/src/org/eclipse/emf/refactor/refactoring/runtime/test/EmfTestRefactoringCommand.java
@@ -0,0 +1,114 @@ +/******************************************************************************* + * Copyright (c) Philipps University of Marburg. 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: + * Philipps University of Marburg - initial API and implementation + *******************************************************************************/ +package org.eclipse.emf.refactor.refactoring.runtime.test; + +import org.eclipse.core.runtime.NullProgressMonitor; +import org.eclipse.emf.common.command.AbstractCommand; +import org.eclipse.emf.ecore.EObject; +import org.eclipse.emf.refactor.refactoring.runtime.ltk.LtkEmfRefactoringProcessorAdapter; +import org.eclipse.ltk.core.refactoring.participants.RefactoringProcessor; + +/** + * Class used for providing a command that tests an EMF model refactoring. + * @generated NOT + * @author Thorsten Arendt + */ +public class EmfTestRefactoringCommand extends AbstractCommand { + + /** + * Root of the corresponding EMF model. + */ + private final EObject root; + + /** + * RefactoringProcessor to be used by the command. + */ + private final LtkEmfRefactoringProcessorAdapter processor; + + /** + * Constructor. + * @param name Name of the refactoring to run. + * @param newProcessor RefactoringProcessor to be used by the command. + * @param rootObject Root EObject to run the refactoring on. + */ + public EmfTestRefactoringCommand( + final String name, + final RefactoringProcessor newProcessor, + final EObject rootObject) { + super(name); + this.root = rootObject; + this.processor = + (LtkEmfRefactoringProcessorAdapter) newProcessor; + } + + /** + * @see org.eclipse.emf.common.command.Command#execute() + */ + @Override + public final void execute() { + try { + // check whether all conditions are met + if (this.processor.checkConditions()) { + // apply refactoring + this + .processor + .createChange(new NullProgressMonitor()) + .perform(new NullProgressMonitor()); + } else { + // TODO real error handling that gets displayed + System.out.println("Checks failed"); + } + } catch (Exception e) { + e.printStackTrace(); + } + } + + /** + * Returns to the root EObject. + * @return Root EObject + */ + protected final EObject getRoot() { + return root; + } + + /** + * @see org.eclipse.emf.common.command.Command#redo() + */ + @Override + public void redo() { + // do nothing + } + + /** + * @see org.eclipse.emf.common.command.AbstractCommand#undo() + */ + @Override + public void undo() { + // do nothing + } + + /** + * @see org.eclipse.emf.common.command.AbstractCommand#canExecute() + */ + @Override + public final boolean canExecute() { + return true; + } + + /** + * @see org.eclipse.emf.common.command.AbstractCommand#canUndo() + */ + @Override + public final boolean canUndo() { + return false; + } + +} \ No newline at end of file
diff --git a/org.eclipse.emf.refactor.refactoring.runtime/src/org/eclipse/emf/refactor/refactoring/runtime/test/JUnitTestCaseAdapter.java b/org.eclipse.emf.refactor.refactoring.runtime/src/org/eclipse/emf/refactor/refactoring/runtime/test/JUnitTestCaseAdapter.java new file mode 100644 index 0000000..eb2a6aa --- /dev/null +++ b/org.eclipse.emf.refactor.refactoring.runtime/src/org/eclipse/emf/refactor/refactoring/runtime/test/JUnitTestCaseAdapter.java
@@ -0,0 +1,345 @@ +/******************************************************************************* + * Copyright (c) Philipps University of Marburg. 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: + * Philipps University of Marburg - initial API and implementation + *******************************************************************************/ +package org.eclipse.emf.refactor.refactoring.runtime.test; + +import static org.junit.Assert.assertEquals; + +import java.io.File; +import java.io.IOException; +import java.util.ArrayList; +import java.util.Collections; +import java.util.Iterator; +import java.util.List; + +import javax.xml.parsers.DocumentBuilder; +import javax.xml.parsers.DocumentBuilderFactory; +import javax.xml.parsers.ParserConfigurationException; + +import org.eclipse.emf.common.util.URI; +import org.eclipse.emf.ecore.EAnnotation; +import org.eclipse.emf.ecore.EModelElement; +import org.eclipse.emf.ecore.EObject; +import org.eclipse.emf.ecore.EPackage; +import org.eclipse.emf.ecore.resource.Resource; +import org.eclipse.emf.ecore.resource.ResourceSet; +import org.eclipse.emf.ecore.resource.Resource.Factory; +import org.eclipse.emf.ecore.resource.impl.ResourceSetImpl; +import org.eclipse.emf.ecore.util.EcoreUtil; +import org.eclipse.emf.ecore.xmi.impl.XMIResourceFactoryImpl; +import org.eclipse.emf.edit.domain.EditingDomain; +import org.eclipse.emf.refactor.refactoring.core.Refactoring; +import org.eclipse.emf.transaction.TransactionalEditingDomain; +import org.junit.Test; +import org.w3c.dom.Document; +import org.w3c.dom.Element; +import org.w3c.dom.Node; +import org.w3c.dom.NodeList; +import org.xml.sax.SAXException; + +/** + * Adapter class used for running JUnit tests. + * @generated NOT + * @author Thorsten Arendt + */ +public abstract class JUnitTestCaseAdapter { + + private static final String TEST_CASES_DIR = "test_"; + private static final String ANNOTATION = "marker"; + + /** + * Path prefix of the model to be loaded. + */ + private final String pathPrefix; + + /** + * Name of the refactoring to test + */ + private final String name; + + /** + * File extension of the models + */ + private final String extension; + + /** + * XMIResourceFactory used for registry purposes. + */ + private final Factory factory; + + /** + * Refactoring to test + */ + private final Refactoring refactoring; + + /** + * Constructor. + * @param newName the name of the refactoring to test + * @param newExtension the file extension of the models + * @param bundle path to the bundle containing the test cases + * @param newEmfRefactoring the refactoring to test + */ + protected JUnitTestCaseAdapter( + final String newName, + final String newExtension, + final String bundle, + final Refactoring newRefactoring) { + this.name = newName; + this.extension = newExtension; + this.refactoring = newRefactoring; + this.pathPrefix = bundle + "/tests/" + newName; + this.factory = new XMIResourceFactoryImpl(); + } + + /** + * Prepares and runs the test case with the given number. + * @param no the number of the test case + */ + protected final void executeTestCase(final String no) { + // create model manager for this test case + JUnitModelManager newModelManager = createJUnitModelManager(no); + if (newModelManager != null) { + // get source model + EObject source = newModelManager.getSource(); + // set the selection to the annotated element + // of the source model + setSelection(getAnnotatedElement(source)); + // set the port values for this test case + setPortValues(no); + // run actual test + newModelManager.runTest(no); + } + } + + /** + * Creates a JUnitModelManager for this test case. + * @param no the number of the test case + * @return JUnitModelManager for this test case + */ + private JUnitModelManager createJUnitModelManager(final String no) { + // create URIs for source and target model files + URI sourceUri = URI.createFileURI( + new File(pathPrefix, + "/" + TEST_CASES_DIR + + no + "/source." + + extension) + .getAbsolutePath()); + URI targetUri = URI.createFileURI( + new File(pathPrefix, + "/" + TEST_CASES_DIR + + no + "/target." + + extension) + .getAbsolutePath()); + // load source and target models + EObject source = null; + try { + source = loadResource(sourceUri); + } catch (IOException e) { + e.printStackTrace(); + return null; + } + EObject target = null; + try { + target = loadResource(targetUri); + } catch (IOException e) { + e.printStackTrace(); + } + // return the model manager + // target = null intentionally allowed, tries constraints instead + return new JUnitModelManager( + source, target, getEditingDomain(source)); + } + + /** + * Loads and returns the EObject for a given resource via it's URI. + * @param resourceUri URI of the resource that should be loaded + * @return the EObject to the given URI + * @throws IOException + */ + private EObject loadResource(final URI resourceUri) throws IOException { + ResourceSet resourceSet = new ResourceSetImpl(); + resourceSet.getResourceFactoryRegistry() + .getExtensionToFactoryMap() + .put(extension, factory); + Resource rs = resourceSet.createResource(resourceUri); + rs.load(Collections.EMPTY_MAP); + return EcoreUtil.getRootContainer(rs.getContents().get(0)); + } + + /** + * Returns the editing domain for this EObject (the model). + * @param source the model to get the editing domain for + * @return the editing domain for the given EObject (model) + */ + private EditingDomain getEditingDomain(final EObject source) { + ResourceSet rset = source.eResource().getResourceSet(); + EditingDomain editingDomain = null; + try { + // if a domain is registered already, use it + editingDomain = + TransactionalEditingDomain.Factory.INSTANCE + .getEditingDomain(rset); + } catch (Exception e) { + //Ignore Exception + } + + if (null == editingDomain) { + try { + // else, create a new one + editingDomain = + TransactionalEditingDomain + .Factory.INSTANCE + .createEditingDomain(rset); + } catch (Exception e) { + e.printStackTrace(); + } + } + return editingDomain; + } + + /** + * Sets the selection of the refactoring to the given object. + * Preselects port accordingly. + * @param selection the EObject to select + */ + private void setSelection(final EObject selection) { + if (null == selection) { + throw new RuntimeException("Selection not found!"); + } + List<EObject> sel = new ArrayList<EObject>(); + sel.add(selection); + // set the refactoring controller's selection + refactoring.getController().setSelection(sel); + // preselect the port + refactoring.getController().getDataManagementObject() + .preselect(sel); + } + + /** + * Returns the annotated model element from the given model. + * @param root the model which contains the annotated element + * @return the annotated model element + */ + private static EModelElement getAnnotatedElement(final EObject root) { + Iterator<EObject> allElements = root.eAllContents(); + // loop through all elements of the model object + while (allElements.hasNext()) { + EObject element = allElements.next(); + if (element instanceof EModelElement) { + if (element instanceof EAnnotation) { + if (((EAnnotation) element).getSource() + .equals(ANNOTATION)) { + // return annotated element + return + ((EAnnotation) element) + .getEModelElement(); + } + } + } + } + throw new RuntimeException("Element not found!"); + } + + /** + * Sets the port values according to the config XML. + * @param no the number of the test case + */ + @SuppressWarnings("unchecked") + private void setPortValues(final String no) { + // create URI for the config XML file of this test case + URI configUri = URI.createFileURI( + new File(pathPrefix, "/" + + TEST_CASES_DIR + + no + "/config.xml") + .getAbsolutePath()); + // parse the XML + DocumentBuilderFactory dbf = + DocumentBuilderFactory.newInstance(); + Document doc = null; + try { + DocumentBuilder db = dbf.newDocumentBuilder(); + try { + doc = db.parse(configUri.toString()); + } catch (final SAXException e) { + e.printStackTrace(); + } catch (final IOException e) { + e.printStackTrace(); + } + } catch (ParserConfigurationException e1) { + e1.printStackTrace(); + } + if (null != doc) { + doc.getDocumentElement().normalize(); + NodeList nodes = doc.getElementsByTagName("param"); + String portName = ""; + String portValue = ""; + // for every parameter in the config + for (int i = 0; i < nodes.getLength(); i++) { + Node node = nodes.item(i); + if (node.getNodeType() == Node.ELEMENT_NODE) { + Element param = (Element) node; + NodeList names = + ((Element) param + .getElementsByTagName("name") + .item(0)) + .getChildNodes(); + portName = + ((Node) names + .item(0)) + .getNodeValue(); + NodeList values = + ((Element) param + .getElementsByTagName("value") + .item(0)) + .getChildNodes(); + portValue = + ((Node) values.item(0)).getNodeValue(); + // save the value of the specified port + refactoring + .getController() + .getDataManagementObject() + .getInPortByName(portName) + .setValue(portValue); + } + } + } + } + + /** + * Registers the right package to namespace URI relation to + * the package registry. + */ + protected static void register(final EPackage ePackage) { + EPackage.Registry.INSTANCE.put( + ePackage.getNsURI(), + EPackage.Registry.INSTANCE.get( + ePackage.getNsURI())); + } + + /** + * Individual Model Manager + */ + protected final class JUnitModelManager extends ModelManager { + + public JUnitModelManager(final EObject source, + final EObject target, + final EditingDomain editingDomain) { + super(name, refactoring.getController(), + source, target, extension, editingDomain); + } + + @Test + public void runTest(final String no) { + assertEquals(true, this.testRefactor()); + } + + } + +}
diff --git a/org.eclipse.emf.refactor.refactoring.runtime/src/org/eclipse/emf/refactor/refactoring/runtime/test/ModelManager.java b/org.eclipse.emf.refactor.refactoring.runtime/src/org/eclipse/emf/refactor/refactoring/runtime/test/ModelManager.java new file mode 100644 index 0000000..131d54a --- /dev/null +++ b/org.eclipse.emf.refactor.refactoring.runtime/src/org/eclipse/emf/refactor/refactoring/runtime/test/ModelManager.java
@@ -0,0 +1,252 @@ +/******************************************************************************* + * Copyright (c) Philipps University of Marburg. 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: + * Philipps University of Marburg - initial API and implementation + *******************************************************************************/ +package org.eclipse.emf.refactor.refactoring.runtime.test; + +import java.io.File; +import java.io.IOException; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +import org.eclipse.emf.common.util.URI; +import org.eclipse.emf.compare.diff.metamodel.DiffModel; +import org.eclipse.emf.compare.diff.service.DiffService; +import org.eclipse.emf.compare.match.MatchOptions; +import org.eclipse.emf.compare.match.metamodel.MatchElement; +import org.eclipse.emf.compare.match.metamodel.MatchModel; +import org.eclipse.emf.compare.match.service.MatchService; +import org.eclipse.emf.compare.util.EMFCompareMap; +import org.eclipse.emf.compare.util.ModelUtils; +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.resource.impl.ResourceSetImpl; +import org.eclipse.emf.ecore.util.EcoreUtil; +import org.eclipse.emf.ecore.xmi.XMLResource; +import org.eclipse.emf.ecore.xmi.impl.XMIResourceFactoryImpl; +import org.eclipse.emf.edit.domain.EditingDomain; +import org.eclipse.emf.refactor.refactoring.interfaces.IController; + +/** + * Class used for JUnit tests. + * @generated NOT + * @author Thorsten Arendt + */ +public class ModelManager { + + + /** + * Name of the refactoring to be tested. + */ + private final String name; + + /** + * Controller to be used for the refactoring. + */ + private final IController controller; + + /** + * EObject to run the refactoring on. + */ + private final EObject source; + + /** + * EObject to compare the refactored source model to. + */ + private final EObject target; + + /** + * File extension of the corresponding meta model. + */ + private final String extension; + + /** + * Editing domain to be used for the refactoring. + */ + private final EditingDomain editingDomain; + + /** + * Constructor. + * @param newName Name of the refactoring to be tested. + * @param newController Controller to be used for the refactoring. + * @param newSource Source EObject to run the refactoring on. + * @param newTarget Target EObject to compare the refactored source model to. + * @param newExtension File extension of the corresponding meta model. + * @param newEditingDomain Editing domain to be used for the refactoring. + */ + public ModelManager( + final String newName, + final IController newController, + final EObject newSource, + final EObject newTarget, + final String newExtension, + final EditingDomain newEditingDomain) { + super(); + this.name = newName; + this.controller = newController; + this.source = newSource; + this.target = newTarget; + this.extension = newExtension; + this.editingDomain = newEditingDomain; + } + + /** + * Returns the source EObject. + * @return the source EObject + */ + public final EObject getSource() { + return source; + } + + /** + * Returns the target EObject. + * @return the target EObject + */ + public final EObject getTarget() { + return target; + } + + /** + * Refactors the source model and compares it to the target model. + * @return true if the expected target model is matched, false if not + */ + protected final boolean testRefactor() { + try { + boolean match = true; + // create refactoring + EObject refactoredSource = executeRefactoring(); + + // set match model options + Map<String, Object> options = + new HashMap<String, Object>(); + // OPTION_IGNORE_XMI_ID = true + options.put( + MatchOptions.OPTION_IGNORE_XMI_ID, + Boolean.TRUE); + // create match model with those options + MatchModel matchModel = + MatchService.doMatch( + refactoredSource, + target, + options); + // if match model contains unmatched elements + if (matchModel.getUnmatchedElements().size() > 0) { + // set matched to false + match = false; + } + + // if still matched + if (match) { + // create diff model + DiffModel diff = DiffService.doDiff(matchModel); + // if there are differences + if (diff.getDifferences().size() > 0) { + // set matched to false + match = false; + } + } + + // if still matched + if (match) { + // run through all matched elements + List<MatchElement> matchedElements = + matchModel.getMatchedElements(); + for (MatchElement m : matchedElements) { + if (1 != m.getSimilarity()) { + match = false; + } + } + } + this.saveEMFDiffFile(matchModel); + this.saveModel(EcoreUtil.copy(refactoredSource)); + return match; + } catch (final Exception e) { + e.printStackTrace(); + return false; + } + } + + private EObject executeRefactoring() { + EmfTestRefactoringCommand command = + new EmfTestRefactoringCommand( + name, + controller.getLtkRefactoringProcessor(), + source); + // execute the refactoring + editingDomain.getCommandStack().execute(command); + return command.getRoot(); + } + + /** + * Save an EMFDiffFile for the given match model. + * @param match the MatchModel to create the diff file for + * @throws IOException + */ + private void saveEMFDiffFile( + final MatchModel match) throws IOException { + // get source model URI + final String decodedSourcePath = + URI.decode(source.eResource().getURI().path()); + // diff file URI = model URI with different extension (.emfdiff) + final String diffFileName = + new File(decodedSourcePath) + .getAbsolutePath().replace("source." + extension, "differences.emfdiff"); + final URI diffFileURI = URI.createFileURI(diffFileName); + + // create diff model + final DiffModel diff = DiffService.doDiff(match, false); + + // save the diff model + ResourceSet rs = new ResourceSetImpl(); + rs.getResourceFactoryRegistry() + .getExtensionToFactoryMap() + .put("emfdiff", new XMIResourceFactoryImpl()); + final Resource newModelResource = + ModelUtils.createResource(diffFileURI, rs); + newModelResource.getContents().add(diff); + final Map<String, String> options = + new EMFCompareMap<String, String>(); + options.put( + XMLResource.OPTION_ENCODING, + System.getProperty("file.encoding")); + newModelResource.save(options); + + } + + private void saveModel(EObject refsource) { + ResourceSet rs = new ResourceSetImpl(); + rs.getResourceFactoryRegistry() + .getExtensionToFactoryMap() + .put(extension, new XMIResourceFactoryImpl()); + final String decodedSourcePath = + URI.decode(source.eResource().getURI().path()); + final String refSourceFileName = + new File(decodedSourcePath) + .getAbsolutePath().replace("source." + extension, "source_ref." + extension); + final URI refSourceURI = URI.createFileURI(refSourceFileName); + final Resource newModelResource = + ModelUtils.createResource(refSourceURI, rs); + rs.eSetDeliver(false); + newModelResource.eSetDeliver(false); + newModelResource.getContents().add(refsource); + final Map<String, String> options = + new EMFCompareMap<String, String>(); + options.put( + XMLResource.OPTION_ENCODING, + System.getProperty("file.encoding")); + try { + newModelResource.save(options); + } catch (IOException e) { + e.printStackTrace(); + } + } + +}
diff --git a/org.eclipse.emf.refactor.refactoring.runtime/src/org/eclipse/emf/refactor/refactoring/runtime/ui/ApplicationMenu.java b/org.eclipse.emf.refactor.refactoring.runtime/src/org/eclipse/emf/refactor/refactoring/runtime/ui/ApplicationMenu.java new file mode 100644 index 0000000..6611d50 --- /dev/null +++ b/org.eclipse.emf.refactor.refactoring.runtime/src/org/eclipse/emf/refactor/refactoring/runtime/ui/ApplicationMenu.java
@@ -0,0 +1,215 @@ +/******************************************************************************* + * Copyright (c) Philipps University of Marburg. 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: + * Philipps University of Marburg - initial API and implementation + *******************************************************************************/ +package org.eclipse.emf.refactor.refactoring.runtime.ui; + +import java.lang.reflect.Method; +import java.util.ArrayList; +import java.util.Iterator; +import java.util.LinkedList; +import java.util.List; + +import org.eclipse.core.resources.IProject; +import org.eclipse.emf.ecore.EObject; +import org.eclipse.emf.refactor.refactoring.configuration.managers.ConfigurationManager; +import org.eclipse.emf.refactor.refactoring.core.Refactoring; +import org.eclipse.emf.refactor.refactoring.managers.ProjectManager; +import org.eclipse.emf.refactor.refactoring.runtime.config.RuntimeConfig; + +import org.eclipse.jface.action.ContributionItem; +import org.eclipse.jface.dialogs.MessageDialog; +import org.eclipse.jface.viewers.ISelection; +import org.eclipse.jface.viewers.StructuredSelection; +import org.eclipse.ltk.ui.refactoring.RefactoringWizardOpenOperation; +import org.eclipse.swt.SWT; +import org.eclipse.swt.events.SelectionAdapter; +import org.eclipse.swt.events.SelectionEvent; +import org.eclipse.swt.widgets.Display; +import org.eclipse.swt.widgets.Menu; +import org.eclipse.swt.widgets.MenuItem; +import org.eclipse.swt.widgets.Shell; +import org.eclipse.ui.PlatformUI; + +/** + * Class for invoking EMF model refactoring out from a selection + * of objects in the workbench. + * @generated NOT + * @author Florian Mantz + */ +public class ApplicationMenu extends ContributionItem { + + /** + * Interface name of GMF editors' graphical edit parts. + */ + private static final String GMF_EDITPART_IDENTIFIER = + "org.eclipse.gmf.runtime.diagram.ui.editparts.IGraphicalEditPart"; + + /** + * Method of IGraphicalEditPart that returns the corresponding EObject. + */ + private static Method gmfMethod = null; + + /** + * List of EObjects selected in the workbench. + */ + private final List<EObject> selection; + + /** + * The menu is created each time when it is displayed + */ + public ApplicationMenu() { + ISelection orgSelection = + PlatformUI.getWorkbench().getActiveWorkbenchWindow() + .getSelectionService().getSelection(); + selection = getESelection(orgSelection); + } + + /** + * The menu is created each time when it is displayed + */ + public ApplicationMenu(String id) { + super(id); + ISelection orgSelection = + PlatformUI.getWorkbench().getActiveWorkbenchWindow() + .getSelectionService().getSelection(); + selection = getESelection(orgSelection); + } + + /** + * Sets the selected EObject list out of the origin selection. + * @param selection Origin selection in the workbench. + * @return List of selected EObjects. + */ + private List<EObject> getESelection(ISelection selection){ + List<EObject> r = new ArrayList<EObject>(); + for(Object o : this.getSelection(selection)){ + if(o instanceof org.eclipse.emf.ecore.EObject){ + r.add((EObject)o); + } + } + return r; + } + + /** + * Returns a list of relevant objects from the given selection. + * @param selection Origin selection in the workbench. + * @return List of relevant objects from the given selection. + */ + @SuppressWarnings("rawtypes") + private Object[] getSelection(ISelection selection) { + if(null != selection && selection instanceof StructuredSelection){ + StructuredSelection ss = (StructuredSelection) selection; + if(null == ss.getFirstElement()){ + return ss.toArray(); + } + List<Object> list = new ArrayList<Object>(); + final Iterator i = ss.iterator(); + while(i.hasNext()){ + final Object selectedEObject = i.next(); + final Class cl = selectedEObject.getClass(); + //Usual EMF-Tree: + boolean added = checkEMFTree(list, selectedEObject); + if(!added){ + added = checkGmf(list, selectedEObject, cl); + } + } + return list.toArray(); + } + return new Object[0]; + } + + /** + * Checks whether the selected Object is an edit part of an gmf + * generated editor and adds the corresponding EObject to the + * given list. + * @param list List of relevant objects from the given selection. + * @param selectedEObject Object to be checked. + * @param cl Class of the object to be checked. + * @return true if the object was inserted to the list, false + * otherwise. + */ + @SuppressWarnings("rawtypes") + private boolean checkGmf (List<Object> list, + final Object selectedEObject, final Class cl) { + RuntimeConfig config = new RuntimeConfig(); + if(config.isSupportGmfDiagramEditors() && + RuntimeConfig.checkIsTypeOf(cl, GMF_EDITPART_IDENTIFIER, true)){ + try { + if(null == ApplicationMenu.gmfMethod){ + ApplicationMenu.gmfMethod = + selectedEObject.getClass().getMethod + ("resolveSemanticElement", new Class[0]); + } + list.add(ApplicationMenu.gmfMethod.invoke(selectedEObject)); + return true; + } catch (Exception e) { + e.printStackTrace(); + } + } + return false; + } + + /** + * Checks whether the given selectedObject is of type EObject + * and then adds it to the list. + * @param list List of relevant objects from the given selection. + * @param selectedEObject Object to be checked. + * @return true if the object was inserted to the list, false + * otherwise. + */ + private boolean checkEMFTree(List<Object> list, + final Object selectedEObject) { + if(selectedEObject instanceof EObject){ + list.add(selectedEObject); + return true; + } + return false; + } + + /** + * @see org.eclipse.jface.action.ContributionItem#fill + * (org.eclipse.swt.widgets.Menu, int) + */ + @Override + public void fill(Menu menu, int index) { + ConfigurationManager.getInstance(); + IProject project = ProjectManager.getActualProject(); + LinkedList<Refactoring> refactorings = + ConfigurationManager.getSelectedRefactorings(project); + for(final Refactoring r : refactorings){ + if(r.getGui().showInMenu(this.selection)){ + MenuItem menuItem = new MenuItem(menu, SWT.CHECK, index); + menuItem.setText(r.getName()); + menuItem.addSelectionListener(new SelectionAdapter() { + public void widgetSelected(SelectionEvent e) { + try { + //1. Set Selection: + r.getController().setSelection(selection); + //2. Preselect Values: + r.getController().getDataManagementObject() + .preselect(selection); + //3. Show Refactoring-Gui: + Shell shell = + Display.getDefault().getActiveShell(); + RefactoringWizardOpenOperation dialog = + new RefactoringWizardOpenOperation + (r.getGui().show()); + dialog.run(shell, "Refactoring: " + r.getName()); + + } catch (Exception e2) { + MessageDialog + .openError(null, "Error", e2.getMessage()); + } + } + }); + } + } + } +}