diff options
author | Camille Letavernier | 2014-09-11 08:45:41 +0000 |
---|---|---|
committer | Gerrit Code Review @ Eclipse.org | 2014-09-11 08:45:42 +0000 |
commit | 73f75d36e58e1918b51aa4fa0f2619f64e05e0f0 (patch) | |
tree | b9cf40aa81ff279a4596af508548141bce5022a9 /plugins | |
parent | f294dc79fa607a671be145ab5fec2580020ba2f9 (diff) | |
parent | 5c11443da77dfac09bdcd06fcf2d29024d7d7ec5 (diff) | |
download | org.eclipse.papyrus-73f75d36e58e1918b51aa4fa0f2619f64e05e0f0.tar.gz org.eclipse.papyrus-73f75d36e58e1918b51aa4fa0f2619f64e05e0f0.tar.xz org.eclipse.papyrus-73f75d36e58e1918b51aa4fa0f2619f64e05e0f0.zip |
Merge "436666: "Stereotype repair" pop-up for already upgraded model https://bugs.eclipse.org/bugs/show_bug.cgi?id=436666"
Diffstat (limited to 'plugins')
3 files changed, 143 insertions, 24 deletions
diff --git a/plugins/uml/org.eclipse.papyrus.uml.modelrepair/src/org/eclipse/papyrus/uml/modelrepair/internal/participants/StereotypeApplicationRepairParticipant.java b/plugins/uml/org.eclipse.papyrus.uml.modelrepair/src/org/eclipse/papyrus/uml/modelrepair/internal/participants/StereotypeApplicationRepairParticipant.java index 4e9db793a6a..80d2bd42644 100644 --- a/plugins/uml/org.eclipse.papyrus.uml.modelrepair/src/org/eclipse/papyrus/uml/modelrepair/internal/participants/StereotypeApplicationRepairParticipant.java +++ b/plugins/uml/org.eclipse.papyrus.uml.modelrepair/src/org/eclipse/papyrus/uml/modelrepair/internal/participants/StereotypeApplicationRepairParticipant.java @@ -13,8 +13,10 @@ package org.eclipse.papyrus.uml.modelrepair.internal.participants; import java.util.Collection; +import java.util.LinkedList; import java.util.List; import java.util.Map; +import java.util.Queue; import java.util.regex.Pattern; import org.eclipse.core.runtime.IProgressMonitor; @@ -40,7 +42,6 @@ import org.eclipse.emf.ecore.EcorePackage; import org.eclipse.emf.ecore.resource.Resource; import org.eclipse.emf.ecore.resource.ResourceSet; import org.eclipse.emf.ecore.util.EcoreUtil; -import org.eclipse.emf.ecore.util.ExtendedMetaData; import org.eclipse.emf.ecore.util.FeatureMap; import org.eclipse.emf.ecore.xmi.XMLResource; import org.eclipse.emf.ecore.xml.type.AnyType; @@ -318,7 +319,15 @@ public class StereotypeApplicationRepairParticipant extends PackageOperations im // Handle case of unrecognized schema if (isUnrecognizedSchema(classifier.getEPackage()) && (profile.getDefinition() != null)) { // It's unrecognized content. Force look-up in the profile chosen by the user - EClassifier force = profile.getDefinition().getEClassifier(classifier.getName()); + EPackage definition = profile.getDefinition(); + EClassifier force = definition.getEClassifier(classifier.getName()); + if (force == null) { + // Maybe it's in some sub-package that was generated from a nested package + // containing stereotypes in the profile + if (!definition.getESubpackages().isEmpty()) { + force = searchSubpackages(definition, classifier); + } + } if (force != null) { element = force; } @@ -340,31 +349,31 @@ public class StereotypeApplicationRepairParticipant extends PackageOperations im return super.getNamedElement(element); } - protected boolean isUnrecognizedSchema(EPackage ePackage) { - boolean result; - - if (copying != null) { - result = getExtendedMetadata(copying).demandedPackages().contains(ePackage); - } else { - // Simple heuristic: unknown-schema packages don't have names, but profile-defined packages always do - result = (ePackage.getName() == null); + protected EClassifier searchSubpackages(EPackage ePackage, EClassifier unresolved) { + String nsPrefix = unresolved.getEPackage().getNsPrefix(); + EClassifier result = null; + String name = unresolved.getName(); + + // Breadth-first search because we do a prefix match, to prefer matches higher + // in the package structure in case of multiple same-named stereotypes + Queue<EPackage> search = new LinkedList<EPackage>(ePackage.getESubpackages()); + + for (EPackage next = search.poll(); (next != null) && (result == null); next = search.poll()) { + // Match on the package's nsPrefix, accounting for possible _1, _2, etc. suffixes + // for differentiation of EPackages that specify the same prefix + if ((nsPrefix == null) ? (next.getNsPrefix() == null) : nsPrefix.startsWith(next.getNsPrefix())) { + result = next.getEClassifier(name); + if ((result == null) && !next.getESubpackages().isEmpty()) { + search.addAll(next.getESubpackages()); + } + } } return result; } - protected ExtendedMetaData getExtendedMetadata(EObject context) { - ExtendedMetaData result = ExtendedMetaData.INSTANCE; - - Resource resource = context.eResource(); - if (resource instanceof XMLResource) { - Object option = ((XMLResource) resource).getDefaultSaveOptions().get(XMLResource.OPTION_EXTENDED_META_DATA); - if (option instanceof ExtendedMetaData) { - result = (ExtendedMetaData) option; - } - } - - return result; + protected boolean isUnrecognizedSchema(EPackage ePackage) { + return StereotypesUtil.isUnrecognizedSchema(ePackage, copying); } @Override diff --git a/plugins/uml/org.eclipse.papyrus.uml.modelrepair/src/org/eclipse/papyrus/uml/modelrepair/internal/participants/StereotypesUtil.java b/plugins/uml/org.eclipse.papyrus.uml.modelrepair/src/org/eclipse/papyrus/uml/modelrepair/internal/participants/StereotypesUtil.java new file mode 100644 index 00000000000..1bf9307e16c --- /dev/null +++ b/plugins/uml/org.eclipse.papyrus.uml.modelrepair/src/org/eclipse/papyrus/uml/modelrepair/internal/participants/StereotypesUtil.java @@ -0,0 +1,72 @@ +/***************************************************************************** + * Copyright (c) 2014 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.uml.modelrepair.internal.participants; + +import org.eclipse.emf.ecore.EObject; +import org.eclipse.emf.ecore.EPackage; +import org.eclipse.emf.ecore.resource.Resource; +import org.eclipse.emf.ecore.util.ExtendedMetaData; +import org.eclipse.emf.ecore.xmi.XMLResource; + +/** + * Utilities for working with stereotypes, profiles, etc. + */ +public class StereotypesUtil { + + /** + * Not instantiable by clients. + */ + private StereotypesUtil() { + super(); + } + + /** + * Queries whether a package, discovered in the context of some stereotype application, is a demand-created + * package created by EMF to record unrecognized schema content from the XML. + * + * @param ePackage + * a package (not {@code null}) + * @param stereotypeApplication + * the contextual stereotype application, or {@code null} if none is available + * + * @return whether the package looks like an unrecognized schema + */ + public static boolean isUnrecognizedSchema(EPackage ePackage, EObject stereotypeApplication) { + boolean result; + + if (stereotypeApplication != null) { + result = getExtendedMetadata(stereotypeApplication).demandedPackages().contains(ePackage); + } else { + // Simple heuristic: unknown-schema packages don't have names, but profile-defined packages always do + result = (ePackage.getName() == null); + } + + return result; + } + + private static ExtendedMetaData getExtendedMetadata(EObject context) { + ExtendedMetaData result = ExtendedMetaData.INSTANCE; + + Resource resource = context.eResource(); + if (resource instanceof XMLResource) { + Object option = ((XMLResource) resource).getDefaultSaveOptions().get(XMLResource.OPTION_EXTENDED_META_DATA); + if (option instanceof ExtendedMetaData) { + result = (ExtendedMetaData) option; + } + } + + return result; + } + +} diff --git a/plugins/uml/org.eclipse.papyrus.uml.modelrepair/src/org/eclipse/papyrus/uml/modelrepair/internal/stereotypes/ZombieStereotypesDescriptor.java b/plugins/uml/org.eclipse.papyrus.uml.modelrepair/src/org/eclipse/papyrus/uml/modelrepair/internal/stereotypes/ZombieStereotypesDescriptor.java index 3d28991c356..73199c701f3 100644 --- a/plugins/uml/org.eclipse.papyrus.uml.modelrepair/src/org/eclipse/papyrus/uml/modelrepair/internal/stereotypes/ZombieStereotypesDescriptor.java +++ b/plugins/uml/org.eclipse.papyrus.uml.modelrepair/src/org/eclipse/papyrus/uml/modelrepair/internal/stereotypes/ZombieStereotypesDescriptor.java @@ -34,6 +34,7 @@ import org.eclipse.emf.ecore.util.EcoreUtil; import org.eclipse.emf.ecore.util.FeatureMap; import org.eclipse.emf.ecore.util.FeatureMapUtil; import org.eclipse.papyrus.infra.services.labelprovider.service.LabelProviderService; +import org.eclipse.papyrus.uml.modelrepair.internal.participants.StereotypesUtil; import org.eclipse.uml2.uml.Element; import org.eclipse.uml2.uml.Extension; import org.eclipse.uml2.uml.Package; @@ -52,6 +53,7 @@ import com.google.common.collect.ImmutableSet; import com.google.common.collect.Iterables; import com.google.common.collect.Maps; import com.google.common.collect.Multimap; +import com.google.common.collect.Sets; /** @@ -80,14 +82,38 @@ public class ZombieStereotypesDescriptor { public ZombieStereotypesDescriptor(Resource resource, Package root, Set<EPackage> appliedProfileDefinitions, Function<? super EPackage, Profile> dynamicProfileSupplier, LabelProviderService labelProviderService) { this.resource = resource; this.root = root; - this.appliedProfileDefinitions = appliedProfileDefinitions; + this.appliedProfileDefinitions = includingSubpackages(appliedProfileDefinitions); this.dynamicProfileSupplier = dynamicProfileSupplier; this.labelProviderService = labelProviderService; } + /** + * Stereotypes may be defined in regular packages within a profile. To that end, collect all + * nested packages of the applied profile-definition packages as being implicitly "applied". + */ + private static Set<EPackage> includingSubpackages(Collection<? extends EPackage> profileDefinitions) { + final Set<EPackage> result = Sets.newHashSet(); + + for (EPackage next : profileDefinitions) { + collectPackages(next, result); + } + + return result; + } + + private static void collectPackages(EPackage ePackage, Collection<? super EPackage> result) { + if (result.add(ePackage)) { // Not exactly likely to have cycles + if (!ePackage.getESubpackages().isEmpty()) { + for (EPackage next : ePackage.getESubpackages()) { + collectPackages(next, result); + } + } + } + } + public void analyze(EObject stereotypeApplication) { EPackage schema = getEPackage(stereotypeApplication); - if ((schema == null) || !appliedProfileDefinitions.contains(schema)) { + if ((schema == null) || (!appliedProfileDefinitions.contains(schema) && couldBeProfileDefinition(schema, stereotypeApplication))) { // It's a zombie. Determine the profile-application context that covers this stereotype instance ProfileContext context = getProfileContext(stereotypeApplication, schema); @@ -108,6 +134,18 @@ public class ZombieStereotypesDescriptor { } } + protected boolean couldBeProfileDefinition(EPackage schema, EObject stereotypeApplication) { + // an EPackage could be a profile definition if either actually is one or + // it is a package demand-created by EMF for unrecognized content + boolean result = findProfile(schema) != null; + + if (!result) { + result = StereotypesUtil.isUnrecognizedSchema(schema, stereotypeApplication); + } + + return result; + } + public boolean hasZombies() { return !zombies.isEmpty(); } |