diff options
author | Christian W. Damus | 2021-02-02 18:48:39 +0000 |
---|---|---|
committer | Patrick Tessier | 2021-03-29 19:15:28 +0000 |
commit | 3c9a8bfbf91e2dcae1f5f30c2b3144f7339fefb7 (patch) | |
tree | 93f553e39bf087ab4ba5c9abc53c918fb21db9d1 /plugins/infra/core | |
parent | f4cc368beb7e01d2e3993f0f01cf4e3d93225d27 (diff) | |
download | org.eclipse.papyrus-3c9a8bfbf91e2dcae1f5f30c2b3144f7339fefb7.tar.gz org.eclipse.papyrus-3c9a8bfbf91e2dcae1f5f30c2b3144f7339fefb7.tar.xz org.eclipse.papyrus-3c9a8bfbf91e2dcae1f5f30c2b3144f7339fefb7.zip |
Bug 570856: [Toolsmiths][AF] Improve messages for command-class constraints
- introduce custom messages for problems in the command class attributes
- includes a second step to distinguish diagnosis of missing class versus
a class that doesn't implement the expected protocol
- requires generation of the plug-in class for the Papyrus Representation model
- update existing JUnit tests to accommodate new diagnostic messages
Change-Id: I351466b561700fdcda68d23b1385821d4d8fc1a9
Signed-off-by: Christian W. Damus <give.a.damus@gmail.com>
Diffstat (limited to 'plugins/infra/core')
3 files changed, 51 insertions, 11 deletions
diff --git a/plugins/infra/core/org.eclipse.papyrus.infra.core.architecture/plugin.properties b/plugins/infra/core/org.eclipse.papyrus.infra.core.architecture/plugin.properties index 6055ab0689f..2ab38948aae 100644 --- a/plugins/infra/core/org.eclipse.papyrus.infra.core.architecture/plugin.properties +++ b/plugins/infra/core/org.eclipse.papyrus.infra.core.architecture/plugin.properties @@ -14,3 +14,9 @@ pluginName = Architecture Model providerName=Eclipse Modeling Project + +_UI_creationCommandClassExists_diagnostic = Model creation command of ''{0}'' is not found in the Java classpath. +_UI_creationCommandClassConforms_diagnostic = Model creation command of ''{0}'' does not implement the {1} interface. +_UI_genericRequiredInterface_name = required +_UI_conversionCommandClassExists_diagnostic = Model conversion command of ''{0}'' is not found in the Java classpath. +_UI_conversionCommandClassConforms_diagnostic = Model conversion command of ''{0}'' does not implement the {1} interface. diff --git a/plugins/infra/core/org.eclipse.papyrus.infra.core.architecture/src-gen/org/eclipse/papyrus/infra/core/architecture/impl/ArchitectureContextImpl.java b/plugins/infra/core/org.eclipse.papyrus.infra.core.architecture/src-gen/org/eclipse/papyrus/infra/core/architecture/impl/ArchitectureContextImpl.java index dcfd450eddd..bd2f7121ecd 100644 --- a/plugins/infra/core/org.eclipse.papyrus.infra.core.architecture/src-gen/org/eclipse/papyrus/infra/core/architecture/impl/ArchitectureContextImpl.java +++ b/plugins/infra/core/org.eclipse.papyrus.infra.core.architecture/src-gen/org/eclipse/papyrus/infra/core/architecture/impl/ArchitectureContextImpl.java @@ -1,5 +1,5 @@ /** -* Copyright (c) 2017, 2021 CEA LIST, Christian W. Damus, and others. + * Copyright (c) 2017, 2021 CEA LIST, Christian W. Damus, and others. * * All rights reserved. This program and the accompanying materials * are made available under the terms of the Eclipse Public License 2.0 @@ -10,8 +10,7 @@ * * Contributors: * Maged Elaasar - Initial API and implementation - * Christian W. Damus - bug, 539694 - * + * Christian W. Damus - bugs 539694, 570856 * */ package org.eclipse.papyrus.infra.core.architecture.impl; @@ -29,7 +28,6 @@ import org.eclipse.emf.common.util.EList; import org.eclipse.emf.ecore.EClass; import org.eclipse.emf.ecore.InternalEObject; import org.eclipse.emf.ecore.impl.ENotificationImpl; -import org.eclipse.emf.ecore.plugin.EcorePlugin; import org.eclipse.emf.ecore.util.EObjectContainmentWithInverseEList; import org.eclipse.emf.ecore.util.EObjectResolvingEList; import org.eclipse.emf.ecore.util.EObjectValidator; @@ -294,13 +292,19 @@ public abstract class ArchitectureContextImpl extends ADElementImpl implements A if (!exists) { if (diagnostics != null) { + // Further narrow the problem + String problem = ArchitectureCommandUtils.getCommandClassUnconstrained(this, ArchitecturePackage.Literals.ARCHITECTURE_CONTEXT__CREATION_COMMAND_CLASS) == null + ? "_UI_creationCommandClassExists_diagnostic" : "_UI_creationCommandClassConforms_diagnostic"; //$NON-NLS-1$//$NON-NLS-2$ + String expectedInterface = ArchitectureCommandUtils.getCommandType( ArchitecturePackage.Literals.ARCHITECTURE_CONTEXT__CREATION_COMMAND_CLASS) + .map(Class::getSimpleName).orElse(ArchitecturePlugin.INSTANCE.getString("_UI_genericRequiredInterface_name")); //$NON-NLS-1$ + diagnostics.add (new BasicDiagnostic (Diagnostic.ERROR, ArchitectureValidator.DIAGNOSTIC_SOURCE, ArchitectureValidator.ARCHITECTURE_CONTEXT__CEATION_COMMAND_CLASS_EXISTS, - EcorePlugin.INSTANCE.getString("_UI_GenericInvariant_diagnostic", new Object[] { "ceationCommandClassExists", EObjectValidator.getObjectLabel(this, context) }), //$NON-NLS-1$ //$NON-NLS-2$ - new Object [] { this })); + ArchitecturePlugin.INSTANCE.getString(problem, new Object[] { EObjectValidator.getObjectLabel(this, context), expectedInterface }), + new Object [] { this, ArchitecturePackage.Literals.ARCHITECTURE_CONTEXT__CREATION_COMMAND_CLASS })); } return false; } @@ -322,13 +326,19 @@ public abstract class ArchitectureContextImpl extends ADElementImpl implements A if (!exists) { if (diagnostics != null) { + // Further narrow the problem + String problem = ArchitectureCommandUtils.getCommandClassUnconstrained(this, ArchitecturePackage.Literals.ARCHITECTURE_CONTEXT__CONVERSION_COMMAND_CLASS) == null + ? "_UI_conversionCommandClassExists_diagnostic" : "_UI_conversionCommandClassConforms_diagnostic"; //$NON-NLS-1$//$NON-NLS-2$ + String expectedInterface = ArchitectureCommandUtils.getCommandType( ArchitecturePackage.Literals.ARCHITECTURE_CONTEXT__CONVERSION_COMMAND_CLASS) + .map(Class::getSimpleName).orElse(ArchitecturePlugin.INSTANCE.getString("_UI_genericRequiredInterface_name")); //$NON-NLS-1$ + diagnostics.add (new BasicDiagnostic (Diagnostic.ERROR, ArchitectureValidator.DIAGNOSTIC_SOURCE, ArchitectureValidator.ARCHITECTURE_CONTEXT__CONVERSION_COMMAND_CLASS_EXISTS, - EcorePlugin.INSTANCE.getString("_UI_GenericInvariant_diagnostic", new Object[] { "conversionCommandClassExists", EObjectValidator.getObjectLabel(this, context) }), //$NON-NLS-1$ //$NON-NLS-2$ - new Object [] { this })); + ArchitecturePlugin.INSTANCE.getString(problem, new Object[] { EObjectValidator.getObjectLabel(this, context), expectedInterface }), + new Object [] { this, ArchitecturePackage.Literals.ARCHITECTURE_CONTEXT__CONVERSION_COMMAND_CLASS })); } return false; } diff --git a/plugins/infra/core/org.eclipse.papyrus.infra.core.architecture/src/org/eclipse/papyrus/infra/core/architecture/util/ArchitectureCommandUtils.java b/plugins/infra/core/org.eclipse.papyrus.infra.core.architecture/src/org/eclipse/papyrus/infra/core/architecture/util/ArchitectureCommandUtils.java index 15a58a6caa8..067fc3ae040 100644 --- a/plugins/infra/core/org.eclipse.papyrus.infra.core.architecture/src/org/eclipse/papyrus/infra/core/architecture/util/ArchitectureCommandUtils.java +++ b/plugins/infra/core/org.eclipse.papyrus.infra.core.architecture/src/org/eclipse/papyrus/infra/core/architecture/util/ArchitectureCommandUtils.java @@ -92,7 +92,8 @@ public class ArchitectureCommandUtils { } /** - * Get the command class referenced by the given feature of an architecture model object. + * Get the command class referenced by the given feature of an architecture model object, if it + * conforms to constraints (if any) declared in the Ecore model. * * @param modelObject * the architecture model object for which to load a command class @@ -105,9 +106,17 @@ public class ArchitectureCommandUtils { * {@code IType}, depending whether JDT is available */ public static Object getCommandClass(EObject modelObject, EStructuralFeature commandClassFeature) { + return getCommandClass(modelObject, commandClassFeature, getCommandType(commandClassFeature)); + } + + private static Object getCommandClass(EObject modelObject, EStructuralFeature commandClassFeature, Optional<Class<?>> registeredType) { if (commandClassFeature.getEType().getInstanceClass() == Class.class) { // Easy - return modelObject.eGet(commandClassFeature); + Class<?> result = (Class<?>) modelObject.eGet(commandClassFeature); + if (result != null && registeredType.isPresent() && !registeredType.get().isAssignableFrom(result)) { + result = null; + } + return result; } String className = Optional.ofNullable(modelObject.eGet(commandClassFeature)).map(String::valueOf).orElse(null); @@ -116,10 +125,25 @@ public class ArchitectureCommandUtils { return null; } - Optional<Class<?>> registeredType = getCommandType(commandClassFeature); URI context = EcoreUtil.getURI(modelObject).trimFragment(); return ClasspathHelper.INSTANCE.findClass(className, context, registeredType.orElse(null)); } + /** + * Get the command class referenced by the given feature of an architecture model object, not considering + * any constraints imposed on it by the Ecore model. + * + * @param modelObject + * the architecture model object for which to load a command class + * @param commandClassFeature + * the model feature that names the command class + * @return + * the referenced class, or {@code null} if the class doesn't exist. The result may be a Java + * {@link Class} or a JDT {@code IType}, depending whether JDT is available + */ + public static Object getCommandClassUnconstrained(EObject modelObject, EStructuralFeature commandClassFeature) { + return getCommandClass(modelObject, commandClassFeature, Optional.empty()); + } + } |