diff options
author | Ansgar Radermacher | 2013-11-25 12:56:15 +0000 |
---|---|---|
committer | Ansgar Radermacher | 2013-11-25 13:05:36 +0000 |
commit | 20b15b903e161a371eef82c5177d6faf9ddaedf0 (patch) | |
tree | 875cc9d313cd3a4418f38678f5742f0cb6d5ec1c /extraplugins/qompass-designer | |
parent | 5174c804212ca9c264795af43c1f618c766ed3a4 (diff) | |
download | org.eclipse.papyrus-20b15b903e161a371eef82c5177d6faf9ddaedf0.tar.gz org.eclipse.papyrus-20b15b903e161a371eef82c5177d6faf9ddaedf0.tar.xz org.eclipse.papyrus-20b15b903e161a371eef82c5177d6faf9ddaedf0.zip |
- Initial fix [QDesginer] Not possible to apply container transformation without deployment plan
Diffstat (limited to 'extraplugins/qompass-designer')
5 files changed, 500 insertions, 33 deletions
diff --git a/extraplugins/qompass-designer/org.eclipse.papyrus.qompass.designer.core/src/org/eclipse/papyrus/qompass/designer/core/transformations/InstantiateDepPlan.java b/extraplugins/qompass-designer/org.eclipse.papyrus.qompass.designer.core/src/org/eclipse/papyrus/qompass/designer/core/transformations/InstantiateDepPlan.java index 1f2f17f21f3..69cb1fa0bd9 100644 --- a/extraplugins/qompass-designer/org.eclipse.papyrus.qompass.designer.core/src/org/eclipse/papyrus/qompass/designer/core/transformations/InstantiateDepPlan.java +++ b/extraplugins/qompass-designer/org.eclipse.papyrus.qompass.designer.core/src/org/eclipse/papyrus/qompass/designer/core/transformations/InstantiateDepPlan.java @@ -31,6 +31,7 @@ import org.eclipse.papyrus.FCM.DeploymentPlan; import org.eclipse.papyrus.FCM.util.MapUtil; import org.eclipse.papyrus.acceleo.AcceleoDriver; import org.eclipse.papyrus.qompass.designer.core.Log; +import org.eclipse.papyrus.qompass.designer.core.Messages; import org.eclipse.papyrus.qompass.designer.core.ModelManagement; import org.eclipse.papyrus.qompass.designer.core.ProjectManagement; import org.eclipse.papyrus.qompass.designer.core.StUtils; @@ -114,8 +115,9 @@ public class InstantiateDepPlan { Configuration configuration = null; if(cdpOrConfig instanceof Package) { cdp = (Package)cdpOrConfig; - MainModelTrafo.setConfiguration(null); - } else if(StereotypeUtil.isApplied(cdpOrConfig, Configuration.class)) { + RuleManagement.setConfiguration(null); + } + else if(StereotypeUtil.isApplied(cdpOrConfig, Configuration.class)) { configuration = UMLUtil.getStereotypeApplication(cdpOrConfig, Configuration.class); DeploymentPlan fcmCDP = configuration.getDeploymentPlan(); if(fcmCDP == null) { @@ -124,13 +126,14 @@ public class InstantiateDepPlan { public void run() { Shell shell = new Shell(); - MessageDialog.openError(shell, "Cannot generate model", "The stereotype attribute <deploymentPlan> of configuration <" + config.getName() + "> is not initialized"); + MessageDialog.openError(shell, Messages.InstantiateDepPlan_CannotGenModel, + String.format(Messages.InstantiateDepPlan_DepPlanStereotypeNotInitialized, config.getName())); } }); return; } cdp = fcmCDP.getBase_Package(); - MainModelTrafo.setConfiguration(configuration); + RuleManagement.setConfiguration(configuration); } else { return; } @@ -151,7 +154,7 @@ public class InstantiateDepPlan { if(generateCode) { steps += nodes.size(); } - monitor.beginTask("Generating deployment model ...", steps); + monitor.beginTask(Messages.InstantiateDepPlan_InfoGeneratingModel, steps); if(monitor.isCanceled()) { return; } @@ -182,7 +185,7 @@ public class InstantiateDepPlan { Copy.copyID(existingModel, tmpModel); // 1b: reify the connectors "into" the new model - monitor.subTask("expanding connectors and containers"); + monitor.subTask(Messages.InstantiateDepPlan_InfoExpandingConnectors); // obtain reference to CDP in target model // @@ -190,7 +193,8 @@ public class InstantiateDepPlan { Package tmCDP = (Package)tmpCopy.get(cdp); ContainerTrafo.init(); - InstanceSpecification newRootIS = MainModelTrafo.mainModelTrafo(tmpCopy, tmCDP, rootIS, null); + MainModelTrafo mainModelTrafo = new MainModelTrafo(tmpCopy, tmCDP); + InstanceSpecification newRootIS = mainModelTrafo.transformInstance(rootIS, null); monitor.worked(1); // 1c: late bindings @@ -213,21 +217,21 @@ public class InstantiateDepPlan { nodes = AllocUtils.getAllNodes(newRootIS); if(nodes.size() == 0) { - throw new TransformationException("None of the instances in the deployment plan is allocated to a node. Verify the node allocation."); + throw new TransformationException(Messages.InstantiateDepPlan_InfoNoneAllocated); } int nodeIndex = 0; Classifier cl = DepUtils.getClassifier(rootIS); - String targetLanguage = DepUtils.getLanguageFromClassifier(cl); + String targetLanguage = DepUtils.getLanguageFromPackage(cl.getNearestPackage()); if (targetLanguage == null) { - targetLanguage = "C++"; + targetLanguage = "C++"; //$NON-NLS-1$ } for(InstanceSpecification node : nodes) { - String modelName = existingModel.getName() + "_" + node.getName(); + String modelName = existingModel.getName() + "_" + node.getName(); //$NON-NLS-1$ if(configuration != null) { - modelName += "_" + configuration.getBase_Class().getName(); + modelName += "_" + configuration.getBase_Class().getName(); //$NON-NLS-1$ } else { - modelName += "_" + cdp.getName(); + modelName += "_" + cdp.getName(); //$NON-NLS-1$ } ModelManagement genMM = createTargetModel(existingModel, monitor, MapUtil.rootModelName, false); Model genModel = genMM.getModel(); @@ -246,7 +250,7 @@ public class InstantiateDepPlan { targetCopy.preCopyListeners.add(FilterRuleApplication.getInstance()); targetCopy.postCopyListeners.add(InstantiateCppIncludeWOB.getInstance()); - monitor.setTaskName("deploying for node " + node.getName()); + monitor.setTaskName(String.format(Messages.InstantiateDepPlan_InfoDeployingForNode, node.getName())); ILangSupport langSupport = LanguageSupport.getLangSupport(targetLanguage); langSupport.resetConfigurationData(); @@ -262,7 +266,7 @@ public class InstantiateDepPlan { // Due to the copying of imports, the top-level package has changed which implies that new // derived interfaces are put into a different package and the derivedInterfaces package in // the original root becomes obsolete. Delete this obsolete package, if existing. - NamedElement derivedInterfaces = Utils.getQualifiedElement(genModel, "root::derivedInterfaces"); + NamedElement derivedInterfaces = Utils.getQualifiedElement(genModel, "root::derivedInterfaces"); //$NON-NLS-1$ if(derivedInterfaces instanceof Package) { derivedInterfaces.destroy(); } @@ -317,7 +321,7 @@ public class InstantiateDepPlan { public void run() { Shell shell = new Shell(); - MessageDialog.openError(shell, "A transformation exception occurred", teFinal.getMessage()); //$NON-NLS-1$ + MessageDialog.openError(shell, Messages.InstantiateDepPlan_TransformationException, teFinal.getMessage()); } }); Log.log(Status.ERROR, Log.DEPLOYMENT, "", teFinal); //$NON-NLS-1$ @@ -329,8 +333,8 @@ public class InstantiateDepPlan { public void run() { Shell shell = new Shell(); String msg = eFinal.toString() + "\n\n" + //$NON-NLS-1$ - "Consult error log or console for details"; //$NON-NLS-1$ - MessageDialog.openError(shell, "An error occurred during transformation", msg); //$NON-NLS-1$ + Messages.InstantiateDepPlan_ConsultConsole; + MessageDialog.openError(shell, Messages.InstantiateDepPlan_ErrorsDuringTransformation, msg); } }); Log.log(Status.ERROR, Log.DEPLOYMENT, "", e); //$NON-NLS-1$ @@ -342,8 +346,8 @@ public class InstantiateDepPlan { Display.getDefault().syncExec(new Runnable() { public void run() { Shell shell = new Shell(); - MessageDialog.openInformation(shell, "Acceleo errors occured", //$NON-NLS-1$ - "Acceleo errors occured during code generation. Please check the error log"); //$NON-NLS-1$ + MessageDialog.openInformation(shell, Messages.InstantiateDepPlan_AcceleoErrors, + Messages.InstantiateDepPlan_AcceleoErrorsCheckLog); } }); } @@ -367,7 +371,7 @@ public class InstantiateDepPlan { // copy profile application for(Profile profile : existingModel.getAppliedProfiles()) { // reload profile in resource of new model - monitor.subTask("apply profile " + profile.getQualifiedName()); + monitor.subTask(Messages.InstantiateDepPlan_InfoApplyProfile + profile.getQualifiedName()); if(profile.eResource() == null) { String profileName = profile.getQualifiedName(); @@ -375,12 +379,12 @@ public class InstantiateDepPlan { if(profile instanceof MinimalEObjectImpl.Container) { URI uri = ((MinimalEObjectImpl.Container)profile).eProxyURI(); if(uri != null) { - throw new TransformationException("Check input model: the applied profile with URI \"" + uri + "\" has no name and is not contained in a resource"); + throw new TransformationException(String.format(Messages.InstantiateDepPlan_CheckInputModelProfileNoRes, uri)); } } - throw new TransformationException("Check input model: one of the applied profiles has no name and is not contained in a resource"); + throw new TransformationException(Messages.InstantiateDepPlan_CheckInputModelProfileNoResNoName); } - throw new TransformationException("Check input model: profile \"" + profileName + "\" is not contained in a resource"); + throw new TransformationException(String.format(Messages.InstantiateDepPlan_CheckInputModelProfile3, profileName)); } Resource profileResource = null; @@ -410,7 +414,7 @@ public class InstantiateDepPlan { newModel.applyProfile(newProfile); } } catch (IllegalArgumentException e) { - throw new TransformationException("An Illegal argument exception occured during the copy of profile applications. This may indicate that the original model contains an invalid profile application\n\n" + e.toString()); + throw new TransformationException(Messages.InstantiateDepPlan_IllegalArgumentDuringCopy + e.toString()); } // copy imports (and load resources associated - TODO: might not be necessary) @@ -421,24 +425,24 @@ public class InstantiateDepPlan { if(copyImports) { for(Package importedPackage : existingModel.getImportedPackages()) { if(importedPackage == null) { - throw new TransformationException("An imported package is null. Verify the imported packages"); + throw new TransformationException(Messages.InstantiateDepPlan_CheckInputImportPkg); } if(importedPackage.eResource() == null) { - String errorMsg = "An imported package has no eResource. Verify imported packages"; + String errorMsg = Messages.InstantiateDepPlan_CheckInputImportPkgNoRes; if(importedPackage instanceof MinimalEObjectImpl.Container) { URI uri = ((MinimalEObjectImpl.Container)importedPackage).eProxyURI(); if(uri != null) { - errorMsg += " - URI: " + uri.devicePath(); + errorMsg += " - URI: " + uri.devicePath(); //$NON-NLS-1$ } } throw new TransformationException(errorMsg); } newModel.createPackageImport(importedPackage); - monitor.subTask("import package " + importedPackage.getName()); + monitor.subTask(String.format(Messages.InstantiateDepPlan_InfoImportPackage, importedPackage.getName())); try { importedPackage.eResource().load(null); - newModel.getMember("dummy"); // force loading of model + newModel.getMember("dummy"); // force loading of model //$NON-NLS-1$ } catch (IOException e) { throw new TransformationException(e.getMessage()); } diff --git a/extraplugins/qompass-designer/org.eclipse.papyrus.qompass.designer.core/src/org/eclipse/papyrus/qompass/designer/core/transformations/RuleManagement.java b/extraplugins/qompass-designer/org.eclipse.papyrus.qompass.designer.core/src/org/eclipse/papyrus/qompass/designer/core/transformations/RuleManagement.java new file mode 100644 index 00000000000..2afa92530b3 --- /dev/null +++ b/extraplugins/qompass-designer/org.eclipse.papyrus.qompass.designer.core/src/org/eclipse/papyrus/qompass/designer/core/transformations/RuleManagement.java @@ -0,0 +1,32 @@ +package org.eclipse.papyrus.qompass.designer.core.transformations; + +import org.eclipse.papyrus.FCM.ConfigOption; +import org.eclipse.papyrus.FCM.Configuration; +import org.eclipse.papyrus.FCM.ContainerRule; + +public class RuleManagement { + private static Configuration m_config; + + public static void setConfiguration(Configuration config) { + m_config = config; + } + + /** + * check whether a rule is active in a given configuration + * + * @param aRule + * @return + */ + public static boolean isRuleActive(ContainerRule rule) { + if(m_config != null) { + for(ConfigOption option : m_config.getConfigOptions()) { + if(rule.getForConfig().contains(option)) { + return true; + } + } + } + // not already true via specific configuration. + // => Also turn on rules by default that are not for a specific configuration option + return (rule.getForConfig().size() == 0); + } +} diff --git a/extraplugins/qompass-designer/org.eclipse.papyrus.qompass.designer.core/src/org/eclipse/papyrus/qompass/designer/core/transformations/TrafoAndCodegenPackage.java b/extraplugins/qompass-designer/org.eclipse.papyrus.qompass.designer.core/src/org/eclipse/papyrus/qompass/designer/core/transformations/TrafoAndCodegenPackage.java new file mode 100644 index 00000000000..13592311d51 --- /dev/null +++ b/extraplugins/qompass-designer/org.eclipse.papyrus.qompass.designer.core/src/org/eclipse/papyrus/qompass/designer/core/transformations/TrafoAndCodegenPackage.java @@ -0,0 +1,361 @@ +/***************************************************************************** + * Copyright (c) 2013 CEA LIST. + * + * + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Ansgar Radermacher ansgar.radermacher@cea.fr + * + *****************************************************************************/ + +package org.eclipse.papyrus.qompass.designer.core.transformations; + +import java.io.IOException; + +import org.eclipse.core.resources.IProject; +import org.eclipse.core.resources.ResourcesPlugin; +import org.eclipse.core.runtime.IProgressMonitor; +import org.eclipse.core.runtime.Status; +import org.eclipse.emf.common.util.BasicEList; +import org.eclipse.emf.common.util.EList; +import org.eclipse.emf.common.util.URI; +import org.eclipse.emf.common.util.WrappedException; +import org.eclipse.emf.ecore.impl.MinimalEObjectImpl; +import org.eclipse.emf.ecore.resource.Resource; +import org.eclipse.jface.dialogs.MessageDialog; +import org.eclipse.papyrus.FCM.ContainerRule; +import org.eclipse.papyrus.FCM.ContainerRuleKind; +import org.eclipse.papyrus.FCM.util.FCMUtil; +import org.eclipse.papyrus.acceleo.AcceleoDriver; +import org.eclipse.papyrus.qompass.designer.core.Log; +import org.eclipse.papyrus.qompass.designer.core.Messages; +import org.eclipse.papyrus.qompass.designer.core.ModelManagement; +import org.eclipse.papyrus.qompass.designer.core.StUtils; +import org.eclipse.papyrus.qompass.designer.core.Utils; +import org.eclipse.papyrus.qompass.designer.core.acceleo.EnumService; +import org.eclipse.papyrus.qompass.designer.core.deployment.DepUtils; +import org.eclipse.papyrus.qompass.designer.core.extensions.ILangSupport; +import org.eclipse.papyrus.qompass.designer.core.extensions.LanguageSupport; +import org.eclipse.papyrus.qompass.designer.core.generate.GenerateCode; +import org.eclipse.papyrus.qompass.designer.core.templates.InstantiateCppIncludeWOB; +import org.eclipse.papyrus.qompass.designer.core.transformations.filters.FilterComments; +import org.eclipse.papyrus.qompass.designer.core.transformations.filters.FilterTemplate; +import org.eclipse.swt.widgets.Display; +import org.eclipse.swt.widgets.Shell; +import org.eclipse.uml2.uml.Class; +import org.eclipse.uml2.uml.Element; +import org.eclipse.uml2.uml.Model; +import org.eclipse.uml2.uml.Package; +import org.eclipse.uml2.uml.PackageableElement; +import org.eclipse.uml2.uml.Profile; + +/** + * This class executes all transformations during the instantiation of a + * deployment plan, i.e. + * 1. The reification of connectors (including template instantiation). This transformation targets a new model + * 2. Adding get_p/connect_q operations to a class (transformation within same model) + * 3. Remove all component types + * 4. distribute to nodes + * + * @author ansgar + * + */ +public class TrafoAndCodegenPackage { + + /** + * Iterate over source model and apply transformation + * @param copy + * @param pkg + * @throws TransformationException + */ + public static void applyTrafo(Copy copy, Package pkg) throws TransformationException { + EList<PackageableElement> peList = new BasicEList<PackageableElement>(); + peList.addAll(pkg.getPackagedElements()); + for(PackageableElement element : peList) { + if(element instanceof Package) { + applyTrafo(copy, (Package)element); + } + else if(element instanceof Class) { + + Class smImplementation = (Class)element; + Class tmImplementation = copy.getCopy(smImplementation); + + // get container trafo instance, if already existing + AbstractContainerTrafo containerTrafo = ContainerTrafo.get(tmImplementation); + + // we may not apply the transformation to the boot-loader itself, in particular it would transform + // singletons into pointers. + EList<ContainerRule> rules = FCMUtil.getAllContainerRules(smImplementation); + for(ContainerRule rule : rules) { + // if(RuleManagement.isRuleActive(rule)) { + // at least one active rule => create container (or get previously instantiated)) + if(rule.getKind() == ContainerRuleKind.LIGHT_WEIGHT_OO_RULE) { + if (containerTrafo == null) { + // container does not exist yet, create + containerTrafo = new LWContainerTrafo(copy, null); + containerTrafo.createContainer(smImplementation, tmImplementation); + } + containerTrafo.applyRule(rule, smImplementation, tmImplementation); + } + } + // } + } + } + } + + /** + * Instantiate a deployment plan, i.e. generate an intermediate model via a sequence of transformations + * + * @param cdpOrConfig 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 + */ + public static void instantiate(Element cdpOrConfig, IProgressMonitor monitor, IProject project) { + if(project == null) { + String projectName = cdpOrConfig.eResource().getURI().toString(); + project = ResourcesPlugin.getWorkspace().getRoot().getProject(projectName); + } + Model tmpModel = null; + ModelManagement tmpMM = null; + + AcceleoDriver.clearErrors(); + Package selectedPkg; + if(cdpOrConfig instanceof Package) { + selectedPkg = (Package)cdpOrConfig; + RuleManagement.setConfiguration(null); + } + else { + return; + } + + try { + EnumService.init(); + // Package copyCDP = dt.getCopyCDT (selectedCDP); + + // -- calc # of steps for progress monitor + // 1 (tmpModel creation) + 1 (reification) + 1 (tmpModel save) + // 5x on each deployed node (see below) + // problem? Connector reification is a single, relatively long step + int steps = 3; + + monitor.beginTask(Messages.InstantiateDepPlan_InfoGeneratingModel, steps); + if(monitor.isCanceled()) { + return; + } + + // 1a: create a new model (and applies same profiles / imports) + Model existingModel = selectedPkg.getModel(); + TransformationContext.sourceRoot = existingModel; + tmpMM = createTargetModel(existingModel, monitor, existingModel.getName(), true); + tmpModel = tmpMM.getModel(); + // Declare that the new model is a derivedElement (kind of hack, since the source + // element (attribute of derive element) remains undefined). This is used to + // de-activate automatic transformations that should not be applied to the generated + // model. + monitor.worked(1); + if(monitor.isCanceled()) { + return; + } + + // LateEval.clear(); + + EnumService.createEnumPackage(tmpModel); + + Copy tmpCopy = new Copy(existingModel, tmpModel, false); + tmpCopy.preCopyListeners.add(FilterTemplate.getInstance()); + tmpCopy.preCopyListeners.add(FilterComments.getInstance()); + tmpCopy.postCopyListeners.add(InstantiateCppIncludeWOB.getInstance()); + + Copy.copyID(existingModel, tmpModel); + + // 1b: reify the connectors "into" the new model + monitor.subTask(Messages.InstantiateDepPlan_InfoExpandingConnectors); + + // obtain reference to CDP in target model + + ContainerTrafo.init(); + monitor.worked(1); + + // create recursive copy of selectedPackage + tmpCopy.getCopy(selectedPkg); + + // apply container transformation + applyTrafo(tmpCopy, selectedPkg); + + // 1c: late bindings + // LateEval.bindLateOperations(); + // 3: distribute to nodes + + String tmpPath = tmpMM.getPath(project, InstantiateDepPlan.TEMP_MODEL_FOLDER, tmpModel.getName() + InstantiateDepPlan.TEMP_MODEL_POSTFIX); + tmpMM.saveModel(tmpPath); + + String targetLanguage = DepUtils.getLanguageFromPackage(selectedPkg); + if (targetLanguage == null) { + targetLanguage = "C++"; //$NON-NLS-1$ + } + // genProject = project + ModelManagement genMM = tmpMM; + IProject genProject = project; + ILangSupport langSupport = LanguageSupport.getLangSupport(targetLanguage); + langSupport.resetConfigurationData(); + + langSupport.setProject(genProject); + + GenerateCode codeGen = new GenerateCode(genProject, langSupport, genMM, monitor); + codeGen.generate(null, targetLanguage, false); + + genMM.dispose(); + + if(monitor.isCanceled()) { + return; + } + monitor.worked(1); + + } catch (TransformationException te) { + // Get UI thread to show dialog + final TransformationException teFinal = te; + Display.getDefault().syncExec(new Runnable() { + + public void run() { + Shell shell = new Shell(); + MessageDialog.openError(shell, Messages.InstantiateDepPlan_TransformationException, teFinal.getMessage()); + } + }); + Log.log(Status.ERROR, Log.DEPLOYMENT, "", teFinal); //$NON-NLS-1$ + } catch (Exception e) { + final Exception eFinal = e; + e.printStackTrace(); + Display.getDefault().syncExec(new Runnable() { + + public void run() { + Shell shell = new Shell(); + String msg = eFinal.toString() + "\n\n" + //$NON-NLS-1$ + Messages.InstantiateDepPlan_ConsultConsole; + MessageDialog.openError(shell, Messages.InstantiateDepPlan_ErrorsDuringTransformation, msg); + } + }); + Log.log(Status.ERROR, Log.DEPLOYMENT, "", e); //$NON-NLS-1$ + } + if(tmpMM != null) { + tmpMM.dispose(); + } + if (AcceleoDriver.hasErrors()) { + Display.getDefault().syncExec(new Runnable() { + public void run() { + Shell shell = new Shell(); + MessageDialog.openInformation(shell, Messages.InstantiateDepPlan_AcceleoErrors, + Messages.InstantiateDepPlan_AcceleoErrorsCheckLog); + } + }); + } + + } + + + /** + * Create a new empty model from an existing model that applies the same + * profiles and has the same imports + * + * @param existingModel + * @return + */ + public static ModelManagement createTargetModel(Model existingModel, IProgressMonitor monitor, String name, boolean copyImports) throws TransformationException { + ModelManagement mm = new ModelManagement(); + Model newModel = mm.getModel(); + newModel.setName(name); + + try { + // copy profile application + for(Profile profile : existingModel.getAppliedProfiles()) { + // reload profile in resource of new model + monitor.subTask(Messages.InstantiateDepPlan_InfoApplyProfile + profile.getQualifiedName()); + + if(profile.eResource() == null) { + String profileName = profile.getQualifiedName(); + if(profileName == null) { + if(profile instanceof MinimalEObjectImpl.Container) { + URI uri = ((MinimalEObjectImpl.Container)profile).eProxyURI(); + if(uri != null) { + throw new TransformationException(String.format(Messages.InstantiateDepPlan_CheckInputModelProfileNoRes, uri)); + } + } + throw new TransformationException(Messages.InstantiateDepPlan_CheckInputModelProfileNoResNoName); + } + throw new TransformationException(String.format(Messages.InstantiateDepPlan_CheckInputModelProfile3, profileName)); + } + + Resource profileResource = null; + try { + profileResource = ModelManagement.getResourceSet().getResource(profile.eResource().getURI(), true); + } catch (WrappedException e) { + // read 2nd time (some diagnostic errors are raised only once) + Log.log(Status.WARNING, Log.DEPLOYMENT, "Warning: exception in profile.eResource() " + e.getMessage()); //$NON-NLS-1$ + profileResource = ModelManagement.getResourceSet().getResource(profile.eResource().getURI(), true); + } + Profile newProfileTop = (Profile)profileResource.getContents().get(0); + Profile newProfile; + String qname = profile.getQualifiedName(); + if((qname != null) && qname.contains("::")) { //$NON-NLS-1$ + // profile is a sub-profile within same resource + // TODO: should Copy class copy profile applications? + // Should be handled in shallowContainer class. + // if we put profile/newProfile pair into copy map, copy would find (and copy profile + // applications in sub-folders + qname = qname.substring(qname.indexOf("::") + 2); //$NON-NLS-1$ + newProfile = (Profile)Utils.getQualifiedElement(newProfileTop, qname); + } + else { + newProfile = newProfileTop; + } + newProfile.getMember("dummy"); // force profile loading //$NON-NLS-1$ + newModel.applyProfile(newProfile); + } + } catch (IllegalArgumentException e) { + throw new TransformationException(Messages.InstantiateDepPlan_IllegalArgumentDuringCopy + e.toString()); + } + + // copy imports (and load resources associated - TODO: might not be necessary) + // While this is useful in general, it implies that code for imported models + // has been generated and compiled (for the right target) into a library. This may be + // quite tedious, unless automatically managed. + // Therefore we do not activate this option in a first pass of the model transformations. + if(copyImports) { + for(Package importedPackage : existingModel.getImportedPackages()) { + if(importedPackage == null) { + throw new TransformationException(Messages.InstantiateDepPlan_CheckInputImportPkg); + } + if(importedPackage.eResource() == null) { + String errorMsg = Messages.InstantiateDepPlan_CheckInputImportPkgNoRes; + if(importedPackage instanceof MinimalEObjectImpl.Container) { + URI uri = ((MinimalEObjectImpl.Container)importedPackage).eProxyURI(); + if(uri != null) { + errorMsg += " - URI: " + uri.devicePath(); //$NON-NLS-1$ + } + } + throw new TransformationException(errorMsg); + } + newModel.createPackageImport(importedPackage); + monitor.subTask(String.format(Messages.InstantiateDepPlan_InfoImportPackage, importedPackage.getName())); + + try { + importedPackage.eResource().load(null); + newModel.getMember("dummy"); // force loading of model //$NON-NLS-1$ + } catch (IOException e) { + throw new TransformationException(e.getMessage()); + } + + } + } + + StUtils.copyStereotypes(existingModel, newModel); + + return mm; + } +} diff --git a/extraplugins/qompass-designer/org.eclipse.papyrus.qompass.designer.ui/plugin.xml b/extraplugins/qompass-designer/org.eclipse.papyrus.qompass.designer.ui/plugin.xml index 21846effdaf..8df44b89c05 100644 --- a/extraplugins/qompass-designer/org.eclipse.papyrus.qompass.designer.ui/plugin.xml +++ b/extraplugins/qompass-designer/org.eclipse.papyrus.qompass.designer.ui/plugin.xml @@ -73,6 +73,13 @@ id="org.eclipse.papyrus.qompass.designer.ui.menuActions.AllocateCmd" name="dummy"> </command> + <command + categoryId="org.eclipse.papyrus.editor.category" + defaultHandler="org.eclipse.papyrus.qompass.designer.ui.handlers.TrafoAndCodegenHandler" + description="dummy" + id="org.eclipse.papyrus.qompass.designer.ui.menuActions.TrafoAndCodegenCmd" + name="dummy"> + </command> </extension> <extension point="org.eclipse.ui.menus"> @@ -184,7 +191,6 @@ icon="icons/selContainer.gif" id="org.eclipse.papyrus.qompass.designer.ui.menuActions.ConfigurePortsMenu" label="Qompass: Configure ports" - mode="FORCE_TEXT" style="push"> <visibleWhen checkEnabled="true"> @@ -196,7 +202,6 @@ id="org.eclipse.papyrus.qompass.designer.ui.menuActions.AddProfileAndModelLibsMenu" label="Qompass: Add profiles and model libraries" mnemonic="P" - mode="FORCE_TEXT" style="push"> <visibleWhen checkEnabled="true"> @@ -208,7 +213,16 @@ id="org.eclipse.papyrus.qompass.designer.ui.menuActions.AllocateMenu" label="Qompass: Allocate to node" mnemonic="A" - mode="FORCE_TEXT" + style="push"> + <visibleWhen + checkEnabled="true"> + </visibleWhen> + </command> + <command + commandId="org.eclipse.papyrus.qompass.designer.ui.menuActions.TrafoAndCodegenCmd" + icon="icons/deploy.gif" + id="org.eclipse.papyrus.qompass.designer.ui.menuActions.TrafoAndCodegenCmd" + label="Qompass: Execute transformation and generate code (w/o deployment)" style="push"> <visibleWhen checkEnabled="true"> diff --git a/extraplugins/qompass-designer/org.eclipse.papyrus.qompass.designer.ui/src/org/eclipse/papyrus/qompass/designer/ui/handlers/TrafoAndCodegenHandler.java b/extraplugins/qompass-designer/org.eclipse.papyrus.qompass.designer.ui/src/org/eclipse/papyrus/qompass/designer/ui/handlers/TrafoAndCodegenHandler.java new file mode 100644 index 00000000000..cb3c63e3557 --- /dev/null +++ b/extraplugins/qompass-designer/org.eclipse.papyrus.qompass.designer.ui/src/org/eclipse/papyrus/qompass/designer/ui/handlers/TrafoAndCodegenHandler.java @@ -0,0 +1,56 @@ +package org.eclipse.papyrus.qompass.designer.ui.handlers; + +import org.eclipse.core.commands.ExecutionEvent; +import org.eclipse.core.commands.ExecutionException; +import org.eclipse.core.resources.IProject; +import org.eclipse.core.runtime.IProgressMonitor; +import org.eclipse.core.runtime.IStatus; +import org.eclipse.core.runtime.Status; +import org.eclipse.core.runtime.jobs.Job; +import org.eclipse.papyrus.qompass.designer.core.ProjectManagement; +import org.eclipse.papyrus.qompass.designer.core.transformations.TrafoAndCodegenPackage; +import org.eclipse.uml2.uml.Package; + +public class TrafoAndCodegenHandler extends CmdHandler { + /** + * {@inheritDoc} + */ + @Override + public boolean isEnabled() { + updateSelectedEObject(); + return (selectedEObject instanceof Package); + } + + /** + * {@inheritDoc} + */ + public Object execute(ExecutionEvent event) throws ExecutionException { + // only one model is selected + selectedPkg = null; + if(selectedEObject instanceof Package) { + selectedPkg = (Package)selectedEObject; + } else { + return null; + } + project = ProjectManagement.getCurrentProject(); + + Job job = new Job("Execute transformations and generate code") { + + @Override + protected IStatus run(IProgressMonitor monitor) { + // execute the task ... + TrafoAndCodegenPackage.instantiate(selectedPkg, monitor, project); + monitor.done(); + return Status.OK_STATUS; + } + }; + job.setUser(true); + job.schedule(); + + return null; + } + + protected Package selectedPkg; + + protected IProject project; +} |