Skip to main content
aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorRemi Schnekenburger2016-01-08 13:06:51 +0000
committerRemi Schnekenburger2016-01-08 13:09:06 +0000
commit7699488dacebed22c60befb7ca7158fb9572bb79 (patch)
tree4dc10510ebdf57438d3095f799a410dbc8d01bd7 /extraplugins/adl4eclipse/org.eclipse.papyrus.adl4eclipsetool/src
parent62c43ee924b01e4e0aed4f18410205084967776d (diff)
downloadorg.eclipse.papyrus-7699488dacebed22c60befb7ca7158fb9572bb79.tar.gz
org.eclipse.papyrus-7699488dacebed22c60befb7ca7158fb9572bb79.tar.xz
org.eclipse.papyrus-7699488dacebed22c60befb7ca7158fb9572bb79.zip
Bug 485417: [ADL4Eclipse] Provide some refactoring facilities to
facilitate usage of reversed models https://bugs.eclipse.org/bugs/show_bug.cgi?id=485417 - add the refactoring action - add icons to bundles/features - update the model template Change-Id: Ib8626099bfd618a3f4f485dd821fa35088cc57b0
Diffstat (limited to 'extraplugins/adl4eclipse/org.eclipse.papyrus.adl4eclipsetool/src')
-rw-r--r--extraplugins/adl4eclipse/org.eclipse.papyrus.adl4eclipsetool/src/org/eclipse/papyrus/adltool/designer/ArchitectureRefactoring.java409
-rw-r--r--extraplugins/adl4eclipse/org.eclipse.papyrus.adl4eclipsetool/src/org/eclipse/papyrus/adltool/designer/ArchitectureSnapshotDesigner.java1337
-rw-r--r--extraplugins/adl4eclipse/org.eclipse.papyrus.adl4eclipsetool/src/org/eclipse/papyrus/adltool/reversible/project/ReversibleFeature.java605
3 files changed, 1416 insertions, 935 deletions
diff --git a/extraplugins/adl4eclipse/org.eclipse.papyrus.adl4eclipsetool/src/org/eclipse/papyrus/adltool/designer/ArchitectureRefactoring.java b/extraplugins/adl4eclipse/org.eclipse.papyrus.adl4eclipsetool/src/org/eclipse/papyrus/adltool/designer/ArchitectureRefactoring.java
new file mode 100644
index 00000000000..ed682978115
--- /dev/null
+++ b/extraplugins/adl4eclipse/org.eclipse.papyrus.adl4eclipsetool/src/org/eclipse/papyrus/adltool/designer/ArchitectureRefactoring.java
@@ -0,0 +1,409 @@
+/*****************************************************************************
+ * Copyright (c) 2016 CEA LIST and others.
+ *
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * CEA LIST - Initial API and implementation
+ *
+ *****************************************************************************/
+
+package org.eclipse.papyrus.adltool.designer;
+
+import java.io.PrintStream;
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+
+import org.eclipse.core.runtime.Assert;
+import org.eclipse.core.runtime.IProgressMonitor;
+import org.eclipse.emf.common.command.Command;
+import org.eclipse.emf.transaction.RecordingCommand;
+import org.eclipse.emf.transaction.TransactionalEditingDomain;
+import org.eclipse.papyrus.adl4eclipse.org.ADL4Eclipse_StereotypesUtils;
+import org.eclipse.papyrus.adltool.Activator;
+import org.eclipse.papyrus.infra.core.services.ServiceException;
+import org.eclipse.papyrus.infra.emf.utils.ServiceUtilsForEObject;
+import org.eclipse.papyrus.osgi.profile.OSGIStereotypesUtils;
+import org.eclipse.papyrus.uml.tools.namereferences.NameReferencesHelper;
+import org.eclipse.uml2.uml.Comment;
+import org.eclipse.uml2.uml.Component;
+import org.eclipse.uml2.uml.Dependency;
+import org.eclipse.uml2.uml.Element;
+import org.eclipse.uml2.uml.NamedElement;
+import org.eclipse.uml2.uml.Package;
+import org.eclipse.uml2.uml.PackageableElement;
+import org.eclipse.uml2.uml.Property;
+import org.eclipse.uml2.uml.Type;
+import org.eclipse.uml2.uml.UMLFactory;
+
+/**
+ * Handler that refactors the model to be more human-readable.
+ */
+public class ArchitectureRefactoring {
+
+ /**
+ * Computes and return the command to refactor the model, eg move features and bundles to specific folders, simplifies name, create dependencies between features
+ *
+ * @param rootModel
+ * the model to refactor
+ * @param monitor
+ * the progres monitor
+ * @return the command to refacotr, or <code>null</code> if there were some issues to get the editing domain for the command
+ */
+ public static Command getRefactoringCommand(Package rootModel, IProgressMonitor monitor) {
+ TransactionalEditingDomain transactionalEditingDomain;
+ try {
+ transactionalEditingDomain = ServiceUtilsForEObject.getInstance().getTransactionalEditingDomain(rootModel);
+ return new RefactoringCommand(transactionalEditingDomain, rootModel, monitor);
+ } catch (ServiceException e) {
+ Activator.log.error(e);
+ }
+ return null;
+
+ }
+
+ /**
+ * Command executed to refactor the model
+ */
+ public static class RefactoringCommand extends RecordingCommand {
+
+ private Package model;
+ private Package featuresPackage;
+ private Package bundlesPackage;
+ private Package bundleDependenciesPackage;
+ private IProgressMonitor monitor;
+ private Package internalBundleDependenciesPackage;
+ private Package externalDependenciesPackage;
+ private Package papyrusToExternalsDependenciesPackage;
+ private Package externalsToPapyrusDependenciesPackage;
+
+ public RefactoringCommand(TransactionalEditingDomain domain, Package rootModel, IProgressMonitor monitor) {
+ super(domain, "Refactoring " + rootModel.getName(),
+ "Refactoring of the architecture model to be human readable");
+ this.model = rootModel;
+ this.monitor = monitor;
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ protected void doExecute() {
+ moveFeaturesAndBundles();
+ createFeatureDependencies();
+
+ // simplify names
+ simplifyNames();
+
+ }
+
+ protected void simplifyNames() {
+ simplifyFeatureNames();
+ simplifyBundleNames();
+ simplifyFeatureDependenciesNames();
+ }
+
+ protected void simplifyFeatureDependenciesNames() {
+ for (Package dependencyPackage : bundleDependenciesPackage.getNestedPackages()) {
+ for (PackageableElement dependency : dependencyPackage.getPackagedElements()) {
+ simplifyName(dependency);
+ }
+ }
+ }
+
+ protected void simplifyBundleNames() {
+ for (PackageableElement bundle : bundlesPackage.getPackagedElements()) {
+ if (isBundle(bundle)) {
+ simplifyName(bundle);
+ // simplifies also dependencies and property of the component
+ for (Property property : ((Component) bundle).getAttributes()) {
+ simplifyName(property);
+ }
+
+ // simplify dependencies
+ for (Dependency dependency : ((Component) bundle).getClientDependencies()) {
+ simplifyName(dependency);
+ }
+ }
+ }
+
+ }
+
+ protected void simplifyFeatureNames() {
+ for (PackageableElement feature : featuresPackage.getPackagedElements()) {
+ if (isFeature(feature)) {
+ simplifyName(feature);
+ // simplifies also dependencies and property of the component
+ for (Property property : ((Component) feature).getAttributes()) {
+ simplifyName(property);
+ }
+
+ // simplify dependencies
+ for (Dependency dependency : ((Component) feature).getClientDependencies()) {
+ simplifyName(dependency);
+ }
+ }
+ }
+
+ }
+
+ protected void moveFeaturesAndBundles() {
+ monitor.subTask("Moving Features & Bundles");
+ featuresPackage = (Package) model.createNestedPackage("Features");
+ bundlesPackage = (Package) model.createNestedPackage("Bundles");
+ bundleDependenciesPackage = (Package) model.createNestedPackage("BundleDependencies");
+ internalBundleDependenciesPackage = (Package) bundleDependenciesPackage.createNestedPackage("Internals");
+ externalDependenciesPackage = (Package) bundleDependenciesPackage.createNestedPackage("Externals");
+ papyrusToExternalsDependenciesPackage = (Package) bundleDependenciesPackage
+ .createNestedPackage("PapyrusToExternals");
+ externalsToPapyrusDependenciesPackage = (Package) bundleDependenciesPackage
+ .createNestedPackage("ExternalsToPapyrus");
+
+ List<PackageableElement> packageableElements = new ArrayList<>(model.getPackagedElements());
+ for (PackageableElement packageableElement : packageableElements) {
+ if (isBundle(packageableElement)) {
+ bundlesPackage.getPackagedElements().add(packageableElement);
+ } else if (isFeature(packageableElement)) {
+ featuresPackage.getPackagedElements().add(packageableElement);
+ }
+ monitor.worked(1);
+ }
+ }
+
+ protected void initMapPluginsToFeatures(Map<Component, Set<Component>> mapPluginToFeatures) {
+ monitor.subTask("Initializing Plugins to Features cache");
+ Assert.isNotNull(bundlesPackage, "Bundles Package should not be null here");
+ Assert.isNotNull(featuresPackage, "Features Package should not be null here");
+
+ for (PackageableElement element : featuresPackage.getPackagedElements()) {
+ if (isFeature(element)) {
+ for (Property ownedPlugin : ((Component) element).getOwnedAttributes()) {
+ Type type = ownedPlugin.getType();
+ if (isBundle(type)) {
+ // now insert it in the map or complete the map if
+ // this
+ // entry already exists
+ if (!mapPluginToFeatures.containsKey(type)) {
+ mapPluginToFeatures.put((Component) type, new HashSet<Component>());
+ } else {
+ Activator.log.debug("Warning: the plugin " + type.getName() + "[" + element.getName()
+ + "] has been found in several other features: "
+ + mapPluginToFeatures.get(type));
+ }
+ Set<Component> features = mapPluginToFeatures.get(type);
+ features.add((Component) element);
+ }
+ }
+ }
+ monitor.worked(1);
+ }
+
+ // pretty print for debug
+ for (Component plugin : mapPluginToFeatures.keySet()) {
+ PrintStream stream = System.out;
+ if (mapPluginToFeatures.get(plugin).size() != 1) {
+ stream = System.err;
+ }
+ stream.print(plugin.getName() + ": ");
+ Iterator<Component> featureIt = mapPluginToFeatures.get(plugin).iterator();
+ while (featureIt.hasNext()) {
+ Component feature = featureIt.next();
+ stream.print(feature.getName());
+ if (featureIt.hasNext()) {
+ stream.print(", ");
+ }
+ }
+ stream.println();
+ }
+
+ }
+
+ protected boolean isInternalFeature(Component feature) {
+ String name = feature.getName();
+ return (name != null) ? name.indexOf("org.eclipse.papyrus") == 0 : false;
+ }
+
+ protected void createFeatureDependencies() {
+ Map<Component, Set<Component>> mapPluginToFeatures = new HashMap<>();
+ initMapPluginsToFeatures(mapPluginToFeatures);
+
+ NameReferencesHelper helper = new NameReferencesHelper(model.eResource());
+
+ monitor.subTask("Creating Feature dependencies");
+ // browse all features
+ for (Element member : featuresPackage.getOwnedMembers()) {
+ if (isFeature(member)) {
+ Component feature = (Component) member;
+ // for all plugins contained in this feature ==> get the dependents plugins, and from these plugins, their containing feature and create a dependency if not already existing between the 2 features
+ for (Property child : feature.getOwnedAttributes()) {
+ // type of the child is the plugin (feature?) we want to
+ // check
+ Type plugin = child.getType();
+
+ // see the dependencies of that plugin, and get their owning features
+ if (isBundle(plugin)) {
+ for (Property property : ((Component) plugin).getOwnedAttributes()) {
+ Type referencedPlugin = property.getType();
+ if (isBundle(referencedPlugin)) {
+ // check the feature that ships this plugin
+ Set<Component> referencedFeatures = mapPluginToFeatures.get(referencedPlugin);
+ // there should be a dependency created from the current features to all these containing features
+ if (referencedFeatures != null && referencedFeatures.size() > 0
+ && !referencedFeatures.contains(feature)) {
+ for (Component referencedFeature : referencedFeatures) {
+ if (!feature.equals(referencedFeature) && referencedFeature != null) {
+ // check if dependency already exists. If not, create it
+ Dependency dependency = feature
+ .getClientDependency(referencedFeature.getName());
+ if (dependency == null) {
+ dependency = createDependency(referencedFeature.getName(), feature,
+ referencedFeature);
+
+ // move it to the right folder check client (is internal or external)
+ boolean isClientInternal = isInternalFeature(feature);
+
+ // check supplier
+ boolean isSupplierInternal = isInternalFeature(referencedFeature);
+
+ /*
+ * 4 possibilities:
+ * - Papyrus internals: client & supplier are Papyrus features
+ * - Papyrus to external component: client is Papyrus feature, supplier is not
+ * - External To External: client & supplier are external features
+ * - External to Papyrus (shall not exist yet): client is external, supplier is Papyrus
+ */
+ if (isClientInternal) {
+ if (isSupplierInternal) {
+ internalBundleDependenciesPackage.getPackagedElements()
+ .add(dependency);
+ } else {
+ papyrusToExternalsDependenciesPackage.getPackagedElements()
+ .add(dependency);
+ }
+ } else {
+ if (isSupplierInternal) {
+ externalsToPapyrusDependenciesPackage.getPackagedElements()
+ .add(dependency);
+ } else {
+ externalDependenciesPackage.getPackagedElements()
+ .add(dependency);
+ }
+ }
+ }
+
+ List<Comment> comments = dependency.getOwnedComments();
+ Comment comment = null;
+ if (comments.isEmpty()) {
+ comment = dependency.createOwnedComment();
+ comment.setBody("");
+ comment.getAnnotatedElements().add(dependency);
+ } else {
+ comment = comments.get(0);
+ }
+ String body = comment.getBody();
+ body = body + plugin.getName() + " -> " + referencedPlugin.getName() + "</p>\n";
+ comment.setBody(body);
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ monitor.worked(1);
+ }
+
+ }
+
+ /**
+ * Creates a dependency link between two
+ * {@link org.eclipse.uml2.uml.NamedElement NamedElement}s
+ *
+ * @param name
+ * the name of the dependency
+ * @param client
+ * the client NamedElement
+ * @param supplier
+ * the supplier NamedElement
+ * @return the created dependency
+ */
+ private Dependency createDependency(String name, NamedElement client, NamedElement supplier) {
+ Dependency dependency = UMLFactory.eINSTANCE.createDependency();
+
+ dependency.setName(name);
+ dependency.getClients().add(client);
+ dependency.getSuppliers().add(supplier);
+
+ return dependency;
+ }
+
+ }
+
+ /**
+ * Returns <code>true</code> if the specified element represents an Eclipse
+ * feature (instanceof Component & stereotyped by "Feature")
+ *
+ * @param element
+ * the element to test
+ * @return <code>true</code> if the specified element represents an Eclipse
+ * feature (instanceof Component & stereotyped by "Feature")
+ */
+ public static boolean isFeature(Element element) {
+ return element instanceof Component && ADL4Eclipse_StereotypesUtils.isFeature(element);
+ }
+
+ /**
+ * Returns <code>true</code> if the specified element represents an Eclipse
+ * plugin (instanceof Component & stereotyped by "Plugin")
+ *
+ * @param element
+ * the element to test
+ * @return <code>true</code> if the specified element represents an Eclipse
+ * plugin (instanceof Component & stereotyped by "Plugin")
+ */
+ public static boolean isBundle(Element element) {
+ return element instanceof Component && OSGIStereotypesUtils.isBundle(element);
+ }
+
+ /**
+ * Changes the name of the specified {@link NamedElement} if it can be
+ * simplified.
+ *
+ * @see #getSimplifiedName(String)
+ * @param namedElement
+ * the named element to be modified
+ */
+ public static void simplifyName(NamedElement namedElement) {
+ String name = namedElement.getName();
+ String simplifiedName = getSimplifiedName(name);
+ if (simplifiedName != name) {
+ namedElement.setName(simplifiedName);
+ }
+ }
+
+ /**
+ * Computes and returns a simplified name from the given String. Basically,
+ * it removes the "org.eclipse." at the beginning of the name.
+ *
+ * @param name
+ * the name to be simplified, can be <code>null</code>
+ * @return the simplified name or the exact same string if it could not be
+ * simplified
+ */
+ public static String getSimplifiedName(String name) {
+ if (name != null && name.indexOf("org.eclipse.") == 0) {
+ return name.substring("org.eclipse.".length());
+ }
+ return name;
+ }
+
+}
diff --git a/extraplugins/adl4eclipse/org.eclipse.papyrus.adl4eclipsetool/src/org/eclipse/papyrus/adltool/designer/ArchitectureSnapshotDesigner.java b/extraplugins/adl4eclipse/org.eclipse.papyrus.adl4eclipsetool/src/org/eclipse/papyrus/adltool/designer/ArchitectureSnapshotDesigner.java
index b84e8825e93..eeafdd04f60 100644
--- a/extraplugins/adl4eclipse/org.eclipse.papyrus.adl4eclipsetool/src/org/eclipse/papyrus/adltool/designer/ArchitectureSnapshotDesigner.java
+++ b/extraplugins/adl4eclipse/org.eclipse.papyrus.adl4eclipsetool/src/org/eclipse/papyrus/adltool/designer/ArchitectureSnapshotDesigner.java
@@ -1,645 +1,694 @@
-/*****************************************************************************
- * 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:
- * Patrick Tessier (CEA LIST) patrick.tessier@cea.fr - Initial API and implementation
- * Thomas Daniellou (CEA LIST) - Refactoring and cleanup
- *****************************************************************************/
-package org.eclipse.papyrus.adltool.designer;
-
-import java.util.HashSet;
-import java.util.Set;
-
-import org.eclipse.emf.common.util.URI;
-import org.eclipse.emf.ecore.resource.Resource;
-import org.eclipse.papyrus.adl4eclipse.org.ADL4Eclipse_Stereotypes;
-import org.eclipse.papyrus.adltool.ADLConstants;
-import org.eclipse.papyrus.adltool.reversible.project.StereotypeVersion;
-import org.eclipse.papyrus.adltool.reversible.project.ReversiblePlugin;
-import org.eclipse.papyrus.adltool.reversible.project.ReversibleProject;
-import org.eclipse.papyrus.osgi.profile.OSGIStereotypes;
-import org.eclipse.papyrus.adltool.reversible.extension.SchemaElement;
-import org.eclipse.papyrus.adltool.reversible.extension.SchemaAttribute;
-import org.eclipse.papyrus.adltool.reversible.Reversible;
-import org.eclipse.papyrus.adltool.reversible.extension.ReversibleExtension;
-import org.eclipse.papyrus.adltool.reversible.extensionpoint.ReversibleExtensionPoint;
-import org.eclipse.papyrus.adltool.reversible.packages.ReversiblePackage;
-import org.eclipse.papyrus.uml.extensionpoints.profile.IRegisteredProfile;
-import org.eclipse.papyrus.uml.extensionpoints.profile.RegisteredProfile;
-import org.eclipse.papyrus.uml.extensionpoints.utils.Util;
-import org.eclipse.papyrus.uml.tools.utils.PackageUtil;
-import org.eclipse.uml2.uml.Component;
-import org.eclipse.uml2.uml.Dependency;
-import org.eclipse.uml2.uml.InstanceSpecification;
-import org.eclipse.uml2.uml.LiteralString;
-import org.eclipse.uml2.uml.NamedElement;
-import org.eclipse.uml2.uml.Package;
-import org.eclipse.uml2.uml.PackageableElement;
-import org.eclipse.uml2.uml.Port;
-import org.eclipse.uml2.uml.Profile;
-import org.eclipse.uml2.uml.Property;
-import org.eclipse.uml2.uml.Slot;
-import org.eclipse.uml2.uml.Stereotype;
-import org.eclipse.uml2.uml.UMLFactory;
-
-/**
- * This class manipulates each reversibles representation, creates the
- * dependencies between them, and when necessary, adds them in the model.
- */
-public class ArchitectureSnapshotDesigner {
-
- /**
- * Set containing the projects that have been reversed during the current import.
- */
- private Set<ReversibleProject> reversedProjects;
-
- /**
- * Set of projects to be reversed.
- */
- private Set<ReversibleProject> reversibles;
-
- /**
- * Set of reversibles that need to apply and fill their stereotypes.
- */
- private Set<Reversible<?>> postponedReversibles;
-
- /**
- * Reverse settings containing the depth level of dependencies to reverse.
- */
- private ReverseSettings settings;
-
- /**
- * The package that will hold the reversed projects.
- */
- private Package model;
-
- /**
- * Constructor.
- *
- * @param model
- * @param reversibles
- * @param settings
- */
- public ArchitectureSnapshotDesigner(Package model, Set<ReversibleProject> reversibles, ReverseSettings settings) {
- if (model == null || reversibles == null || reversibles.isEmpty()) {
- throw new IllegalArgumentException();
- }
-
- this.model = model;
- this.settings = settings;
- this.reversibles = reversibles;
-
- reversedProjects = new HashSet<>();
- postponedReversibles = new HashSet<>();
- }
-
- /**
- * Launches the import of bundles into the model.
- */
- public void runImportBundles() {
- initModel();
-
- // Reverses the selected projects in the model
- for (ReversibleProject project : reversibles) {
- reverseProject(project);
- }
-
- // Fill the reversibles' stereotypes
- for (Reversible<?> reversible : postponedReversibles) {
- reversible.fillStereotype();
- }
- }
-
- /**
- * Ensures that the ADL4Eclipse and OSGi profiles have been applied.
- */
- private void initModel() {
- applyProfile(OSGIStereotypes.OSGI);
- applyProfile(ADL4Eclipse_Stereotypes.ADL4ECLIPSE);
- }
-
- private void applyProfile(String profileName) {
- Profile appliedProfile = model.getAppliedProfile(profileName);
-
- if (appliedProfile == null) {
- IRegisteredProfile registeredProfile = RegisteredProfile.getRegisteredProfile(profileName);
-
- if (registeredProfile != null) {
- URI modelUri = registeredProfile.getUri();
- Resource modelResource = Util.createTemporaryResourceSet().getResource(modelUri, true);
- Profile profile = (Profile) modelResource.getContents().get(0);
-
- PackageUtil.applyProfile(model, profile, true);
- }
- }
- }
-
- /**
- * Checks whether the reversible has been flagged as reversed or not.
- *
- * @param project
- * @return returns true if this the reversible has been reversed.
- */
- private boolean wasReversed(ReversibleProject project) {
- return reversedProjects.contains(project);
- }
-
- /**
- * Flags the reversible to prevent recursive reverse loop.
- *
- * @param project the project to be flagged as reversed
- */
- private void setReversed(ReversibleProject project) {
- reversedProjects.add(project);
- }
-
- /**
- * Saves the reversible to fill its properties at the end of the reverse.
- * @param reversible
- */
- private void postPoneFillStereotype(Reversible<?> reversible) {
- postponedReversibles.add(reversible);
- }
-
- /**
- * Reverses a project and, if the {@link ReverseSettings} allows it, its
- * dependencies, exported packages, extension points and extensions.
- *
- * <p>
- * <b>Note:</b> This method adds the project's representation in the model.
- * </p>
- *
- * @param project the project to reverse
- */
- private void reverseProject(ReversibleProject project) {
- insertInModel(project);
- setReversed(project);
-
- // Reverse the children
- if (settings.reverseDependencies()) {
- for (ReversibleProject child : project.getDependencies()) {
- reverseChildProject(project, child, settings.getReverseDepth());
- }
- }
-
- if (project instanceof ReversiblePlugin) {
- ReversiblePlugin reversiblePlugin = (ReversiblePlugin) project;
-
- // Reverse exported packages
- if (settings.reverseExportPackages()) {
- for (ReversiblePackage exportedPackageName : reversiblePlugin.getExportedPackages()) {
- reversePackage(project, exportedPackageName);
- }
- }
-
- // Reverse imported packages
- if (settings.reverseImportPackages()) {
- for (ReversiblePackage importedPackage : reversiblePlugin.getImportedPackages()) {
- reversePackage(project, importedPackage);
- }
- }
-
- // Extension points
- if (settings.reverseExtensionPoints()) {
- for (ReversibleExtensionPoint extensionPoint : reversiblePlugin.getExtensionPoints()) {
- reverseExtensionPoint(extensionPoint);
- }
- }
-
- // Extensions
- if (settings.reverseExtensions()) {
- for (ReversibleExtension extension : reversiblePlugin.getExtensions()) {
- reverseExtension(extension);
- }
- }
- }
-
- // Fill stereotype properties
- postPoneFillStereotype(project);
- }
-
- /**
- * Reverses a child project and adds a dependency to its parent.
- *
- * <p>
- * <b>Note:</b> This method adds the project's representation in the model.
- * </p>
- *
- * @param parent the parent project
- * @param child the child project
- * @param currentDepth the current depth level
- */
- private void reverseChildProject(ReversibleProject parent, ReversibleProject child, int currentDepth) {
- // Prevent recursion cycle
- if (!wasReversed(child)) {
- insertInModel(child);
- setReversed(child);
-
- // Reverse the sub-children if we are in infinite mode or the depth is not reached
- if (currentDepth == ADLConstants.INFINITE_DEPTH_OPTION || currentDepth > 1) {
- int newDepth = currentDepth == ADLConstants.INFINITE_DEPTH_OPTION ? currentDepth : currentDepth - 1;
-
- for (ReversibleProject subChild : child.getDependencies()) {
- reverseChildProject(child, subChild, newDepth);
- }
- }
-
- // Apply stereotype
- child.applyStereotype();
- postPoneFillStereotype(child);
- }
-
- createDependency(parent, child);
- }
-
- /**
- * Reverses an reversible package inside a reversible project, creates a dependency between the package and the project
- * and applies the stereotypes on the created elements.
- *
- * @param project the project containing the imported packages
- * @param reversiblePackage the imported package name
- */
- private void reversePackage(ReversibleProject project, ReversiblePackage reversiblePackage) {
- Component reversedProject = project.getRepresentation();
- Package reversedPackage = project.getElement(reversiblePackage);
-
- if (reversedPackage == null) {
- reversedPackage = reversiblePackage.getRepresentation();
- reversedProject.getPackagedElements().add(reversedPackage);
- } else {
- reversiblePackage.setRepresentation(reversedPackage);
- }
-
- reversiblePackage.applyStereotype();
-
- Dependency packageDependency = project.getElement(reversiblePackage.getId(), Dependency.class);
-
- if (packageDependency == null) {
- // Create the dependency link
- packageDependency = createDependency(reversiblePackage.getId(), reversedProject, reversedPackage);
- reversedProject.getPackagedElements().add(packageDependency);
- }
-
- String dependencyStereotypeName = reversiblePackage.getDependencyStereotypeName();
- Stereotype dependencyStereotype = packageDependency.getAppliedStereotype(dependencyStereotypeName);
-
- if (dependencyStereotype == null) {
- // Apply the PackageReference stereotype on the link
- dependencyStereotype = packageDependency.getApplicableStereotype(OSGIStereotypes.PACKAGE_REFERENCE);
-
- if (dependencyStereotype != null) {
- packageDependency.applyStereotype(dependencyStereotype);
- }
- }
-
- // Fill dependency stereotype
- StereotypeVersion dependencyVersion = project.getReversibleVersion(reversiblePackage);
-
- if (dependencyVersion != null) {
- String floor = dependencyVersion.getFloor();
- String ceiling = dependencyVersion.getCeiling();
- boolean includeFloor = dependencyVersion.includeFloor();
- boolean includeCeiling = dependencyVersion.includeCeiling();
-
- packageDependency.setValue(dependencyStereotype, OSGIStereotypes.VERSIONRANGE_FLOOR_ATT, floor);
- packageDependency.setValue(dependencyStereotype, OSGIStereotypes.VERSIONRANGE_INCLUDEFLOOR_ATT, includeFloor);
-
- if (ceiling != null) {
- packageDependency.setValue(dependencyStereotype, OSGIStereotypes.VERSIONRANGE_CEILING_ATT, ceiling);
- packageDependency.setValue(dependencyStereotype, OSGIStereotypes.VERSIONRANGE_INCLUDECEILING_ATT, includeCeiling);
- }
- }
- }
-
- /**
- * Reverses an extension point. <br />
- * A reversed extension point is a component inside the project's component.
- *
- * @param extensionPoint
- */
- private void reverseExtensionPoint(ReversibleExtensionPoint extensionPoint) {
- ReversibleProject project = extensionPoint.getParent();
- Component reversedProject = project.getRepresentation();
- Component reversedExtensionPoint = project.getElement(extensionPoint);
-
- if (reversedExtensionPoint == null) {
- reversedExtensionPoint = extensionPoint.getRepresentation();
- reversedProject.getPackagedElements().add(reversedExtensionPoint);
- } else {
- extensionPoint.setRepresentation(reversedExtensionPoint);
- }
-
- // Create a port of type "reversed extension point" if it does not exist
- if (project.getElement(extensionPoint.getId(), Port.class) == null) {
- reversedProject.createOwnedPort(extensionPoint.getId(), reversedExtensionPoint);
- }
-
- reverseExtensionPointElements(extensionPoint);
-
- // Apply stereotype
- extensionPoint.applyStereotype();
- postPoneFillStereotype(extensionPoint);
- }
-
- /**
- * Reverses an extension. <br/>
- * An reversed extension is represented by an
- * {@link org.eclipse.uml2.uml.InstanceSpecification InstanceSpecification}
- * inside the project's component. The reversed project will have a port
- * linked to the extension point definer's port.
- *
- * @param extension
- */
- private void reverseExtension(ReversibleExtension extension) {
- ReversibleProject project = extension.getParent();
- ReversibleExtensionPoint extensionPoint = extension.getExtensionPoint();
-
- if (extensionPoint != null) {
- Component reversedProject = project.getRepresentation();
-
- // Check if the extension is in the project's representation
- InstanceSpecification reversedExtension = project.getElement(extension);
-
- if (reversedExtension == null) {
- reversedExtension = extension.getRepresentation();
- reversedProject.getPackagedElements().add(reversedExtension);
- } else {
- extension.setRepresentation(reversedExtension);
- }
-
- // TODO: Create a Usage link
-
- // Make sure the extension point's elements are reversed
- reverseExtensionPointElements(extensionPoint);
-
- // Create the instance specification's slots
- for (SchemaElement element : extension.getElements()) {
- Component reversedElement = extensionPoint.getElement(element.getName(), Component.class);
-
- if (reversedElement != null) {
- // Set the InstanceSpecification's classifier
- reversedExtension.getClassifiers().add(reversedElement);
- reversedExtension.getSlots().clear();
-
- for (SchemaAttribute schemaAttribute : element.getAttributes()) {
- LiteralString value = UMLFactory.eINSTANCE.createLiteralString();
- value.setValue(schemaAttribute.getValue());
-
- // TODO: This might need some refactoring
- for (Property attribute : reversedElement.getOwnedAttributes()) {
- if (attribute.getName().equals(schemaAttribute.getName())) {
- Slot slot = reversedExtension.createSlot();
-
- slot.setDefiningFeature(attribute);
- slot.getValues().add(value);
- }
- }
- }
- }
- }
-
- // Create a port of type "reversed extension point"
- if (project.getElement(extensionPoint.getId(), Port.class) == null) {
- reversedProject.createOwnedPort(extensionPoint.getId(), extensionPoint.getRepresentation());
- }
-
- createExtensionPointDependency(project, extensionPoint);
- }
-
- // Apply stereotype
- extension.applyStereotype();
- postPoneFillStereotype(extension);
- }
-
- /**
- * Creates a dependency between two projects (the one that contributes to an
- * extension point and the extension point's parent).
- *
- * <p>
- * <b>Note:</b> If the project and its extension point are not in the model,
- * this method will add them.
- * </p>
- *
- * @param project
- * @param extensionPoint
- */
- private void createExtensionPointDependency(ReversibleProject project, ReversibleExtensionPoint extensionPoint) {
- // Retrieve the extension point definer
- ReversibleProject parent = extensionPoint.getParent();
-
- Component reversedProject = project.getRepresentation();
- Component parentRepresentation = parent.getRepresentation();
- Component reversedExtensionPoint = extensionPoint.getRepresentation();
-
- // Add the extension point definer in the model
- if (searchRepresentation(parent) == null) {
- model.getPackagedElements().add(parentRepresentation);
- }
-
- // Make sure the extension point is in the model
- if (parent.getElement(extensionPoint) == null) {
- parentRepresentation.getPackagedElements().add(reversedExtensionPoint);
- }
-
- // Ensure the stereotype are applied
- parent.applyStereotype();
- extensionPoint.applyStereotype();
-
- postPoneFillStereotype(parent);
- postPoneFillStereotype(extensionPoint);
-
- // The project's port was created before this method is called
- Port extensionPort = project.getElement(extensionPoint.getId(), Port.class);
- Port extensionPointPort = parent.getElement(extensionPoint.getId(), Port.class);
-
- if (extensionPointPort == null) {
- extensionPointPort = parentRepresentation.createOwnedPort(extensionPoint.getId(), reversedExtensionPoint);
- }
-
- String dependencyName = extensionPoint.getId();
- Dependency dependency = project.getElement(dependencyName, Dependency.class);
-
- if (dependency != null) {
- return; // The dependency already exists
- }
-
- // Create the dependency and add it to the reversed project's representation
- Dependency extensionPointDependency = createDependency(dependencyName, extensionPort, extensionPointPort);
-
- reversedProject.getPackagedElements().add(extensionPointDependency);
-
- String extensionPtStereotypeName = extensionPoint.getDependencyStereotypeName();
- Stereotype dependencyStereotype = extensionPointDependency.getApplicableStereotype(extensionPtStereotypeName);
-
- extensionPointDependency.applyStereotype(dependencyStereotype);
- }
-
- /**
- * Creates a dependency link between two reversible projects. Adds the
- * dependency to the first reversible representation and apply the
- * stereotype.
- *
- * @param parent
- * @param child
- * @return the created dependency
- */
- private Dependency createDependency(ReversibleProject parent, ReversibleProject child) {
- Component parentComponent = parent.getRepresentation();
- Component childComponent = child.getRepresentation();
-
- String dependencyName = child.getId();
- Dependency dependency = parent.getElement(dependencyName, Dependency.class);
-
- // Create the dependency if it does not exist
- if (dependency == null) {
- dependency = createDependency(dependencyName, parentComponent, childComponent);
-
- parentComponent.getPackagedElements().add(dependency);
- parentComponent.createOwnedAttribute(child.getId(), childComponent);
- }
-
- // Apply the stereotype
- String depStereotypeName = child.getDependencyStereotypeName();
- Stereotype depStereotype = dependency.getApplicableStereotype(depStereotypeName);
-
- if (dependency.getAppliedStereotype(depStereotypeName) == null) {
- dependency.applyStereotype(depStereotype);
- }
-
- // Get the version to fill the stereotype
- StereotypeVersion dependencyVersionRange = parent.getReversibleVersion(child);
-
- if (dependencyVersionRange != null) {
- String floor = dependencyVersionRange.getFloor();
- String ceiling = dependencyVersionRange.getCeiling();
- boolean includeFloor = dependencyVersionRange.includeFloor();
- boolean includeCeiling = dependencyVersionRange.includeCeiling();
-
- dependency.setValue(depStereotype, OSGIStereotypes.VERSIONRANGE_FLOOR_ATT, floor);
- dependency.setValue(depStereotype, OSGIStereotypes.VERSIONRANGE_INCLUDEFLOOR_ATT, includeFloor);
-
- if (ceiling != null) {
- dependency.setValue(depStereotype, OSGIStereotypes.VERSIONRANGE_CEILING_ATT, ceiling);
- dependency.setValue(depStereotype, OSGIStereotypes.VERSIONRANGE_INCLUDECEILING_ATT, includeCeiling);
- }
- }
-
- return dependency;
- }
-
- /**
- * Creates a dependency link between two
- * {@link org.eclipse.uml2.uml.NamedElement NamedElement}s
- *
- * @param name the name of the dependency
- * @param client the client NamedElement
- * @param supplier the supplier NamedElement
- * @return the created dependency
- */
- private Dependency createDependency(String name, NamedElement client, NamedElement supplier) {
- Dependency dependency = UMLFactory.eINSTANCE.createDependency();
-
- dependency.setName(name);
- dependency.getClients().add(client);
- dependency.getSuppliers().add(supplier);
-
- return dependency;
- }
-
- /**
- * Adds a reversible project's representation in the model or updates it if
- * is already in it (in case we are updating an existing model).
- *
- * @param project
- */
- private void insertInModel(ReversibleProject project) {
- PackageableElement representation = searchRepresentation(project);
-
- if (representation instanceof Component) {
- project.setRepresentation((Component) representation);
- } else {
- representation = project.getRepresentation();
- model.getPackagedElements().add(representation);
- }
- }
-
- private void reverseExtensionPointElements(ReversibleExtensionPoint extensionPoint) {
- ReversibleProject parent = extensionPoint.getParent();
-
- // Make sure the parent project is in the model to apply the stereotypes on the elements
- insertInModel(parent);
-
- // Ensure the extension point is in its parent's representation
- Component reversedExtensionPoint = parent.getElement(extensionPoint);
-
- if (reversedExtensionPoint != null) {
- extensionPoint.setRepresentation(reversedExtensionPoint);
- } else {
- Component parentRepresentation = parent.getRepresentation();
- reversedExtensionPoint = extensionPoint.getRepresentation();
-
- parentRepresentation.getPackagedElements().add(reversedExtensionPoint);
- }
-
- // Create the extension point's elements
- for (SchemaElement element : extensionPoint.getElements()) {
- String elementName = element.getName();
- PackageableElement existingElement = reversedExtensionPoint.getPackagedElement(elementName);
-
- if (existingElement == null) {
- Component reversedElement = UMLFactory.eINSTANCE.createComponent();
-
- reversedElement.setName(elementName);
- reversedExtensionPoint.getPackagedElements().add(reversedElement);
-
- for (SchemaAttribute attribute : element.getAttributes()) {
- Property property = UMLFactory.eINSTANCE.createProperty();
-
- property.setName(attribute.getName());
- reversedElement.getOwnedAttributes().add(property);
- }
- }
- }
-
- // Apply the stereotype if it is not already applied
- for (PackageableElement element : reversedExtensionPoint.getPackagedElements()) {
- if (element instanceof Component) {
- String stereotypeName = ADL4Eclipse_Stereotypes.ELEMENT_STEREOTYPE;
- Stereotype elementStereotype = element.getAppliedStereotype(stereotypeName);
-
- if (elementStereotype == null) {
- elementStereotype = element.getApplicableStereotype(stereotypeName);
- element.applyStereotype(elementStereotype);
- }
- }
- }
- }
-
- /**
- * Returns a reversible project's representation in the model.
- * This method checks if the representation has the same name of the reversible's id
- * and if the reversible's stereotype is applied on it.
- *
- * @param reversible
- * @return the representation or null if it does not exists
- */
- private PackageableElement searchRepresentation(ReversibleProject reversible) {
- for (PackageableElement element : model.getPackagedElements()) {
- if (element.getName().equals(reversible.getId())) {
- Stereotype appliedStereotype = element.getAppliedStereotype(reversible.getStereotypeName());
-
- if (appliedStereotype != null) {
- return element;
- }
- }
- }
-
- return null;
- }
-
+/*****************************************************************************
+ * Copyright (c) 2013 CEA LIST.
+ *
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Patrick Tessier (CEA LIST) patrick.tessier@cea.fr - Initial API and implementation
+ * Thomas Daniellou (CEA LIST) - Refactoring and cleanup
+ *****************************************************************************/
+package org.eclipse.papyrus.adltool.designer;
+
+import java.util.HashSet;
+import java.util.Set;
+
+import org.eclipse.emf.common.util.URI;
+import org.eclipse.emf.ecore.resource.Resource;
+import org.eclipse.papyrus.adl4eclipse.org.ADL4Eclipse_Stereotypes;
+import org.eclipse.papyrus.adltool.ADLConstants;
+import org.eclipse.papyrus.adltool.Activator;
+import org.eclipse.papyrus.adltool.reversible.Reversible;
+import org.eclipse.papyrus.adltool.reversible.extension.ReversibleExtension;
+import org.eclipse.papyrus.adltool.reversible.extension.SchemaAttribute;
+import org.eclipse.papyrus.adltool.reversible.extension.SchemaElement;
+import org.eclipse.papyrus.adltool.reversible.extensionpoint.ReversibleExtensionPoint;
+import org.eclipse.papyrus.adltool.reversible.packages.ReversiblePackage;
+import org.eclipse.papyrus.adltool.reversible.project.ReversibleFeature;
+import org.eclipse.papyrus.adltool.reversible.project.ReversiblePlugin;
+import org.eclipse.papyrus.adltool.reversible.project.ReversibleProject;
+import org.eclipse.papyrus.adltool.reversible.project.StereotypeVersion;
+import org.eclipse.papyrus.osgi.profile.OSGIStereotypes;
+import org.eclipse.papyrus.uml.extensionpoints.profile.IRegisteredProfile;
+import org.eclipse.papyrus.uml.extensionpoints.profile.RegisteredProfile;
+import org.eclipse.papyrus.uml.extensionpoints.utils.Util;
+import org.eclipse.papyrus.uml.tools.utils.PackageUtil;
+import org.eclipse.uml2.uml.Component;
+import org.eclipse.uml2.uml.Dependency;
+import org.eclipse.uml2.uml.InstanceSpecification;
+import org.eclipse.uml2.uml.LiteralString;
+import org.eclipse.uml2.uml.NamedElement;
+import org.eclipse.uml2.uml.Package;
+import org.eclipse.uml2.uml.PackageableElement;
+import org.eclipse.uml2.uml.Port;
+import org.eclipse.uml2.uml.Profile;
+import org.eclipse.uml2.uml.Property;
+import org.eclipse.uml2.uml.Slot;
+import org.eclipse.uml2.uml.Stereotype;
+import org.eclipse.uml2.uml.UMLFactory;
+
+/**
+ * This class manipulates each reversibles representation, creates the
+ * dependencies between them, and when necessary, adds them in the model.
+ */
+public class ArchitectureSnapshotDesigner {
+
+ /**
+ * Set containing the projects that have been reversed during the current
+ * import.
+ */
+ private Set<ReversibleProject> reversedProjects;
+
+ /**
+ * Set of projects to be reversed.
+ */
+ private Set<ReversibleProject> reversibles;
+
+ /**
+ * Set of reversibles that need to apply and fill their stereotypes.
+ */
+ private Set<Reversible<?>> postponedReversibles;
+
+ /**
+ * Reverse settings containing the depth level of dependencies to reverse.
+ */
+ private ReverseSettings settings;
+
+ /**
+ * The package that will hold the reversed projects.
+ */
+ private Package model;
+
+ /**
+ * Constructor.
+ *
+ * @param model
+ * @param reversibles
+ * @param settings
+ */
+ public ArchitectureSnapshotDesigner(Package model, Set<ReversibleProject> reversibles, ReverseSettings settings) {
+ if (model == null || reversibles == null || reversibles.isEmpty()) {
+ throw new IllegalArgumentException();
+ }
+
+ this.model = model;
+ this.settings = settings;
+ this.reversibles = reversibles;
+
+ reversedProjects = new HashSet<>();
+ postponedReversibles = new HashSet<>();
+ }
+
+ /**
+ * Launches the import of bundles into the model.
+ */
+ public void runImportBundles() {
+ initModel();
+
+ // Reverses the selected projects in the model
+ for (ReversibleProject project : reversibles) {
+ reverseProject(project);
+ }
+
+ // Fill the reversibles' stereotypes
+ for (Reversible<?> reversible : postponedReversibles) {
+ reversible.fillStereotype();
+ }
+
+ }
+
+
+ /**
+ * Ensures that the ADL4Eclipse and OSGi profiles have been applied.
+ */
+ private void initModel() {
+ applyProfile(OSGIStereotypes.OSGI);
+ applyProfile(ADL4Eclipse_Stereotypes.ADL4ECLIPSE);
+ }
+
+ private void applyProfile(String profileName) {
+ Profile appliedProfile = model.getAppliedProfile(profileName);
+
+ if (appliedProfile == null) {
+ IRegisteredProfile registeredProfile = RegisteredProfile.getRegisteredProfile(profileName);
+
+ if (registeredProfile != null) {
+ URI modelUri = registeredProfile.getUri();
+ Resource modelResource = Util.createTemporaryResourceSet().getResource(modelUri, true);
+ Profile profile = (Profile) modelResource.getContents().get(0);
+
+ PackageUtil.applyProfile(model, profile, true);
+ }
+ }
+ }
+
+ /**
+ * Checks whether the reversible has been flagged as reversed or not.
+ *
+ * @param project
+ * @return returns true if this the reversible has been reversed.
+ */
+ private boolean wasReversed(ReversibleProject project) {
+ return reversedProjects.contains(project);
+ }
+
+ /**
+ * Flags the reversible to prevent recursive reverse loop.
+ *
+ * @param project
+ * the project to be flagged as reversed
+ */
+ private void setReversed(ReversibleProject project) {
+ reversedProjects.add(project);
+ }
+
+ /**
+ * Saves the reversible to fill its properties at the end of the reverse.
+ *
+ * @param reversible
+ */
+ private void postPoneFillStereotype(Reversible<?> reversible) {
+ postponedReversibles.add(reversible);
+ }
+
+ /**
+ * Reverses a project and, if the {@link ReverseSettings} allows it, its
+ * dependencies, exported packages, extension points and extensions.
+ *
+ * <p>
+ * <b>Note:</b> This method adds the project's representation in the model.
+ * </p>
+ *
+ * @param project
+ * the project to reverse
+ */
+ private void reverseProject(ReversibleProject project) {
+ insertInModel(project);
+ setReversed(project);
+
+ // Reverse the children
+ if (settings.reverseDependencies()) {
+ for (ReversibleProject child : project.getDependencies()) {
+ reverseChildProject(project, child, settings.getReverseDepth());
+ }
+ }
+
+ if (project instanceof ReversiblePlugin) {
+ ReversiblePlugin reversiblePlugin = (ReversiblePlugin) project;
+
+ // Reverse exported packages
+ if (settings.reverseExportPackages()) {
+ for (ReversiblePackage exportedPackageName : reversiblePlugin.getExportedPackages()) {
+ reversePackage(project, exportedPackageName);
+ }
+ }
+
+ // Reverse imported packages
+ if (settings.reverseImportPackages()) {
+ for (ReversiblePackage importedPackage : reversiblePlugin.getImportedPackages()) {
+ reversePackage(project, importedPackage);
+ }
+ }
+
+ // Extension points
+ if (settings.reverseExtensionPoints()) {
+ for (ReversibleExtensionPoint extensionPoint : reversiblePlugin.getExtensionPoints()) {
+ reverseExtensionPoint(extensionPoint);
+ }
+ }
+
+ // Extensions
+ if (settings.reverseExtensions()) {
+ for (ReversibleExtension extension : reversiblePlugin.getExtensions()) {
+ reverseExtension(extension);
+ }
+ }
+ }
+
+ // Fill stereotype properties
+ postPoneFillStereotype(project);
+ }
+
+ /**
+ * Reverses a child project and adds a dependency to its parent.
+ *
+ * <p>
+ * <b>Note:</b> This method adds the project's representation in the model.
+ * </p>
+ *
+ * @param parent
+ * the parent project
+ * @param child
+ * the child project
+ * @param currentDepth
+ * the current depth level
+ */
+ private void reverseChildProject(ReversibleProject parent, ReversibleProject child, int currentDepth) {
+ // Prevent recursion cycle
+ if (!wasReversed(child)) {
+ insertInModel(child);
+ setReversed(child);
+
+ // Reverse the sub-children if we are in infinite mode or the depth
+ // is not reached
+ if (currentDepth == ADLConstants.INFINITE_DEPTH_OPTION || currentDepth > 1) {
+ int newDepth = currentDepth == ADLConstants.INFINITE_DEPTH_OPTION ? currentDepth : currentDepth - 1;
+
+ for (ReversibleProject subChild : child.getDependencies()) {
+ reverseChildProject(child, subChild, newDepth);
+ }
+ }
+
+ // Apply stereotype
+ child.applyStereotype();
+ postPoneFillStereotype(child);
+ }
+
+ createDependency(parent, child);
+ }
+
+ /**
+ * Reverses an reversible package inside a reversible project, creates a
+ * dependency between the package and the project and applies the
+ * stereotypes on the created elements.
+ *
+ * @param project
+ * the project containing the imported packages
+ * @param reversiblePackage
+ * the imported package name
+ */
+ private void reversePackage(ReversibleProject project, ReversiblePackage reversiblePackage) {
+ Component reversedProject = project.getRepresentation();
+ Package reversedPackage = project.getElement(reversiblePackage);
+
+ if (reversedPackage == null) {
+ reversedPackage = reversiblePackage.getRepresentation();
+ reversedProject.getPackagedElements().add(reversedPackage);
+ } else {
+ reversiblePackage.setRepresentation(reversedPackage);
+ }
+
+ reversiblePackage.applyStereotype();
+
+ Dependency packageDependency = project.getElement(reversiblePackage.getId(), Dependency.class);
+
+ if (packageDependency == null) {
+ // Create the dependency link
+ packageDependency = createDependency(reversiblePackage.getId(), reversedProject, reversedPackage);
+ reversedProject.getPackagedElements().add(packageDependency);
+ }
+
+ String dependencyStereotypeName = reversiblePackage.getDependencyStereotypeName();
+ Stereotype dependencyStereotype = packageDependency.getAppliedStereotype(dependencyStereotypeName);
+
+ if (dependencyStereotype == null) {
+ // Apply the PackageReference stereotype on the link
+ dependencyStereotype = packageDependency.getApplicableStereotype(OSGIStereotypes.PACKAGE_REFERENCE);
+
+ if (dependencyStereotype != null) {
+ packageDependency.applyStereotype(dependencyStereotype);
+ }
+ }
+
+ // Fill dependency stereotype
+ StereotypeVersion dependencyVersion = project.getReversibleVersion(reversiblePackage);
+
+ if (dependencyVersion != null) {
+ String floor = dependencyVersion.getFloor();
+ String ceiling = dependencyVersion.getCeiling();
+ boolean includeFloor = dependencyVersion.includeFloor();
+ boolean includeCeiling = dependencyVersion.includeCeiling();
+
+ packageDependency.setValue(dependencyStereotype, OSGIStereotypes.VERSIONRANGE_FLOOR_ATT, floor);
+ packageDependency.setValue(dependencyStereotype, OSGIStereotypes.VERSIONRANGE_INCLUDEFLOOR_ATT,
+ includeFloor);
+
+ if (ceiling != null) {
+ packageDependency.setValue(dependencyStereotype, OSGIStereotypes.VERSIONRANGE_CEILING_ATT, ceiling);
+ packageDependency.setValue(dependencyStereotype, OSGIStereotypes.VERSIONRANGE_INCLUDECEILING_ATT,
+ includeCeiling);
+ }
+ }
+ }
+
+ /**
+ * Reverses an extension point. <br />
+ * A reversed extension point is a component inside the project's component.
+ *
+ * @param extensionPoint
+ */
+ private void reverseExtensionPoint(ReversibleExtensionPoint extensionPoint) {
+ ReversibleProject project = extensionPoint.getParent();
+ Component reversedProject = project.getRepresentation();
+ Component reversedExtensionPoint = project.getElement(extensionPoint);
+
+ if (reversedExtensionPoint == null) {
+ reversedExtensionPoint = extensionPoint.getRepresentation();
+ reversedProject.getPackagedElements().add(reversedExtensionPoint);
+ } else {
+ extensionPoint.setRepresentation(reversedExtensionPoint);
+ }
+
+ // Create a port of type "reversed extension point" if it does not exist
+ if (project.getElement(extensionPoint.getId(), Port.class) == null) {
+ reversedProject.createOwnedPort(extensionPoint.getId(), reversedExtensionPoint);
+ }
+
+ reverseExtensionPointElements(extensionPoint);
+
+ // Apply stereotype
+ extensionPoint.applyStereotype();
+ postPoneFillStereotype(extensionPoint);
+ }
+
+ /**
+ * Reverses an extension. <br/>
+ * An reversed extension is represented by an
+ * {@link org.eclipse.uml2.uml.InstanceSpecification InstanceSpecification}
+ * inside the project's component. The reversed project will have a port
+ * linked to the extension point definer's port.
+ *
+ * @param extension
+ */
+ private void reverseExtension(ReversibleExtension extension) {
+ ReversibleProject project = extension.getParent();
+ ReversibleExtensionPoint extensionPoint = extension.getExtensionPoint();
+
+ if (extensionPoint != null) {
+ Component reversedProject = project.getRepresentation();
+
+ // Check if the extension is in the project's representation
+ InstanceSpecification reversedExtension = project.getElement(extension);
+
+ if (reversedExtension == null) {
+ reversedExtension = extension.getRepresentation();
+ reversedProject.getPackagedElements().add(reversedExtension);
+ } else {
+ extension.setRepresentation(reversedExtension);
+ }
+
+ // TODO: Create a Usage link
+
+ // Make sure the extension point's elements are reversed
+ reverseExtensionPointElements(extensionPoint);
+
+ // Create the instance specification's slots
+ for (SchemaElement element : extension.getElements()) {
+ Component reversedElement = extensionPoint.getElement(element.getName(), Component.class);
+
+ if (reversedElement != null) {
+ // Set the InstanceSpecification's classifier
+ reversedExtension.getClassifiers().add(reversedElement);
+ reversedExtension.getSlots().clear();
+
+ for (SchemaAttribute schemaAttribute : element.getAttributes()) {
+ LiteralString value = UMLFactory.eINSTANCE.createLiteralString();
+ value.setValue(schemaAttribute.getValue());
+
+ // TODO: This might need some refactoring
+ for (Property attribute : reversedElement.getOwnedAttributes()) {
+ if (attribute.getName().equals(schemaAttribute.getName())) {
+ Slot slot = reversedExtension.createSlot();
+
+ slot.setDefiningFeature(attribute);
+ slot.getValues().add(value);
+ }
+ }
+ }
+ }
+ }
+
+ // Create a port of type "reversed extension point"
+ if (project.getElement(extensionPoint.getId(), Port.class) == null) {
+ reversedProject.createOwnedPort(extensionPoint.getId(), extensionPoint.getRepresentation());
+ }
+
+ createExtensionPointDependency(project, extensionPoint);
+ }
+
+ // Apply stereotype
+ extension.applyStereotype();
+ postPoneFillStereotype(extension);
+ }
+
+ /**
+ * Creates a dependency between two projects (the one that contributes to an
+ * extension point and the extension point's parent).
+ *
+ * <p>
+ * <b>Note:</b> If the project and its extension point are not in the model,
+ * this method will add them.
+ * </p>
+ *
+ * @param project
+ * @param extensionPoint
+ */
+ private void createExtensionPointDependency(ReversibleProject project, ReversibleExtensionPoint extensionPoint) {
+ // Retrieve the extension point definer
+ ReversibleProject parent = extensionPoint.getParent();
+
+ Component reversedProject = project.getRepresentation();
+ Component parentRepresentation = parent.getRepresentation();
+ Component reversedExtensionPoint = extensionPoint.getRepresentation();
+
+ // Add the extension point definer in the model
+ if (searchRepresentation(parent) == null) {
+ model.getPackagedElements().add(parentRepresentation);
+ }
+
+ // Make sure the extension point is in the model
+ if (parent.getElement(extensionPoint) == null) {
+ parentRepresentation.getPackagedElements().add(reversedExtensionPoint);
+ }
+
+ // Ensure the stereotype are applied
+ parent.applyStereotype();
+ extensionPoint.applyStereotype();
+
+ postPoneFillStereotype(parent);
+ postPoneFillStereotype(extensionPoint);
+
+ // The project's port was created before this method is called
+ Port extensionPort = project.getElement(extensionPoint.getId(), Port.class);
+ Port extensionPointPort = parent.getElement(extensionPoint.getId(), Port.class);
+
+ if (extensionPointPort == null) {
+ extensionPointPort = parentRepresentation.createOwnedPort(extensionPoint.getId(), reversedExtensionPoint);
+ }
+
+ String dependencyName = extensionPoint.getId();
+ Dependency dependency = project.getElement(dependencyName, Dependency.class);
+
+ if (dependency != null) {
+ return; // The dependency already exists
+ }
+
+ // Create the dependency and add it to the reversed project's
+ // representation
+ Dependency extensionPointDependency = createDependency(dependencyName, extensionPort, extensionPointPort);
+
+ reversedProject.getPackagedElements().add(extensionPointDependency);
+
+ String extensionPtStereotypeName = extensionPoint.getDependencyStereotypeName();
+ Stereotype dependencyStereotype = extensionPointDependency.getApplicableStereotype(extensionPtStereotypeName);
+
+ extensionPointDependency.applyStereotype(dependencyStereotype);
+ }
+
+ /**
+ * Creates a dependency link between two reversible projects. Adds the
+ * dependency to the first reversible representation and apply the
+ * stereotype.
+ *
+ * @param parent
+ * @param child
+ * @return the created dependency
+ */
+ private Dependency createDependency(ReversibleProject parent, ReversibleProject child) {
+ Component parentComponent = parent.getRepresentation();
+ Component childComponent = child.getRepresentation();
+
+ String dependencyName = child.getId();
+ Dependency dependency = parent.getElement(dependencyName, Dependency.class);
+
+ // Create the dependency if it does not exist
+ if (dependency == null) {
+ dependency = createDependency(dependencyName, parentComponent, childComponent);
+
+ parentComponent.getPackagedElements().add(dependency);
+
+ // create only the owned attribute in case of really owned elements
+ // (e.g. do not add for simple referenced bundles)
+ if (shouldCreateAttribute(parent, child)) {
+ parentComponent.createOwnedAttribute(child.getId(), childComponent);
+ }
+
+ }
+
+ // Apply the stereotype
+ String depStereotypeName = child.getDependencyStereotypeName();
+ Stereotype depStereotype = dependency.getApplicableStereotype(depStereotypeName);
+
+ if (dependency.getAppliedStereotype(depStereotypeName) == null) {
+ dependency.applyStereotype(depStereotype);
+ }
+
+ // Get the version to fill the stereotype
+ StereotypeVersion dependencyVersionRange = parent.getReversibleVersion(child);
+
+ if (dependencyVersionRange != null) {
+ String floor = dependencyVersionRange.getFloor();
+ String ceiling = dependencyVersionRange.getCeiling();
+ boolean includeFloor = dependencyVersionRange.includeFloor();
+ boolean includeCeiling = dependencyVersionRange.includeCeiling();
+
+ dependency.setValue(depStereotype, OSGIStereotypes.VERSIONRANGE_FLOOR_ATT, floor);
+ dependency.setValue(depStereotype, OSGIStereotypes.VERSIONRANGE_INCLUDEFLOOR_ATT, includeFloor);
+
+ if (ceiling != null) {
+ dependency.setValue(depStereotype, OSGIStereotypes.VERSIONRANGE_CEILING_ATT, ceiling);
+ dependency.setValue(depStereotype, OSGIStereotypes.VERSIONRANGE_INCLUDECEILING_ATT, includeCeiling);
+ }
+ }
+
+ return dependency;
+ }
+
+ private static boolean shouldCreateAttribute(ReversibleProject parent, ReversibleProject child) {
+ if (parent instanceof ReversibleFeature) {
+ // should only create for included plugins & included features, not
+ // referenced plugins
+ if (child instanceof ReversibleFeature
+ && ((ReversibleFeature) parent).getIncludedReversibleFeatures().contains(child)) {
+ return true;
+ }
+ if (child instanceof ReversiblePlugin
+ && ((ReversibleFeature) parent).getIncludedReversiblePlugins().contains(child)) {
+ return true;
+ }
+ return false;
+ } else if (parent instanceof ReversiblePlugin) {
+ return true;
+ } else {
+ Activator.log.error("Case not handled", null);
+ return true;
+ }
+ }
+
+ /**
+ * Creates a dependency link between two
+ * {@link org.eclipse.uml2.uml.NamedElement NamedElement}s
+ *
+ * @param name
+ * the name of the dependency
+ * @param client
+ * the client NamedElement
+ * @param supplier
+ * the supplier NamedElement
+ * @return the created dependency
+ */
+ private Dependency createDependency(String name, NamedElement client, NamedElement supplier) {
+ Dependency dependency = UMLFactory.eINSTANCE.createDependency();
+
+ dependency.setName(name);
+ dependency.getClients().add(client);
+ dependency.getSuppliers().add(supplier);
+
+ return dependency;
+ }
+
+ /**
+ * Adds a reversible project's representation in the model or updates it if
+ * is already in it (in case we are updating an existing model).
+ *
+ * @param project
+ */
+ private void insertInModel(ReversibleProject project) {
+ PackageableElement representation = searchRepresentation(project);
+
+ if (representation instanceof Component) {
+ project.setRepresentation((Component) representation);
+ } else {
+ representation = project.getRepresentation();
+ model.getPackagedElements().add(representation);
+ }
+ }
+
+ private void reverseExtensionPointElements(ReversibleExtensionPoint extensionPoint) {
+ ReversibleProject parent = extensionPoint.getParent();
+
+ // Make sure the parent project is in the model to apply the stereotypes
+ // on the elements
+ insertInModel(parent);
+
+ // Ensure the extension point is in its parent's representation
+ Component reversedExtensionPoint = parent.getElement(extensionPoint);
+
+ if (reversedExtensionPoint != null) {
+ extensionPoint.setRepresentation(reversedExtensionPoint);
+ } else {
+ Component parentRepresentation = parent.getRepresentation();
+ reversedExtensionPoint = extensionPoint.getRepresentation();
+
+ parentRepresentation.getPackagedElements().add(reversedExtensionPoint);
+ }
+
+ // Create the extension point's elements
+ for (SchemaElement element : extensionPoint.getElements()) {
+ String elementName = element.getName();
+ PackageableElement existingElement = reversedExtensionPoint.getPackagedElement(elementName);
+
+ if (existingElement == null) {
+ Component reversedElement = UMLFactory.eINSTANCE.createComponent();
+
+ reversedElement.setName(elementName);
+ reversedExtensionPoint.getPackagedElements().add(reversedElement);
+
+ for (SchemaAttribute attribute : element.getAttributes()) {
+ Property property = UMLFactory.eINSTANCE.createProperty();
+
+ property.setName(attribute.getName());
+ reversedElement.getOwnedAttributes().add(property);
+ }
+ }
+ }
+
+ // Apply the stereotype if it is not already applied
+ for (PackageableElement element : reversedExtensionPoint.getPackagedElements()) {
+ if (element instanceof Component) {
+ String stereotypeName = ADL4Eclipse_Stereotypes.ELEMENT_STEREOTYPE;
+ Stereotype elementStereotype = element.getAppliedStereotype(stereotypeName);
+
+ if (elementStereotype == null) {
+ elementStereotype = element.getApplicableStereotype(stereotypeName);
+ element.applyStereotype(elementStereotype);
+ }
+ }
+ }
+ }
+
+ /**
+ * Returns a reversible project's representation in the model. This method
+ * checks if the representation has the same name of the reversible's id and
+ * if the reversible's stereotype is applied on it.
+ *
+ * @param reversible
+ * @return the representation or null if it does not exists
+ */
+ private PackageableElement searchRepresentation(ReversibleProject reversible) {
+ for (PackageableElement element : model.getPackagedElements()) {
+ if (element.getName().equals(reversible.getId())) {
+ Stereotype appliedStereotype = element.getAppliedStereotype(reversible.getStereotypeName());
+
+ if (appliedStereotype != null) {
+ return element;
+ }
+ }
+ }
+
+ return null;
+ }
+
} \ No newline at end of file
diff --git a/extraplugins/adl4eclipse/org.eclipse.papyrus.adl4eclipsetool/src/org/eclipse/papyrus/adltool/reversible/project/ReversibleFeature.java b/extraplugins/adl4eclipse/org.eclipse.papyrus.adl4eclipsetool/src/org/eclipse/papyrus/adltool/reversible/project/ReversibleFeature.java
index 11f572b6eb2..97b2abbd9f5 100644
--- a/extraplugins/adl4eclipse/org.eclipse.papyrus.adl4eclipsetool/src/org/eclipse/papyrus/adltool/reversible/project/ReversibleFeature.java
+++ b/extraplugins/adl4eclipse/org.eclipse.papyrus.adl4eclipsetool/src/org/eclipse/papyrus/adltool/reversible/project/ReversibleFeature.java
@@ -1,291 +1,314 @@
-/*****************************************************************************
- * Copyright (c) 2015 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:
- * Thomas Daniellou (CEA LIST) - Initial API and implementation
- *****************************************************************************/
-package org.eclipse.papyrus.adltool.reversible.project;
-
-import static org.eclipse.papyrus.adltool.Activator.log;
-
-import java.net.URL;
-import java.util.ArrayList;
-import java.util.HashMap;
-import java.util.List;
-import java.util.Map;
-
-import org.eclipse.emf.ecore.EObject;
-import org.eclipse.osgi.service.resolver.VersionRange;
-import org.eclipse.papyrus.adl4eclipse.org.ADL4Eclipse_Stereotypes;
-import org.eclipse.papyrus.adltool.ADL4EclipseUtils;
-import org.eclipse.papyrus.adltool.reversible.AbstractReversible;
-import org.eclipse.papyrus.adltool.reversible.Reversible;
-import org.eclipse.papyrus.adltool.reversible.factory.ReversibleFactory;
-import org.eclipse.papyrus.osgi.profile.OSGIStereotypes;
-import org.eclipse.pde.core.IIdentifiable;
-import org.eclipse.pde.internal.core.ifeature.IFeature;
-import org.eclipse.pde.internal.core.ifeature.IFeatureChild;
-import org.eclipse.pde.internal.core.ifeature.IFeatureImport;
-import org.eclipse.pde.internal.core.ifeature.IFeatureInfo;
-import org.eclipse.pde.internal.core.ifeature.IFeaturePlugin;
-import org.eclipse.pde.internal.core.ifeature.IFeatureURL;
-import org.eclipse.pde.internal.core.ifeature.IFeatureURLElement;
-import org.eclipse.swt.graphics.Image;
-import org.eclipse.uml2.uml.Component;
-import org.eclipse.uml2.uml.Dependency;
-import org.eclipse.uml2.uml.Stereotype;
-import org.eclipse.uml2.uml.UMLFactory;
-
-/**
- * This class is a reversible adapter of a feature project.
- */
-@SuppressWarnings("restriction")
-public class ReversibleFeature extends AbstractReversible<Component> implements ReversibleProject {
-
- private Map<Reversible<?>, StereotypeVersion> dependencyVersions;
-
- private IFeature feature;
-
- /**
- * Constructor.
- *
- * @param feature
- */
- public ReversibleFeature(IFeature feature) {
- this.feature = feature;
-
- dependencyVersions = new HashMap<>();
- }
-
- @Override
- public String getId() {
- return feature.getId();
- }
-
- @Override
- public String getStereotypeName() {
- return ADL4Eclipse_Stereotypes.FEATURE_STEREOTYPE;
- }
-
- @Override
- public String getDependencyStereotypeName() {
- return ADL4Eclipse_Stereotypes.FEATURE_REFERENCE;
- }
-
- @Override
- public Type getType() {
- return Type.FEATURE;
- }
-
- @Override
- public Component createRepresentation() {
- return UMLFactory.eINSTANCE.createComponent();
- }
-
- @Override
- public List<ReversibleProject> getDependencies() {
- List<ReversibleProject> dependencies = new ArrayList<>();
-
- for (IFeatureChild include : feature.getIncludedFeatures()) {
- ReversibleProject reversibleFeature = ReversibleFactory.getInstance().getFeature(include.getId());
-
- if (reversibleFeature != null) {
- dependencies.add(reversibleFeature);
- VersionRange versionRange = new VersionRange(include.getVersion());
- dependencyVersions.put(reversibleFeature, new StereotypeVersion(versionRange));
- } else {
- log.warn(getType() + " \"" + getId() + "\": cannot find child " + include.getId());
- }
- }
-
- for (IFeatureImport require : feature.getImports()) {
- ReversibleProject reversibleProject = ReversibleFactory.getInstance().getFeature(require.getId());
-
- if (reversibleProject == null) {
- reversibleProject = ReversibleFactory.getInstance().getPlugin(require.getId());
- }
-
- if (reversibleProject != null) {
- dependencies.add(reversibleProject);
- dependencyVersions.put(reversibleProject, new StereotypeVersion(require.getVersion()));
- } else {
- log.warn(getType() + " \"" + getId() + "\": cannot find child " + require.getId());
- }
- }
-
- for (IFeaturePlugin plugin : feature.getPlugins()) {
- ReversibleProject reversiblePlugin = ReversibleFactory.getInstance().getPlugin(plugin.getId());
-
- if (reversiblePlugin != null) {
- dependencies.add(reversiblePlugin);
- dependencyVersions.put(reversiblePlugin, new StereotypeVersion(plugin.getVersion()));
- } else {
- log.warn(getType() + " \"" + getId() + "\": cannot find child " + plugin.getId());
- }
- }
-
- return dependencies;
- }
-
- @Override
- public String getDescription() {
- IFeatureInfo featureInfo = feature.getFeatureInfo(IFeature.INFO_DESCRIPTION);
-
- if (featureInfo != null) {
- return featureInfo.getDescription();
- }
-
- return null;
- }
-
- @Override
- public Image getImage() {
- return ADL4EclipseUtils.getImage("img/feature_obj.gif");
- }
-
- @Override
- public void fillStereotype() {
- if (!applyStereotype()) {
- log.warn(getId() + ": cannot fill the stereotype properties");
- return;
- }
-
- // Id
- String id = feature.getId();
- representation.setValue(stereotype, ADL4Eclipse_Stereotypes.FEATURE_ID_ATT, id);
-
- // Label
- String label = feature.getLabel();
- representation.setValue(stereotype, ADL4Eclipse_Stereotypes.FEATURE_LABEL_ATT, label);
-
- // Version
- String version = feature.getVersion();
- representation.setValue(stereotype, ADL4Eclipse_Stereotypes.FEATURE_VERSION_ATT, version);
-
- // Provider
- String provider = feature.getProviderName();
- representation.setValue(stereotype, ADL4Eclipse_Stereotypes.FEATURE_PROVIDER_ATT, provider);
-
- IFeatureInfo featureInfoDescription = feature.getFeatureInfo(IFeature.INFO_DESCRIPTION);
- if (featureInfoDescription != null) {
- // Description
- String description = getDescription();
- representation.setValue(stereotype, ADL4Eclipse_Stereotypes.FEATURE_DESCRIPTION_ATT, description);
-
- // Description URL
- String descriptionURL = featureInfoDescription.getURL();
- representation.setValue(stereotype, ADL4Eclipse_Stereotypes.FEATURE_DESCRIPTION_URL_ATT, descriptionURL);
- }
-
- IFeatureInfo featureInfoCopyright = feature.getFeatureInfo(IFeature.INFO_COPYRIGHT);
- if (featureInfoCopyright != null) {
- // Copyright
- String copyright = feature.getFeatureInfo(IFeature.INFO_COPYRIGHT).getDescription();
- representation.setValue(stereotype, ADL4Eclipse_Stereotypes.FEATURE_COPYRIGHT_ATT, copyright);
-
- // Copyright URL
- String copyrightURL = feature.getFeatureInfo(IFeature.INFO_COPYRIGHT).getURL();
- representation.setValue(stereotype, ADL4Eclipse_Stereotypes.FEATURE_COPYRIGHT_URL_ATT, copyrightURL);
- }
-
- IFeatureInfo featureInfoLicense = feature.getFeatureInfo(IFeature.INFO_LICENSE);
- if (featureInfoLicense != null) {
- // License
- String license = featureInfoLicense.getDescription();
- representation.setValue(stereotype, ADL4Eclipse_Stereotypes.FEATURE_LICENSE_ATT, license);
-
- // License URL
- String licenseURL = feature.getFeatureInfo(IFeature.INFO_LICENSE).getURL();
- representation.setValue(stereotype, ADL4Eclipse_Stereotypes.FEATURE_LICENSE_URL_ATT, licenseURL);
- }
-
- // URL
- IFeatureURL featureUrl = feature.getURL();
- if (featureUrl != null) {
-
- IFeatureURLElement updateUrl = featureUrl.getUpdate();
- if (updateUrl != null) {
- // URL label
- representation.setValue(stereotype, ADL4Eclipse_Stereotypes.FEATURE_URL_LABEL_ATT, updateUrl.getLabel());
-
- URL url = updateUrl.getURL();
- if (url != null) {
- // URL address
- representation.setValue(stereotype, ADL4Eclipse_Stereotypes.FEATURE_URL_ATT, url.toString());
- }
- }
- }
-
- // Operating system
- representation.setValue(stereotype, ADL4Eclipse_Stereotypes.FEATURE_OS_ATT, feature.getOS());
-
- // Window system
- representation.setValue(stereotype, ADL4Eclipse_Stereotypes.FEATURE_WS_ATT, feature.getWS());
-
- // Language
- representation.setValue(stereotype, ADL4Eclipse_Stereotypes.FEATURE_LANGUAGES_ATT, feature.getNL());
-
- // Architecture
- representation.setValue(stereotype, ADL4Eclipse_Stereotypes.FEATURE_ARCHITECTURE_ATT, feature.getArch());
-
- // Plug-ins
- setStereotypeValues(ADL4Eclipse_Stereotypes.FEATURE_PLUGINS_ATT, feature.getPlugins(), OSGIStereotypes.BUNDLE_REFERENCE);
-
- // Included Features
- setStereotypeValues(ADL4Eclipse_Stereotypes.FEATURE_INCLUDED_FEATURES_ATT, feature.getIncludedFeatures(), ADL4Eclipse_Stereotypes.FEATURE_REFERENCE);
-
- // Imported Features
- setStereotypeValues(ADL4Eclipse_Stereotypes.FEATURE_FEATURE_DEPENDENCIES_ATT, feature.getImports(), ADL4Eclipse_Stereotypes.FEATURE_REFERENCE);
-
- // Imported Plug-ins
- setStereotypeValues(ADL4Eclipse_Stereotypes.FEATURE_PLUGIN_DEPENDENCIES_ATT, feature.getImports(), OSGIStereotypes.BUNDLE_REFERENCE);
- }
-
- /**
- * Retrieves a list of stereotyped applications from an array of identifiable and
- * store it in the feature's stereotype at the propertyName value.
- *
- * @param propertyName the name of the property to set the value.
- * @param identifiables the array of identifiable to set
- * @param stereotypeIdentifier the stereotype qualified name of the EObject to save
- */
- private void setStereotypeValues(String propertyName, IIdentifiable[] identifiables, String stereotypeIdentifier) {
- List<EObject> pluginReferences = new ArrayList<>();
-
- for (IIdentifiable identifiable : identifiables) {
- // The stereotype takes stereotyped dependencies that are inside the representation
- Dependency dependency = getElement(identifiable.getId(), Dependency.class);
-
- if (dependency != null) {
- Stereotype dependencyStereotype = dependency.getAppliedStereotype(stereotypeIdentifier);
-
- if (dependencyStereotype != null) {
- EObject stereotypeApplication = dependency.getStereotypeApplication(dependencyStereotype);
-
- if (stereotypeApplication != null) {
- pluginReferences.add(stereotypeApplication);
- }
- }
- }
- }
-
- representation.setValue(stereotype, propertyName, pluginReferences);
- }
-
- @Override
- public StereotypeVersion getReversibleVersion(Reversible<?> reversibleProject) {
- return dependencyVersions.get(reversibleProject);
- }
-
- @Override
- public void setReversibleVersion(Reversible<?> reversible, StereotypeVersion version) {
- dependencyVersions.put(reversible, version);
-
- }
-
-}
+/*****************************************************************************
+ * Copyright (c) 2015 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:
+ * Thomas Daniellou (CEA LIST) - Initial API and implementation
+ *****************************************************************************/
+package org.eclipse.papyrus.adltool.reversible.project;
+
+import static org.eclipse.papyrus.adltool.Activator.log;
+
+import java.net.URL;
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+import org.eclipse.emf.ecore.EObject;
+import org.eclipse.osgi.service.resolver.VersionRange;
+import org.eclipse.papyrus.adl4eclipse.org.ADL4Eclipse_Stereotypes;
+import org.eclipse.papyrus.adltool.ADL4EclipseUtils;
+import org.eclipse.papyrus.adltool.reversible.AbstractReversible;
+import org.eclipse.papyrus.adltool.reversible.Reversible;
+import org.eclipse.papyrus.adltool.reversible.factory.ReversibleFactory;
+import org.eclipse.papyrus.osgi.profile.OSGIStereotypes;
+import org.eclipse.pde.core.IIdentifiable;
+import org.eclipse.pde.internal.core.ifeature.IFeature;
+import org.eclipse.pde.internal.core.ifeature.IFeatureChild;
+import org.eclipse.pde.internal.core.ifeature.IFeatureImport;
+import org.eclipse.pde.internal.core.ifeature.IFeatureInfo;
+import org.eclipse.pde.internal.core.ifeature.IFeaturePlugin;
+import org.eclipse.pde.internal.core.ifeature.IFeatureURL;
+import org.eclipse.pde.internal.core.ifeature.IFeatureURLElement;
+import org.eclipse.swt.graphics.Image;
+import org.eclipse.uml2.uml.Component;
+import org.eclipse.uml2.uml.Dependency;
+import org.eclipse.uml2.uml.Stereotype;
+import org.eclipse.uml2.uml.UMLFactory;
+
+/**
+ * This class is a reversible adapter of a feature project.
+ */
+@SuppressWarnings("restriction")
+public class ReversibleFeature extends AbstractReversible<Component> implements ReversibleProject {
+
+ private Map<Reversible<?>, StereotypeVersion> dependencyVersions;
+
+ private IFeature feature;
+
+ /**
+ * Constructor.
+ *
+ * @param feature
+ */
+ public ReversibleFeature(IFeature feature) {
+ this.feature = feature;
+
+ dependencyVersions = new HashMap<>();
+ }
+
+ @Override
+ public String getId() {
+ return feature.getId();
+ }
+
+ @Override
+ public String getStereotypeName() {
+ return ADL4Eclipse_Stereotypes.FEATURE_STEREOTYPE;
+ }
+
+ @Override
+ public String getDependencyStereotypeName() {
+ return ADL4Eclipse_Stereotypes.FEATURE_REFERENCE;
+ }
+
+ @Override
+ public Type getType() {
+ return Type.FEATURE;
+ }
+
+ @Override
+ public Component createRepresentation() {
+ return UMLFactory.eINSTANCE.createComponent();
+ }
+
+ @Override
+ public List<ReversibleProject> getDependencies() {
+ List<ReversibleProject> dependencies = new ArrayList<>();
+
+ for (IFeatureChild include : feature.getIncludedFeatures()) {
+ ReversibleProject reversibleFeature = ReversibleFactory.getInstance().getFeature(include.getId());
+
+ if (reversibleFeature != null) {
+ dependencies.add(reversibleFeature);
+ VersionRange versionRange = new VersionRange(include.getVersion());
+ dependencyVersions.put(reversibleFeature, new StereotypeVersion(versionRange));
+ } else {
+ log.warn(getType() + " \"" + getId() + "\": cannot find child " + include.getId());
+ }
+ }
+
+ for (IFeatureImport require : feature.getImports()) {
+ ReversibleProject reversibleProject = ReversibleFactory.getInstance().getFeature(require.getId());
+
+ if (reversibleProject == null) {
+ reversibleProject = ReversibleFactory.getInstance().getPlugin(require.getId());
+ }
+
+ if (reversibleProject != null) {
+ dependencies.add(reversibleProject);
+ dependencyVersions.put(reversibleProject, new StereotypeVersion(require.getVersion()));
+ } else {
+ log.warn(getType() + " \"" + getId() + "\": cannot find child " + require.getId());
+ }
+ }
+
+ for (IFeaturePlugin plugin : feature.getPlugins()) {
+ ReversibleProject reversiblePlugin = ReversibleFactory.getInstance().getPlugin(plugin.getId());
+
+ if (reversiblePlugin != null) {
+ dependencies.add(reversiblePlugin);
+ dependencyVersions.put(reversiblePlugin, new StereotypeVersion(plugin.getVersion()));
+ } else {
+ log.warn(getType() + " \"" + getId() + "\": cannot find child " + plugin.getId());
+ }
+ }
+
+ return dependencies;
+ }
+
+ @Override
+ public String getDescription() {
+ IFeatureInfo featureInfo = feature.getFeatureInfo(IFeature.INFO_DESCRIPTION);
+
+ if (featureInfo != null) {
+ return featureInfo.getDescription();
+ }
+
+ return null;
+ }
+
+ @Override
+ public Image getImage() {
+ return ADL4EclipseUtils.getImage("img/feature_obj.gif");
+ }
+
+ @Override
+ public void fillStereotype() {
+ if (!applyStereotype()) {
+ log.warn(getId() + ": cannot fill the stereotype properties");
+ return;
+ }
+
+ // Id
+ String id = feature.getId();
+ representation.setValue(stereotype, ADL4Eclipse_Stereotypes.FEATURE_ID_ATT, id);
+
+ // Label
+ String label = feature.getLabel();
+ representation.setValue(stereotype, ADL4Eclipse_Stereotypes.FEATURE_LABEL_ATT, label);
+
+ // Version
+ String version = feature.getVersion();
+ representation.setValue(stereotype, ADL4Eclipse_Stereotypes.FEATURE_VERSION_ATT, version);
+
+ // Provider
+ String provider = feature.getProviderName();
+ representation.setValue(stereotype, ADL4Eclipse_Stereotypes.FEATURE_PROVIDER_ATT, provider);
+
+ IFeatureInfo featureInfoDescription = feature.getFeatureInfo(IFeature.INFO_DESCRIPTION);
+ if (featureInfoDescription != null) {
+ // Description
+ String description = getDescription();
+ representation.setValue(stereotype, ADL4Eclipse_Stereotypes.FEATURE_DESCRIPTION_ATT, description);
+
+ // Description URL
+ String descriptionURL = featureInfoDescription.getURL();
+ representation.setValue(stereotype, ADL4Eclipse_Stereotypes.FEATURE_DESCRIPTION_URL_ATT, descriptionURL);
+ }
+
+ IFeatureInfo featureInfoCopyright = feature.getFeatureInfo(IFeature.INFO_COPYRIGHT);
+ if (featureInfoCopyright != null) {
+ // Copyright
+ String copyright = feature.getFeatureInfo(IFeature.INFO_COPYRIGHT).getDescription();
+ representation.setValue(stereotype, ADL4Eclipse_Stereotypes.FEATURE_COPYRIGHT_ATT, copyright);
+
+ // Copyright URL
+ String copyrightURL = feature.getFeatureInfo(IFeature.INFO_COPYRIGHT).getURL();
+ representation.setValue(stereotype, ADL4Eclipse_Stereotypes.FEATURE_COPYRIGHT_URL_ATT, copyrightURL);
+ }
+
+ IFeatureInfo featureInfoLicense = feature.getFeatureInfo(IFeature.INFO_LICENSE);
+ if (featureInfoLicense != null) {
+ // License
+ String license = featureInfoLicense.getDescription();
+ representation.setValue(stereotype, ADL4Eclipse_Stereotypes.FEATURE_LICENSE_ATT, license);
+
+ // License URL
+ String licenseURL = feature.getFeatureInfo(IFeature.INFO_LICENSE).getURL();
+ representation.setValue(stereotype, ADL4Eclipse_Stereotypes.FEATURE_LICENSE_URL_ATT, licenseURL);
+ }
+
+ // URL
+ IFeatureURL featureUrl = feature.getURL();
+ if (featureUrl != null) {
+
+ IFeatureURLElement updateUrl = featureUrl.getUpdate();
+ if (updateUrl != null) {
+ // URL label
+ representation.setValue(stereotype, ADL4Eclipse_Stereotypes.FEATURE_URL_LABEL_ATT, updateUrl.getLabel());
+
+ URL url = updateUrl.getURL();
+ if (url != null) {
+ // URL address
+ representation.setValue(stereotype, ADL4Eclipse_Stereotypes.FEATURE_URL_ATT, url.toString());
+ }
+ }
+ }
+
+ // Operating system
+ representation.setValue(stereotype, ADL4Eclipse_Stereotypes.FEATURE_OS_ATT, feature.getOS());
+
+ // Window system
+ representation.setValue(stereotype, ADL4Eclipse_Stereotypes.FEATURE_WS_ATT, feature.getWS());
+
+ // Language
+ representation.setValue(stereotype, ADL4Eclipse_Stereotypes.FEATURE_LANGUAGES_ATT, feature.getNL());
+
+ // Architecture
+ representation.setValue(stereotype, ADL4Eclipse_Stereotypes.FEATURE_ARCHITECTURE_ATT, feature.getArch());
+
+ // Plug-ins
+ setStereotypeValues(ADL4Eclipse_Stereotypes.FEATURE_PLUGINS_ATT, feature.getPlugins(), OSGIStereotypes.BUNDLE_REFERENCE);
+
+ // Included Features
+ setStereotypeValues(ADL4Eclipse_Stereotypes.FEATURE_INCLUDED_FEATURES_ATT, feature.getIncludedFeatures(), ADL4Eclipse_Stereotypes.FEATURE_REFERENCE);
+
+ // Imported Features
+ setStereotypeValues(ADL4Eclipse_Stereotypes.FEATURE_FEATURE_DEPENDENCIES_ATT, feature.getImports(), ADL4Eclipse_Stereotypes.FEATURE_REFERENCE);
+
+ // Imported Plug-ins
+ setStereotypeValues(ADL4Eclipse_Stereotypes.FEATURE_PLUGIN_DEPENDENCIES_ATT, feature.getImports(), OSGIStereotypes.BUNDLE_REFERENCE);
+ }
+
+ /**
+ * Retrieves a list of stereotyped applications from an array of identifiable and
+ * store it in the feature's stereotype at the propertyName value.
+ *
+ * @param propertyName the name of the property to set the value.
+ * @param identifiables the array of identifiable to set
+ * @param stereotypeIdentifier the stereotype qualified name of the EObject to save
+ */
+ private void setStereotypeValues(String propertyName, IIdentifiable[] identifiables, String stereotypeIdentifier) {
+ List<EObject> pluginReferences = new ArrayList<>();
+
+ for (IIdentifiable identifiable : identifiables) {
+ // The stereotype takes stereotyped dependencies that are inside the representation
+ Dependency dependency = getElement(identifiable.getId(), Dependency.class);
+
+ if (dependency != null) {
+ Stereotype dependencyStereotype = dependency.getAppliedStereotype(stereotypeIdentifier);
+
+ if (dependencyStereotype != null) {
+ EObject stereotypeApplication = dependency.getStereotypeApplication(dependencyStereotype);
+
+ if (stereotypeApplication != null) {
+ pluginReferences.add(stereotypeApplication);
+ }
+ }
+ }
+ }
+
+ representation.setValue(stereotype, propertyName, pluginReferences);
+ }
+
+ @Override
+ public StereotypeVersion getReversibleVersion(Reversible<?> reversibleProject) {
+ return dependencyVersions.get(reversibleProject);
+ }
+
+ @Override
+ public void setReversibleVersion(Reversible<?> reversible, StereotypeVersion version) {
+ dependencyVersions.put(reversible, version);
+
+ }
+
+ public List<ReversibleProject> getIncludedReversibleFeatures() {
+ if (feature.getIncludedFeatures().length > 0) {
+ List<ReversibleProject> includedFeatures = new ArrayList<ReversibleProject>();
+ for (IFeatureChild includedFeature : feature.getIncludedFeatures()) {
+ includedFeatures.add(ReversibleFactory.getInstance().getFeature(includedFeature.getId()));
+ }
+ return includedFeatures;
+ }
+ return Collections.emptyList();
+ }
+
+ public List<ReversibleProject> getIncludedReversiblePlugins() {
+ if (feature.getPlugins().length > 0) {
+ List<ReversibleProject> includedPlugins = new ArrayList<ReversibleProject>();
+ for (IFeaturePlugin includedPlugin : feature.getPlugins()) {
+ includedPlugins.add(ReversibleFactory.getInstance().getPlugin(includedPlugin.getId()));
+ }
+ return includedPlugins;
+ }
+ return Collections.emptyList();
+ }
+
+}

Back to the top