diff options
author | Ansgar Radermacher | 2018-10-25 11:08:31 +0000 |
---|---|---|
committer | Ansgar Radermacher | 2018-10-25 16:32:47 +0000 |
commit | e75c90875452e5c71f1760dc183a8ab2696f40f5 (patch) | |
tree | 9b49b614d862f8e94d0f8fc81f7915126f731406 | |
parent | 6b3db36871566c18a7b7308c2ca762682cc62aea (diff) | |
download | org.eclipse.papyrus-designer-e75c90875452e5c71f1760dc183a8ab2696f40f5.tar.gz org.eclipse.papyrus-designer-e75c90875452e5c71f1760dc183a8ab2696f40f5.tar.xz org.eclipse.papyrus-designer-e75c90875452e5c71f1760dc183a8ab2696f40f5.zip |
Bug 540460 - [Designer][transformation] It should be possible to use a specific transformation chain programmatically
- Rename InstantiateDepPlan class into ExecuteTransformationChain, since the original name is misleading an did not fit.
- Rename existing class ExecuteTransformation into ExecuteChainUtil (as it only contained a static method)
- Clean-up interface (move two parameters into constructor)
- Update documentation
- Update classes that call the transformation
Signed-off-by: Ansgar Radermacher <ansgar.radermacher@cea.fr>
Change-Id: I436d2e8c8c4becc885692a2b3d3ae38c945347e2
8 files changed, 335 insertions, 327 deletions
diff --git a/plugins/languages/common/org.eclipse.papyrus.designer.languages.common.testutils/META-INF/MANIFEST.MF b/plugins/languages/common/org.eclipse.papyrus.designer.languages.common.testutils/META-INF/MANIFEST.MF index 439b34056..e74a375cc 100644 --- a/plugins/languages/common/org.eclipse.papyrus.designer.languages.common.testutils/META-INF/MANIFEST.MF +++ b/plugins/languages/common/org.eclipse.papyrus.designer.languages.common.testutils/META-INF/MANIFEST.MF @@ -12,7 +12,9 @@ Require-Bundle: org.junit;bundle-version="4.12.0", org.eclipse.uml2.uml;bundle-version="5.2.2", org.eclipse.papyrus.designer.transformation.base;bundle-version="0.8.0", org.eclipse.papyrus.designer.transformation.core;bundle-version="0.8.0", - org.eclipse.papyrus.designer.languages.common.base;bundle-version="1.1.0" + org.eclipse.papyrus.designer.languages.common.base;bundle-version="1.1.0", + org.eclipse.papyrus.designer.transformation.profile;bundle-version="0.8.0" Export-Package: org.eclipse.papyrus.designer.languages.common.testutils Bundle-Vendor: %providerName Bundle-Localization: plugin +Automatic-Module-Name: org.eclipse.papyrus.designer.languages.common.testutils diff --git a/plugins/languages/common/org.eclipse.papyrus.designer.languages.common.testutils/src/org/eclipse/papyrus/designer/languages/common/testutils/TransformationTestSupport.java b/plugins/languages/common/org.eclipse.papyrus.designer.languages.common.testutils/src/org/eclipse/papyrus/designer/languages/common/testutils/TransformationTestSupport.java index f37727973..6c95603a7 100644 --- a/plugins/languages/common/org.eclipse.papyrus.designer.languages.common.testutils/src/org/eclipse/papyrus/designer/languages/common/testutils/TransformationTestSupport.java +++ b/plugins/languages/common/org.eclipse.papyrus.designer.languages.common.testutils/src/org/eclipse/papyrus/designer/languages/common/testutils/TransformationTestSupport.java @@ -22,7 +22,7 @@ import org.eclipse.core.runtime.NullProgressMonitor; import org.eclipse.papyrus.designer.languages.common.base.ElementUtils; import org.eclipse.papyrus.designer.languages.common.base.TestInfo; import org.eclipse.papyrus.designer.transformation.base.utils.ProjectManagement; -import org.eclipse.papyrus.designer.transformation.core.transformations.InstantiateDepPlan; +import org.eclipse.papyrus.designer.transformation.core.transformations.ExecuteTransformationChain; import org.eclipse.papyrus.junit.utils.rules.AbstractHouseKeeperRule; import org.eclipse.papyrus.junit.utils.rules.PapyrusEditorFixture; import org.eclipse.uml2.uml.NamedElement; @@ -76,7 +76,7 @@ public class TransformationTestSupport { Package nePkg = (Package) ne; final int genOptions = 0; - new InstantiateDepPlan().instantiate(nePkg, new NullProgressMonitor(), project, genOptions); + new ExecuteTransformationChain(nePkg, project).executeTransformation(new NullProgressMonitor(), genOptions); } } @@ -87,7 +87,7 @@ public class TransformationTestSupport { * the project into which generation has been done; * @param folderInTestBundle * The folder within the source bundle containing the expected results - * @param folderInModelProject + * @param srcGen * The folder name containing the generated code (a folder of the same name is created within the model project to facilitate the comparison) */ public void validateResults(IProject genProject, String folderInTestBundle, String srcGen) { @@ -98,9 +98,9 @@ public class TransformationTestSupport { copier.copy(srcBundle, folderInTestBundle, modelProject, srcGen); IFolder expectedSrcGen = modelProject.getFolder(srcGen); - assertThat("expected source folder must exist", expectedSrcGen.exists()); + assertThat("expected source folder must exist", expectedSrcGen.exists()); //$NON-NLS-1$ IFolder generatedSrcGen = genProject.getFolder(srcGen); - assertThat("generated source folder must exist", generatedSrcGen.exists()); + assertThat("generated source folder must exist", generatedSrcGen.exists()); //$NON-NLS-1$ FileComparison.assertGeneratedMatchesExpected(generatedSrcGen, expectedSrcGen); } diff --git a/plugins/transformation/org.eclipse.papyrus.designer.transformation.core/src/org/eclipse/papyrus/designer/transformation/core/Messages.java b/plugins/transformation/org.eclipse.papyrus.designer.transformation.core/src/org/eclipse/papyrus/designer/transformation/core/Messages.java index b4e5ccbd1..4aa054919 100644 --- a/plugins/transformation/org.eclipse.papyrus.designer.transformation.core/src/org/eclipse/papyrus/designer/transformation/core/Messages.java +++ b/plugins/transformation/org.eclipse.papyrus.designer.transformation.core/src/org/eclipse/papyrus/designer/transformation/core/Messages.java @@ -32,7 +32,6 @@ public class Messages extends NLS { public static String TemplateInstantiation_TemplateIsNull; public static String TemplateInstantiationListener_TrafoException; - public static String InstantiateDepPlan_ConsultConsole; public static String InstantiateDepPlan_ErrorsDuringTransformation; public static String InstantiateDepPlan_TransformationException; diff --git a/plugins/transformation/org.eclipse.papyrus.designer.transformation.core/src/org/eclipse/papyrus/designer/transformation/core/messages.properties b/plugins/transformation/org.eclipse.papyrus.designer.transformation.core/src/org/eclipse/papyrus/designer/transformation/core/messages.properties index 4657ce8e1..85f57fc99 100644 --- a/plugins/transformation/org.eclipse.papyrus.designer.transformation.core/src/org/eclipse/papyrus/designer/transformation/core/messages.properties +++ b/plugins/transformation/org.eclipse.papyrus.designer.transformation.core/src/org/eclipse/papyrus/designer/transformation/core/messages.properties @@ -10,7 +10,6 @@ TemplateUtils_InfoGetActualFrom=TemplateUtils.getActualFromBinding: substitution TemplateInstantiation_TemplateIsNull=Passed template element is null TemplateInstantiationListener_TrafoException=TransformationException: %s -InstantiateDepPlan_ConsultConsole=Consult error log or console for details InstantiateDepPlan_ErrorsDuringTransformation=An error occurred during transformation InstantiateDepPlan_TransformationException=A transformation exception occurred diff --git a/plugins/transformation/org.eclipse.papyrus.designer.transformation.core/src/org/eclipse/papyrus/designer/transformation/core/transformations/ExecuteChainUtil.java b/plugins/transformation/org.eclipse.papyrus.designer.transformation.core/src/org/eclipse/papyrus/designer/transformation/core/transformations/ExecuteChainUtil.java new file mode 100644 index 000000000..f0a95e8d8 --- /dev/null +++ b/plugins/transformation/org.eclipse.papyrus.designer.transformation.core/src/org/eclipse/papyrus/designer/transformation/core/transformations/ExecuteChainUtil.java @@ -0,0 +1,69 @@ +/***************************************************************************** + * Copyright (c) 2016 CEA LIST. + * + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License 2.0 + * which accompanies this distribution, and is available at + * https://www.eclipse.org/legal/epl-2.0/ + * + * SPDX-License-Identifier: EPL-2.0 + * + * Contributors: + * Ansgar Radermacher ansgar.radermacher@cea.fr + * + *****************************************************************************/ + +package org.eclipse.papyrus.designer.transformation.core.transformations; + + +import java.util.ArrayList; +import java.util.List; + +import org.eclipse.papyrus.designer.transformation.base.utils.TransformationException; +import org.eclipse.papyrus.designer.transformation.profile.Transformation.M2MTrafo; +import org.eclipse.papyrus.designer.transformation.profile.Transformation.M2MTrafoChain; +import org.eclipse.uml2.uml.Property; +import org.eclipse.uml2.uml.util.UMLUtil; + +/** + * This class executes a complete transformation chain. It executes the transformation in + * the order specified in the transformation chain. + */ +public class ExecuteChainUtil { + + public static void apply(M2MTrafoChain chain, List<M2MTrafo> additionalTrafos) throws TransformationException { + ArrayList<M2MTrafo> transformations = new ArrayList<M2MTrafo>(); + for (Property m2mTrafoRef : chain.getBase_Class().getAllAttributes()) { + M2MTrafo trafo = UMLUtil.getStereotypeApplication(m2mTrafoRef.getType(), M2MTrafo.class); + if (trafo != null) { + transformations.add(trafo); + } + else { + throw new TransformationException(String.format( + "type of element %s in chain does not have M2MTrafo stereotype applied.", m2mTrafoRef.getName())); + } + } + + // instead of fully resolving constraints, we assume that the before/after conditions are not both + // specified and only relate to elements already in the original transformation chain. + for (M2MTrafo additionalTrafo : additionalTrafos) { + if (additionalTrafo.getBefore() != null) { + int index = transformations.indexOf(additionalTrafo.getBefore()); + if (index >= 0) { + transformations.add(index, additionalTrafo); + } + } + else if (additionalTrafo.getAfter() != null) { + int index = transformations.indexOf(additionalTrafo.getAfter()); + if (index >= 0) { + transformations.add(index+1, additionalTrafo); + } + } + else { + transformations.add(additionalTrafo); + } + } + + ExecuteTransformation.apply(transformations.iterator()); + } +} diff --git a/plugins/transformation/org.eclipse.papyrus.designer.transformation.core/src/org/eclipse/papyrus/designer/transformation/core/transformations/ExecuteTransformationChain.java b/plugins/transformation/org.eclipse.papyrus.designer.transformation.core/src/org/eclipse/papyrus/designer/transformation/core/transformations/ExecuteTransformationChain.java index 5da9f9e2c..84c37a782 100644 --- a/plugins/transformation/org.eclipse.papyrus.designer.transformation.core/src/org/eclipse/papyrus/designer/transformation/core/transformations/ExecuteTransformationChain.java +++ b/plugins/transformation/org.eclipse.papyrus.designer.transformation.core/src/org/eclipse/papyrus/designer/transformation/core/transformations/ExecuteTransformationChain.java @@ -1,5 +1,6 @@ /***************************************************************************** - * Copyright (c) 2016 CEA LIST. + * Copyright (c) 2013 CEA LIST. + * * * All rights reserved. This program and the accompanying materials * are made available under the terms of the Eclipse Public License 2.0 @@ -15,55 +16,275 @@ package org.eclipse.papyrus.designer.transformation.core.transformations; +import java.util.HashMap; +import java.util.Map; -import java.util.ArrayList; -import java.util.List; - +import org.eclipse.core.resources.IProject; +import org.eclipse.core.resources.ResourcesPlugin; +import org.eclipse.core.runtime.IProgressMonitor; +import org.eclipse.jface.dialogs.MessageDialog; +import org.eclipse.papyrus.designer.deployment.profile.Deployment.DeploymentPlan; +import org.eclipse.papyrus.designer.deployment.tools.DepUtils; +import org.eclipse.papyrus.designer.languages.common.base.TestInfo; +import org.eclipse.papyrus.designer.transformation.base.UIContext; +import org.eclipse.papyrus.designer.transformation.base.utils.CommandSupport; +import org.eclipse.papyrus.designer.transformation.base.utils.ModelManagement; +import org.eclipse.papyrus.designer.transformation.base.utils.TrafoUtils; import org.eclipse.papyrus.designer.transformation.base.utils.TransformationException; -import org.eclipse.papyrus.designer.transformation.profile.Transformation.M2MTrafo; +import org.eclipse.papyrus.designer.transformation.core.Activator; +import org.eclipse.papyrus.designer.transformation.core.EnumService; +import org.eclipse.papyrus.designer.transformation.core.Messages; +import org.eclipse.papyrus.designer.transformation.core.generate.GenerationOptions; +import org.eclipse.papyrus.designer.transformation.core.templates.TemplateInstantiation; +import org.eclipse.papyrus.designer.transformation.core.transformations.LazyCopier.CopyExtResources; +import org.eclipse.papyrus.designer.transformation.core.transformations.filters.FilterLoadReferencedModels; import org.eclipse.papyrus.designer.transformation.profile.Transformation.M2MTrafoChain; -import org.eclipse.uml2.uml.Property; +import org.eclipse.papyrus.uml.tools.utils.PackageUtil; +import org.eclipse.swt.widgets.Display; +import org.eclipse.swt.widgets.Shell; +import org.eclipse.uml2.uml.InstanceSpecification; +import org.eclipse.uml2.uml.Model; +import org.eclipse.uml2.uml.Package; +import org.eclipse.uml2.uml.PackageableElement; import org.eclipse.uml2.uml.util.UMLUtil; /** - * This class executes a complete transformation chain. It executes the transformation in - * the order specified in the transformation chain. + * This class executes all transformations during the instantiation of a + * deployment plan or transformation chain. */ public class ExecuteTransformationChain { - public static void apply(M2MTrafoChain chain, List<M2MTrafo> additionalTrafos) throws TransformationException { - ArrayList<M2MTrafo> transformations = new ArrayList<M2MTrafo>(); - for (Property m2mTrafoRef : chain.getBase_Class().getAllAttributes()) { - M2MTrafo trafo = UMLUtil.getStereotypeApplication(m2mTrafoRef.getType(), M2MTrafo.class); - if (trafo != null) { - transformations.add(trafo); + /** + * Constructor + * + * @param rootPackageOrDP + * a package for which we want to execute a transformation. It may be a deployment plan + * @param monitor + * a progress monitor + * @param project + * the project in which to store the transformed (intermediate) model. If null, the project that hosts the current model is used. + */ + public ExecuteTransformationChain(Package rootPackageOrDP, IProject project) { + this.rootPackageOrDP = rootPackageOrDP; + if (project == null) { + String projectName = rootPackageOrDP.eResource().getURI().toString(); + this.project = ResourcesPlugin.getWorkspace().getRoot().getProject(projectName); + } else { + this.project = project; + } + } + + /** + * The location of the temporary model (relative to current project). TODO: + * make configurable? + */ + public static final String TEMP_MODEL_FOLDER = "tmpModel"; //$NON-NLS-1$ + + /** + * Postfix of the temporary model (prefix = name of top-level package). + * TODO: make configurable? + */ + public static final String TEMP_MODEL_POSTFIX = "Tmp.uml"; //$NON-NLS-1$ + + /** + * Progress monitor of Eclipse. + */ + protected IProgressMonitor monitor = null; + + /** + * generation options, currently unused except for REWRITE_SETTINGS (but caller always passes 0) + * It has been used before switching to configurable transformation chains, now + * possibility to have specific options for a certain transformation step would + * be useful. + */ + protected int generationOptions; + + /** + * The package for which a transformation should be executed. Could be a deployment plan + */ + protected Package rootPackageOrDP = null; + + protected IProject project; + + /** + * Execute a transformation chain + * + * @param monitor + * a progress monitor + * @param genOptions + * generation options + */ + public void executeTransformation(IProgressMonitor monitor, int genOptions) { + executeTransformation(null, monitor, genOptions); + } + + /** + * Execute a transformation chain + * + * @param chain + * a transformation chain. If null, take transformation chain from model + * @param monitor + * a progress monitor. + * @param genOptions + * select whether to produce an intermediate model only, also + * code, ... @see GenerationOptions + */ + public void executeTransformation(M2MTrafoChain chain, IProgressMonitor monitor, int genOptions) { + try { + this.monitor = monitor; + this.generationOptions = genOptions; + executeTransformation(chain); + } catch (final TransformationException e) { + // unload all resources in case of an exception + ModelManagement.getResourceSet().getResources().clear(); + printAndDisplayErrorMessage(e, Messages.InstantiateDepPlan_TransformationException); + } catch (final InterruptedException e) { + // do nothing, user interrupted + } finally { + TransformationContext.current = null; + } + } + + /** + * Execute a transformation chain. + * + * @param chain + * a transformation chain. If null, the transformation chain is obtained from stereotypes on the model + * @throws Exception + */ + protected void executeTransformation(M2MTrafoChain chain) throws TransformationException, InterruptedException { + ModelManagement intermediateModelManagement = null; + UIContext.monitor = monitor; + UIContext.configureProject = (generationOptions & GenerationOptions.REWRITE_SETTINGS) != 0; + + // 1a: create a new model (and applies same profiles / imports) + Model existingModel = rootPackageOrDP.getModel(); + TransformationContext tc = new TransformationContext(); + TransformationContext.current = tc; + TransformationContext.initialSourceRoot = existingModel; + TransformationContext.initialDeploymentPlan = rootPackageOrDP; + tc.project = project; + + intermediateModelManagement = ModelManagement.createNewModel(existingModel.getName()); + TransformationContext.current.mm = intermediateModelManagement; + + // get the temporary model + Package intermediateModel = intermediateModelManagement.getModel(); + + // create a package for global enumerations that are used by xtend code + EnumService.createEnumPackage(intermediateModel); + + // create a lazy copier towards the intermediate model + LazyCopier intermediateModelCopier = new LazyCopier(existingModel, intermediateModel, CopyExtResources.ALL, true); + intermediateModelCopier.preCopyListeners.add(FilterLoadReferencedModels.getInstance()); + + Map<InstanceSpecification, InstanceSpecification> instanceMap = new HashMap<InstanceSpecification, InstanceSpecification>(); + + if (DepUtils.isDeploymentPlan(rootPackageOrDP)) { + // deployment plan - copy top-level instances + for (InstanceSpecification instance : DepUtils.getInstances(rootPackageOrDP)) { + // InstanceSpecification newInstance = mainModelTrafo.transformInstance(instance, null); + InstanceSpecification newInstance = intermediateModelCopier.getCopy(instance); + + checkProgressStatus(); + TransformationUtil.propagateAllocation(newInstance); + instanceMap.put(instance, newInstance); } - else { - throw new TransformationException(String.format( - "type of element %s in chain does not have M2MTrafo stereotype applied.", m2mTrafoRef.getName())); + } else { + // no deployment plan - copy all packaged elements + intermediateModelCopier.shallowCopy(rootPackageOrDP); + + for (PackageableElement pe : rootPackageOrDP.getPackagedElements()) { + intermediateModelCopier.getCopy(pe); + + checkProgressStatus(); } } - - // instead of fully resolving constraints, we assume that the before/after conditions are not both - // specified and only relate to elements already in the original transformation chain. - for (M2MTrafo additionalTrafo : additionalTrafos) { - if (additionalTrafo.getBefore() != null) { - int index = transformations.indexOf(additionalTrafo.getBefore()); - if (index >= 0) { - transformations.add(index, additionalTrafo); - } - } - else if (additionalTrafo.getAfter() != null) { - int index = transformations.indexOf(additionalTrafo.getAfter()); - if (index >= 0) { - transformations.add(index+1, additionalTrafo); + + tc.copier = intermediateModelCopier; + tc.deploymentPlan = intermediateModelCopier.getCopy(rootPackageOrDP); + tc.modelRoot = PackageUtil.getRootPackage(tc.deploymentPlan); + + if (chain == null) { + chain = TrafoUtils.getTransformationChain(tc.deploymentPlan); + } + + TemplateInstantiation.init(); + ExecuteChainUtil.apply(chain, TrafoUtils.getAdditionalTransformations(rootPackageOrDP)); + + // setURIs and save (first update all URIs to ensure that model references use the + // correct URI before saving) + intermediateModelManagement.setURI(project, TEMP_MODEL_FOLDER, TEMP_MODEL_POSTFIX); + // also save additional root elements + for (ModelManagement mm : tc.copier.getAdditionalRootPkgs()) { + mm.setURI(project, TEMP_MODEL_FOLDER, TEMP_MODEL_POSTFIX); + } + intermediateModelManagement.save(); + for (ModelManagement mm : tc.copier.getAdditionalRootPkgs()) { + mm.save(); + } + + // -------------------------------------------------------------------- + checkProgressStatus(); + // -------------------------------------------------------------------- + + intermediateModelManagement.dispose(); + // also dispose additional models + for (ModelManagement mm : tc.copier.getAdditionalRootPkgs()) { + mm.dispose(); + } + } + + /** + * + * @param canonicalProjectName + * the automatically calculated project name + * @param userProjectName + * the project name chosen by the user + */ + public void updateProjectMapping(final String canonicalProjectName, final String userProjectName) { + CommandSupport.exec(rootPackageOrDP, "Update project mapping", new Runnable() { //$NON-NLS-1$ + + @Override + public void run() { + DeploymentPlan depPlan = UMLUtil.getStereotypeApplication(rootPackageOrDP, DeploymentPlan.class); + String mapName = canonicalProjectName + "=" + userProjectName; //$NON-NLS-1$ + for (String mapping : depPlan.getProjectMappings()) { + if (mapping.startsWith(canonicalProjectName)) { + mapping = mapName; + return; + } } + depPlan.getProjectMappings().add(mapName); } - else { - transformations.add(additionalTrafo); - } + }); + + } + + private void checkProgressStatus() throws InterruptedException { + if (monitor.isCanceled()) { + throw new InterruptedException(); + } + monitor.worked(1); + } + + private void printAndDisplayErrorMessage(Exception e, final String title) { + String message = e.toString(); + e.printStackTrace(); + // only display message, if not running headless + if (!TestInfo.runsHeadless()) { + displayError(title, message); } + Activator.log.error(e); + } - ExecuteTransformation.apply(transformations.iterator()); + private void displayError(final String title, final String message) { + Display.getDefault().syncExec(new Runnable() { + @Override + public void run() { + Shell shell = Display.getCurrent().getActiveShell(); + MessageDialog.openInformation(shell, title, message); + } + }); } } diff --git a/plugins/transformation/org.eclipse.papyrus.designer.transformation.core/src/org/eclipse/papyrus/designer/transformation/core/transformations/InstantiateDepPlan.java b/plugins/transformation/org.eclipse.papyrus.designer.transformation.core/src/org/eclipse/papyrus/designer/transformation/core/transformations/InstantiateDepPlan.java deleted file mode 100644 index 4834d2d2b..000000000 --- a/plugins/transformation/org.eclipse.papyrus.designer.transformation.core/src/org/eclipse/papyrus/designer/transformation/core/transformations/InstantiateDepPlan.java +++ /dev/null @@ -1,282 +0,0 @@ -/***************************************************************************** - * Copyright (c) 2013 CEA LIST. - * - * - * All rights reserved. This program and the accompanying materials - * are made available under the terms of the Eclipse Public License 2.0 - * which accompanies this distribution, and is available at - * https://www.eclipse.org/legal/epl-2.0/ - * - * SPDX-License-Identifier: EPL-2.0 - * - * Contributors: - * Ansgar Radermacher ansgar.radermacher@cea.fr - * - *****************************************************************************/ - -package org.eclipse.papyrus.designer.transformation.core.transformations; - -import java.util.HashMap; -import java.util.Map; - -import org.eclipse.core.resources.IProject; -import org.eclipse.core.resources.ResourcesPlugin; -import org.eclipse.core.runtime.IProgressMonitor; -import org.eclipse.jface.dialogs.MessageDialog; -import org.eclipse.papyrus.designer.deployment.profile.Deployment.DeploymentPlan; -import org.eclipse.papyrus.designer.deployment.tools.DepUtils; -import org.eclipse.papyrus.designer.languages.common.base.TestInfo; -import org.eclipse.papyrus.designer.transformation.base.UIContext; -import org.eclipse.papyrus.designer.transformation.base.utils.CommandSupport; -import org.eclipse.papyrus.designer.transformation.base.utils.ModelManagement; -import org.eclipse.papyrus.designer.transformation.base.utils.TrafoUtils; -import org.eclipse.papyrus.designer.transformation.base.utils.TransformationException; -import org.eclipse.papyrus.designer.transformation.core.Activator; -import org.eclipse.papyrus.designer.transformation.core.EnumService; -import org.eclipse.papyrus.designer.transformation.core.Messages; -import org.eclipse.papyrus.designer.transformation.core.generate.GenerationOptions; -import org.eclipse.papyrus.designer.transformation.core.templates.TemplateInstantiation; -import org.eclipse.papyrus.designer.transformation.core.transformations.LazyCopier.CopyExtResources; -import org.eclipse.papyrus.designer.transformation.core.transformations.filters.FilterLoadReferencedModels; -import org.eclipse.papyrus.designer.transformation.profile.Transformation.M2MTrafoChain; -import org.eclipse.papyrus.uml.tools.utils.PackageUtil; -import org.eclipse.swt.widgets.Display; -import org.eclipse.swt.widgets.Shell; -import org.eclipse.uml2.uml.InstanceSpecification; -import org.eclipse.uml2.uml.Model; -import org.eclipse.uml2.uml.Package; -import org.eclipse.uml2.uml.PackageableElement; -import org.eclipse.uml2.uml.util.UMLUtil; - -/** - * This class executes all transformations during the instantiation of a - * deployment plan or transformation chain. - */ -public class InstantiateDepPlan { - - /** - * The location of the temporary model (relative to current project). TODO: - * make configurable? - */ - public static final String TEMP_MODEL_FOLDER = "tmpModel"; //$NON-NLS-1$ - - /** - * Postfix of the temporary model (prefix = name of top-level package). - * TODO: make configurable? - */ - public static final String TEMP_MODEL_POSTFIX = "Tmp.uml"; //$NON-NLS-1$ - - /** - * Progress monitor of Eclipse. - */ - protected IProgressMonitor monitor = null; - - /** - * generation options, currently unused except for REWRITE_SETTINGS (but caller always passes 0) - * It has been used before switching to configurable transformation chains, now - * possibility to have specific options for a certain transformation step would - * be useful. - */ - protected int generationOptions; - - protected Package srcModelComponentDeploymentPlan = null; - - protected IProject project; - - public void instantiate(Package pkg, IProgressMonitor monitor, IProject project, int genOptions) { - srcModelComponentDeploymentPlan = pkg; - // - this.project = project; - if (project == null) { - String projectName = pkg.eResource().getURI().toString(); - this.project = ResourcesPlugin.getWorkspace().getRoot().getProject(projectName); - } - - // - instantiate(monitor, genOptions); - } - - /** - * Instantiate a deployment plan, i.e. generate an intermediate model via a - * sequence of transformations - * - * @param umlElement - * a deployment plan (UML package) or a configuration (UML class) - * @param monitor - * a progress monitor. - * - * @param project - * the current project. This information is used to store the - * intermediate model in a subfolder (tmpModel) of the current - * project - * @param genOptions - * select whether to produce an intermediate model only, also - * code, ... @see GenerationOptions - */ - private void instantiate(IProgressMonitor monitor, int genOptions) { - try { - initialize(monitor, genOptions); - executeTransformation(); - } catch (final TransformationException e) { - // unload all resources in case of an exception - ModelManagement.getResourceSet().getResources().clear(); - printAndDisplayErrorMessage(e, Messages.InstantiateDepPlan_TransformationException, false); - } catch (final Exception e) { - // unload all resources in case of an exception - ModelManagement.getResourceSet().getResources().clear(); - printAndDisplayErrorMessage(e, Messages.InstantiateDepPlan_ErrorsDuringTransformation, true); - } finally { - TransformationContext.current = null; - } - } - - private void initialize(IProgressMonitor monitor, int genOptions) throws TransformationException { - this.monitor = monitor; - this.generationOptions = genOptions; - } - - protected void executeTransformation() throws Exception { - ModelManagement intermediateModelManagement = null; - UIContext.monitor = monitor; - UIContext.configureProject = (generationOptions & GenerationOptions.REWRITE_SETTINGS) != 0; - - // 1a: create a new model (and applies same profiles / imports) - Model existingModel = srcModelComponentDeploymentPlan.getModel(); - TransformationContext tc = new TransformationContext(); - TransformationContext.current = tc; - TransformationContext.initialSourceRoot = existingModel; - TransformationContext.initialDeploymentPlan = srcModelComponentDeploymentPlan; - tc.project = project; - - intermediateModelManagement = ModelManagement.createNewModel(existingModel.getName()); - TransformationContext.current.mm = intermediateModelManagement; - - // get the temporary model - Package intermediateModel = intermediateModelManagement.getModel(); - - // create a package for global enumerations that are used by xtend code - EnumService.createEnumPackage(intermediateModel); - - // create a lazy copier towards the intermediate model - LazyCopier intermediateModelCopier = - new LazyCopier(existingModel, intermediateModel, CopyExtResources.ALL, true); - intermediateModelCopier.preCopyListeners.add(FilterLoadReferencedModels.getInstance()); - - Map<InstanceSpecification, InstanceSpecification> instanceMap = new HashMap<InstanceSpecification, InstanceSpecification>(); - - if (DepUtils.isDeploymentPlan(srcModelComponentDeploymentPlan)) { - // deployment plan - copy top-level instances - for (InstanceSpecification instance : DepUtils.getInstances(srcModelComponentDeploymentPlan)) { - // InstanceSpecification newInstance = mainModelTrafo.transformInstance(instance, null); - InstanceSpecification newInstance = intermediateModelCopier.getCopy(instance); - - checkProgressStatus(); - TransformationUtil.propagateAllocation(newInstance); - instanceMap.put(instance, newInstance); - } - } - else { - // no deployment plan - copy all packaged elements - intermediateModelCopier.shallowCopy(srcModelComponentDeploymentPlan); - - for (PackageableElement pe : srcModelComponentDeploymentPlan.getPackagedElements()) { - intermediateModelCopier.getCopy(pe); - - checkProgressStatus(); - } - } - - tc.copier = intermediateModelCopier; - tc.deploymentPlan = intermediateModelCopier.getCopy(srcModelComponentDeploymentPlan); - tc.modelRoot = PackageUtil.getRootPackage(tc.deploymentPlan); - - M2MTrafoChain chain = TrafoUtils.getTransformationChain(tc.deploymentPlan); - - TemplateInstantiation.init(); - ExecuteTransformationChain.apply(chain, TrafoUtils.getAdditionalTransformations(srcModelComponentDeploymentPlan)); - - // setURIs and save (first update all URIs to ensure that model references use the - // correct URI before saving) - intermediateModelManagement.setURI(project, TEMP_MODEL_FOLDER, TEMP_MODEL_POSTFIX); - // also save additional root elements - for (ModelManagement mm : tc.copier.getAdditionalRootPkgs()) { - mm.setURI(project, TEMP_MODEL_FOLDER, TEMP_MODEL_POSTFIX); - } - intermediateModelManagement.save(); - for (ModelManagement mm : tc.copier.getAdditionalRootPkgs()) { - mm.save(); - } - - // -------------------------------------------------------------------- - checkProgressStatus(); - // -------------------------------------------------------------------- - - intermediateModelManagement.dispose(); - // also dispose additional models - for (ModelManagement mm : tc.copier.getAdditionalRootPkgs()) { - mm.dispose(); - } - } - - /** - * - * @param canonicalProjectName - * the automatically calculated project name - * @param userProjectName - * the project name choosen by the user - */ - public void updateProjectMapping(final String canonicalProjectName, final String userProjectName) { - CommandSupport.exec(srcModelComponentDeploymentPlan, "Update project mapping", new Runnable() { - - @Override - public void run() { - DeploymentPlan depPlan = UMLUtil.getStereotypeApplication(srcModelComponentDeploymentPlan, DeploymentPlan.class); - String mapName = canonicalProjectName + "=" + userProjectName; - for (String mapping : depPlan.getProjectMappings()) { - if (mapping.startsWith(canonicalProjectName)) { - mapping = mapName; - return; - } - } - depPlan.getProjectMappings().add(mapName); - } - }); - - } - - private void checkProgressStatus() throws InterruptedException { - if (monitor.isCanceled()) { - throw new InterruptedException(); - } - monitor.worked(1); - } - - private void printAndDisplayErrorMessage(Exception e, final String title, final boolean consultConsole) { - String message = e.toString(); - if (consultConsole) { - message = message + "\n\n" //$NON-NLS-1$ - + Messages.InstantiateDepPlan_ConsultConsole; - } - - printAndDisplayErrorMessage(e, title, message, consultConsole); - } - - private void printAndDisplayErrorMessage(Exception e, final String title, final String message, final boolean consultConsole) { - e.printStackTrace(); - // only display message, if not running headless - if (!TestInfo.runsHeadless()) { - displayError(title, message); - } - Activator.log.error(e); - } - - private void displayError(final String title, final String message) { - Display.getDefault().syncExec(new Runnable() { - @Override - public void run() { - Shell shell = Display.getCurrent().getActiveShell(); - MessageDialog.openInformation(shell, title, message); - } - }); - } -} diff --git a/plugins/transformation/org.eclipse.papyrus.designer.transformation.ui/src/org/eclipse/papyrus/designer/transformation/ui/handlers/InstantiateDepPlanHandler.java b/plugins/transformation/org.eclipse.papyrus.designer.transformation.ui/src/org/eclipse/papyrus/designer/transformation/ui/handlers/InstantiateDepPlanHandler.java index f7af8372e..b580e5d96 100644 --- a/plugins/transformation/org.eclipse.papyrus.designer.transformation.ui/src/org/eclipse/papyrus/designer/transformation/ui/handlers/InstantiateDepPlanHandler.java +++ b/plugins/transformation/org.eclipse.papyrus.designer.transformation.ui/src/org/eclipse/papyrus/designer/transformation/ui/handlers/InstantiateDepPlanHandler.java @@ -25,7 +25,7 @@ import org.eclipse.core.runtime.Status; import org.eclipse.core.runtime.jobs.Job; import org.eclipse.papyrus.designer.deployment.profile.Deployment.DeploymentPlan; import org.eclipse.papyrus.designer.transformation.base.utils.ProjectManagement; -import org.eclipse.papyrus.designer.transformation.core.transformations.InstantiateDepPlan; +import org.eclipse.papyrus.designer.transformation.core.transformations.ExecuteTransformationChain; import org.eclipse.papyrus.designer.transformation.profile.Transformation.ExecuteTrafoChain; import org.eclipse.papyrus.uml.diagram.common.handlers.CmdHandler; import org.eclipse.papyrus.uml.tools.utils.StereotypeUtil; @@ -67,7 +67,7 @@ public class InstantiateDepPlanHandler extends CmdHandler { @Override public IStatus runInUIThread(IProgressMonitor monitor) { // execute the task ... - new InstantiateDepPlan().instantiate(selectedCDP, monitor, project, 0); + new ExecuteTransformationChain(selectedCDP, project).executeTransformation(monitor, 0); return Status.OK_STATUS; } }; |