diff --git a/common/plugins/org.polarsys.capella.common.transition/src/org/polarsys/capella/core/transition/common/ExtensionHelper.java b/common/plugins/org.polarsys.capella.common.transition/src/org/polarsys/capella/core/transition/common/ExtensionHelper.java index 14097106cb..bf8f7a1f38 100644 --- a/common/plugins/org.polarsys.capella.common.transition/src/org/polarsys/capella/core/transition/common/ExtensionHelper.java +++ b/common/plugins/org.polarsys.capella.common.transition/src/org/polarsys/capella/core/transition/common/ExtensionHelper.java @@ -19,7 +19,9 @@ import org.eclipse.core.runtime.CoreException; import org.eclipse.core.runtime.IConfigurationElement; import org.eclipse.core.runtime.IExtensionPoint; +import org.eclipse.core.runtime.IStatus; import org.eclipse.core.runtime.Platform; +import org.eclipse.core.runtime.Status; import org.polarsys.capella.core.transition.common.constants.ISchemaConstants; import org.polarsys.capella.core.transition.common.handlers.IHandler; import org.polarsys.kitalpha.transposer.rules.handler.rules.api.IContext; @@ -70,23 +72,18 @@ protected static boolean isValidExtension(IConfigurationElement element, String return false; } - public static Collection collectFromExtensions(IContext context, String extension_id, String childName, - String expectedPurpose, String expectedMapping) { + @SuppressWarnings("unchecked") + public static Collection collectFromExtensions(IContext context, String extension_id, String childName, String expectedPurpose, String expectedMapping){ IExtensionPoint point = Platform.getExtensionRegistry().getExtensionPoint(extension_id); - Collection result = new LinkedList(); - + Collection result = new LinkedList<>(); for (IConfigurationElement element : point.getConfigurationElements()) { if (isValidExtension(element, expectedPurpose, expectedMapping)) { for (IConfigurationElement child : element.getChildren()) { - if (childName.equals(child.getName())) { try { - Object extension = child.createExecutableExtension(ISchemaConstants.CLASS); - if ((extension != null) && (extension instanceof IHandler)) { - result.add((IHandler) extension); - } - } catch (CoreException exception) { - // Catch exception silently, we just can't load an extension + result.add((T) child.createExecutableExtension(ISchemaConstants.CLASS)); + } catch (CoreException e) { + Activator.getDefault().getLog().log(new Status(IStatus.ERROR, Activator.PLUGIN_ID, e.getMessage(), e)); } } } diff --git a/common/plugins/org.polarsys.capella.common.transition/src/org/polarsys/capella/core/transition/common/handlers/IHandler.java b/common/plugins/org.polarsys.capella.common.transition/src/org/polarsys/capella/core/transition/common/handlers/IHandler.java index f7d617d9d1..47cc495225 100644 --- a/common/plugins/org.polarsys.capella.common.transition/src/org/polarsys/capella/core/transition/common/handlers/IHandler.java +++ b/common/plugins/org.polarsys.capella.common.transition/src/org/polarsys/capella/core/transition/common/handlers/IHandler.java @@ -13,16 +13,17 @@ package org.polarsys.capella.core.transition.common.handlers; import org.eclipse.core.runtime.IStatus; - +import org.eclipse.core.runtime.Status; import org.polarsys.kitalpha.transposer.rules.handler.rules.api.IContext; -/** - * - */ public interface IHandler { - IStatus init(IContext context); + default IStatus init(IContext context) { + return new Status(IStatus.OK, getClass().getCanonicalName(), "init ok"); //$NON-NLS-1$ + } - IStatus dispose(IContext context); + default IStatus dispose(IContext context) { + return Status.OK_STATUS; + } } diff --git a/common/plugins/org.polarsys.capella.common.transition/src/org/polarsys/capella/core/transition/common/handlers/scope/EReferenceScopeRetriever.java b/common/plugins/org.polarsys.capella.common.transition/src/org/polarsys/capella/core/transition/common/handlers/scope/EReferenceScopeRetriever.java new file mode 100644 index 0000000000..1a5736effb --- /dev/null +++ b/common/plugins/org.polarsys.capella.common.transition/src/org/polarsys/capella/core/transition/common/handlers/scope/EReferenceScopeRetriever.java @@ -0,0 +1,47 @@ +/******************************************************************************* + * Copyright (c) 2020 THALES GLOBAL SERVICES. + * + * This program and the accompanying materials are made available under the + * terms of the Eclipse Public License 2.0 which is available at + * http://www.eclipse.org/legal/epl-2.0 + * + * SPDX-License-Identifier: EPL-2.0 + * + * Contributors: + * Thales - initial API and implementation + *******************************************************************************/ +package org.polarsys.capella.core.transition.common.handlers.scope; + +import java.util.Collection; +import java.util.Collections; + +import org.eclipse.emf.ecore.EClass; +import org.eclipse.emf.ecore.EObject; +import org.eclipse.emf.ecore.EReference; +import org.polarsys.kitalpha.transposer.rules.handler.rules.api.IContext; + +public class EReferenceScopeRetriever implements IScopeRetriever { + private final EReference ref; + + public EReferenceScopeRetriever(EReference ref) { + this.ref = ref; + } + + @SuppressWarnings("unchecked") + @Override + public Collection retrieveRelatedElements(EObject element, IContext context) { + EClass refClass = ref.getEContainingClass(); + if (refClass.isInstance(element)) { + if (element.eIsSet(ref)) { + Object target = element.eGet(ref); + if (ref.isMany()) { + return (Collection) element.eGet(ref); + } else if (target != null) { + return (Collection) Collections.singleton(target); + } + } + } + return Collections.emptyList(); + } + +} diff --git a/common/plugins/org.polarsys.capella.common.transition/src/org/polarsys/capella/core/transition/common/handlers/scope/IScopeRetriever.java b/common/plugins/org.polarsys.capella.common.transition/src/org/polarsys/capella/core/transition/common/handlers/scope/IScopeRetriever.java index 7047fb7995..f2eece5b52 100644 --- a/common/plugins/org.polarsys.capella.common.transition/src/org/polarsys/capella/core/transition/common/handlers/scope/IScopeRetriever.java +++ b/common/plugins/org.polarsys.capella.common.transition/src/org/polarsys/capella/core/transition/common/handlers/scope/IScopeRetriever.java @@ -13,9 +13,9 @@ package org.polarsys.capella.core.transition.common.handlers.scope; import java.util.Collection; +import java.util.Collections; import org.eclipse.emf.ecore.EObject; - import org.polarsys.capella.core.transition.common.handlers.IHandler; import org.polarsys.kitalpha.transposer.rules.handler.rules.api.IContext; @@ -29,8 +29,12 @@ public interface IScopeRetriever extends IHandler { * @param context * @return */ - Collection retrieveRelatedElements(EObject element, IContext context); + default Collection retrieveRelatedElements(EObject element, IContext context){ + return Collections.emptyList(); + } - Collection retrieveSharedElements(IContext context); + default Collection retrieveSharedElements(IContext context){ + return Collections.emptyList(); + } } diff --git a/common/plugins/org.polarsys.capella.common.transition/src/org/polarsys/capella/core/transition/common/handlers/scope/TypedScopeRetriever.java b/common/plugins/org.polarsys.capella.common.transition/src/org/polarsys/capella/core/transition/common/handlers/scope/TypedScopeRetriever.java new file mode 100644 index 0000000000..967dec8883 --- /dev/null +++ b/common/plugins/org.polarsys.capella.common.transition/src/org/polarsys/capella/core/transition/common/handlers/scope/TypedScopeRetriever.java @@ -0,0 +1,42 @@ +/******************************************************************************* + * Copyright (c) 2020 THALES GLOBAL SERVICES. + * + * This program and the accompanying materials are made available under the + * terms of the Eclipse Public License 2.0 which is available at + * http://www.eclipse.org/legal/epl-2.0 + * + * SPDX-License-Identifier: EPL-2.0 + * + * Contributors: + * Thales - initial API and implementation + *******************************************************************************/ +package org.polarsys.capella.core.transition.common.handlers.scope; + +import java.util.Collection; +import java.util.Collections; + +import org.eclipse.emf.ecore.EObject; +import org.polarsys.kitalpha.transposer.rules.handler.rules.api.IContext; + +public abstract class TypedScopeRetriever implements IScopeRetriever { + + private final Class clazz; + + public TypedScopeRetriever(Class clazz) { + this.clazz = clazz; + } + + @SuppressWarnings("unchecked") + @Override + public final Collection retrieveRelatedElements(EObject element, IContext context) { + if (clazz.isInstance(element)) { + return doRetrieveRelatedElements((T) element, context); + } + return Collections.emptyList(); + } + + protected Collection doRetrieveRelatedElements(T element, IContext context) { + return Collections.emptyList(); + } + +} diff --git a/core/plugins/org.polarsys.capella.core.data.fa.ui.wizards/src/org/polarsys/capella/core/data/fa/ui/wizards/dialogs/EIAllocationLabelProvider.java b/core/plugins/org.polarsys.capella.core.data.fa.ui.wizards/src/org/polarsys/capella/core/data/fa/ui/wizards/dialogs/EIAllocationLabelProvider.java index 218f3e8387..a57d23e44e 100644 --- a/core/plugins/org.polarsys.capella.core.data.fa.ui.wizards/src/org/polarsys/capella/core/data/fa/ui/wizards/dialogs/EIAllocationLabelProvider.java +++ b/core/plugins/org.polarsys.capella.core.data.fa.ui.wizards/src/org/polarsys/capella/core/data/fa/ui/wizards/dialogs/EIAllocationLabelProvider.java @@ -12,7 +12,6 @@ *******************************************************************************/ package org.polarsys.capella.core.data.fa.ui.wizards.dialogs; -import java.util.ArrayList; import java.util.Arrays; import java.util.List; @@ -20,6 +19,7 @@ import org.eclipse.emf.ecore.EObject; import org.eclipse.emf.validation.service.IConstraintDescriptor; import org.eclipse.emf.validation.service.IConstraintFilter; +import org.eclipse.emf.validation.service.IValidator; import org.eclipse.jface.viewers.IBaseLabelProvider; import org.eclipse.jface.viewers.IColorProvider; import org.eclipse.jface.viewers.IFontProvider; @@ -30,7 +30,6 @@ import org.eclipse.swt.widgets.TreeItem; import org.eclipse.swt.widgets.Widget; import org.polarsys.capella.common.ui.providers.MDEAdapterFactoryLabelProvider; -import org.polarsys.capella.core.validation.CapellaValidationActivator; import org.polarsys.capella.core.validation.utils.ValidationHelper; public class EIAllocationLabelProvider extends MDEAdapterFactoryLabelProvider implements IBaseLabelProvider, IColorProvider, IFontProvider { @@ -38,33 +37,41 @@ public class EIAllocationLabelProvider extends MDEAdapterFactoryLabelProvider im private final EIAllocationTreeViewer treeViewer; private LinkManager linkManager; private Font startedLinkElementFont; - - private IConstraintFilter _filter = new IConstraintFilter() { - @Override - public boolean accept(IConstraintDescriptor constraint, EObject target) { - return (isSourceViewer ? _srcDesc.contains(constraint) : _tgtDesc.contains(constraint)); - } - }; - - private static final String prefix = "org.polarsys.capella.core.data.fa.validation."; //$NON-NLS-1$ - - protected List _srcDesc = getConstraintDescriptors(Arrays.asList( - new String[]{prefix+"TC_DF_10",prefix+"TC_DF_11",prefix+"TC_DF_12",prefix+"TC_DF_13",prefix+"TC_DF_14"})); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ //$NON-NLS-4$ //$NON-NLS-5$; - - protected List _tgtDesc = getConstraintDescriptors(Arrays.asList( - new String[]{prefix+"TC_DF_11",prefix+"TC_DF_12",prefix+"TC_DF_13",prefix+"TC_DF_14"})); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ //$NON-NLS-4$ //; + private final IValidator validator; + public final static String VALIDATION_KEY = "Validation"; //$NON-NLS-1$ + + @SuppressWarnings("nls") + private static List _srcDesc = Arrays.asList( + "org.polarsys.capella.core.data.fa.validation.TC_DF_10", + "org.polarsys.capella.core.data.fa.validation.TC_DF_11", + "org.polarsys.capella.core.data.fa.validation.TC_DF_12", + "org.polarsys.capella.core.data.fa.validation.TC_DF_13", + "org.polarsys.capella.core.data.fa.validation.TC_DF_14"); + + @SuppressWarnings("nls") + private static List _tgtDesc = Arrays.asList( + "org.polarsys.capella.core.data.fa.validation.TC_DF_11", + "org.polarsys.capella.core.data.fa.validation.TC_DF_12", + "org.polarsys.capella.core.data.fa.validation.TC_DF_13", + "org.polarsys.capella.core.data.fa.validation.TC_DF_14"); /** * @param linkManager * @param treeViewer * @param isSourceViewer */ - public EIAllocationLabelProvider(LinkManager linkManager, EIAllocationTreeViewer treeViewer, boolean isSourceViewer) { - super(); - this.isSourceViewer = isSourceViewer; + public EIAllocationLabelProvider(LinkManager linkManager, EIAllocationTreeViewer treeViewer, boolean isSourceViewer) { + this.isSourceViewer = isSourceViewer; this.treeViewer = treeViewer; this.linkManager = linkManager; - } + validator = ValidationHelper.newDefaultCapellaBatchValidator(); + validator.addConstraintFilter(new IConstraintFilter() { + @Override + public boolean accept(IConstraintDescriptor constraint, EObject target) { + return (isSourceViewer ? _srcDesc.contains(constraint.getId()) : _tgtDesc.contains(constraint.getId())); + } + }); + } /** * @see org.eclipse.emf.edit.ui.provider.AdapterFactoryLabelProvider#dispose() @@ -102,13 +109,8 @@ public Font getFont(Object element) { return super.getFont(element); } - public final static String VALIDATION_KEY = "Validation"; //$NON-NLS-1$ - private boolean isValid(EObject element) { - CapellaValidationActivator.getDefault().getCapellaValidatorAdapter().getValidator().addConstraintFilter(_filter); - IStatus status = CapellaValidationActivator.getDefault().getCapellaValidatorAdapter().getValidator().validate(element); - CapellaValidationActivator.getDefault().getCapellaValidatorAdapter().getValidator().removeConstraintFilter(_filter); - + IStatus status = validator.validate(element); Widget w = treeViewer.findItem(element); if (w instanceof TreeItem) { if (!status.isOK()) { @@ -124,31 +126,13 @@ private boolean isValid(EObject element) { * {@inheritDoc} */ @Override - public Color getForeground(Object element) { + public Color getForeground(Object element) { if (!isValid((EObject) element)) { return Display.getCurrent().getSystemColor(SWT.COLOR_RED); } - return super.getForeground(element); - } - - /** - * Get all constraints contributed via the EMF Validation framework for Capella purposes - * e.g. rules stored into the Capella constraint category - * @return - */ - public static List getConstraintDescriptors(List ids) { - List result = new ArrayList(); - - ValidationHelper.ensureEMFValidationActivation(); - - for (IConstraintDescriptor icd: ValidationHelper.getAllCapellaConstraintDescriptors()) { - String id = icd.getId(); - if (ids.contains(id)) { - result.add(icd); - } - } - return result; + return super.getForeground(element); } + /** * Create started link element font. diff --git a/core/plugins/org.polarsys.capella.core.model.handler/schema/diagnosticianProviders.exsd b/core/plugins/org.polarsys.capella.core.model.handler/schema/diagnosticianProviders.exsd index 7ab5bbe301..913ff380d3 100644 --- a/core/plugins/org.polarsys.capella.core.model.handler/schema/diagnosticianProviders.exsd +++ b/core/plugins/org.polarsys.capella.core.model.handler/schema/diagnosticianProviders.exsd @@ -3,10 +3,10 @@ - + - Allows plugins to choose a diagnostician for model validation + Allows plugins to contribute EMF Diagnosticians for model validation @@ -17,7 +17,7 @@ - + @@ -59,6 +59,27 @@ + + + + The ID for this provider + + + + + + + Description of this provider + + + + + + + + + + diff --git a/core/plugins/org.polarsys.capella.core.model.handler/src/org/polarsys/capella/core/model/handler/validation/AbstractDiagnosticianProvider.java b/core/plugins/org.polarsys.capella.core.model.handler/src/org/polarsys/capella/core/model/handler/validation/AbstractDiagnosticianProvider.java index e493096438..7024c88b18 100644 --- a/core/plugins/org.polarsys.capella.core.model.handler/src/org/polarsys/capella/core/model/handler/validation/AbstractDiagnosticianProvider.java +++ b/core/plugins/org.polarsys.capella.core.model.handler/src/org/polarsys/capella/core/model/handler/validation/AbstractDiagnosticianProvider.java @@ -18,6 +18,6 @@ public abstract class AbstractDiagnosticianProvider { - public abstract Diagnostician getDiagnostician(AdapterFactory adapterFactory_p, IProgressMonitor progressMonitor_p); - + public abstract Diagnostician getDiagnostician(AdapterFactory adapterFactory_p, IProgressMonitor progressMonitor_p); + } diff --git a/core/plugins/org.polarsys.capella.core.model.handler/src/org/polarsys/capella/core/model/handler/validation/CapellaDiagnostician.java b/core/plugins/org.polarsys.capella.core.model.handler/src/org/polarsys/capella/core/model/handler/validation/CapellaDiagnostician.java index 3c1e7b14df..283e882e94 100644 --- a/core/plugins/org.polarsys.capella.core.model.handler/src/org/polarsys/capella/core/model/handler/validation/CapellaDiagnostician.java +++ b/core/plugins/org.polarsys.capella.core.model.handler/src/org/polarsys/capella/core/model/handler/validation/CapellaDiagnostician.java @@ -19,6 +19,7 @@ import org.eclipse.emf.common.util.DiagnosticChain; import org.eclipse.emf.ecore.EClass; import org.eclipse.emf.ecore.EObject; +import org.eclipse.emf.ecore.EValidator; import org.eclipse.emf.ecore.util.Diagnostician; import org.eclipse.emf.ecore.util.EcoreUtil; import org.eclipse.emf.edit.provider.IItemLabelProvider; @@ -35,12 +36,17 @@ public class CapellaDiagnostician extends Diagnostician { private AdapterFactory adapterFactory; private IProgressMonitor progressMonitor; - public CapellaDiagnostician (AdapterFactory adapterFactory_p, IProgressMonitor progressMonitor_p) { - adapterFactory = adapterFactory_p; - progressMonitor = progressMonitor_p; + public CapellaDiagnostician (AdapterFactory adapterFactory, IProgressMonitor progressMonitor) { + this(EValidator.Registry.INSTANCE, adapterFactory, progressMonitor); } - @Override + public CapellaDiagnostician (EValidator.Registry registry, AdapterFactory adapterFactory, IProgressMonitor monitor) { + super(registry); + this.adapterFactory = adapterFactory; + this.progressMonitor = monitor; + } + + @Override public String getObjectLabel(EObject eObject) { if (adapterFactory != null && !eObject.eIsProxy()) { IItemLabelProvider itemLabelProvider = (IItemLabelProvider)adapterFactory.adapt(eObject, IItemLabelProvider.class); diff --git a/core/plugins/org.polarsys.capella.core.model.handler/src/org/polarsys/capella/core/model/handler/validation/DiagnosticianProviderRegistry.java b/core/plugins/org.polarsys.capella.core.model.handler/src/org/polarsys/capella/core/model/handler/validation/DiagnosticianProviderRegistry.java new file mode 100644 index 0000000000..5c705da8a0 --- /dev/null +++ b/core/plugins/org.polarsys.capella.core.model.handler/src/org/polarsys/capella/core/model/handler/validation/DiagnosticianProviderRegistry.java @@ -0,0 +1,87 @@ +/******************************************************************************* + * Copyright (c) 2020 THALES GLOBAL SERVICES. + * + * This program and the accompanying materials are made available under the + * terms of the Eclipse Public License 2.0 which is available at + * http://www.eclipse.org/legal/epl-2.0 + * + * SPDX-License-Identifier: EPL-2.0 + * + * Contributors: + * Thales - initial API and implementation + *******************************************************************************/ +package org.polarsys.capella.core.model.handler.validation; + +import java.util.ArrayList; +import java.util.Collection; +import java.util.Collections; + +import org.eclipse.core.runtime.CoreException; +import org.eclipse.core.runtime.IConfigurationElement; +import org.eclipse.core.runtime.IStatus; +import org.eclipse.core.runtime.Platform; +import org.eclipse.core.runtime.Status; +import org.polarsys.capella.core.model.handler.ModelHandlerPlugin; + +/** + * Reads registered {@link AbstractDiagnosticianProvider}s from the extension registry. + */ +public final class DiagnosticianProviderRegistry { + + public static final String DIAGNOSTICIAN_PROVIDER_EXTENSION = ModelHandlerPlugin.PLUGIN_ID + ".diagnosticianProviders"; //$NON-NLS-1$ + public static final DiagnosticianProviderRegistry INSTANCE = new DiagnosticianProviderRegistry(); + + public final Collection providerDescriptors; + + private DiagnosticianProviderRegistry() { + providerDescriptors = readProviderDescriptors(); + } + + private Collection readProviderDescriptors() { + Collection result = new ArrayList(); + IConfigurationElement[] elems = Platform.getExtensionRegistry().getConfigurationElementsFor(DIAGNOSTICIAN_PROVIDER_EXTENSION); + for (IConfigurationElement e : elems) { + result.add(new Descriptor(e)); + } + return Collections.unmodifiableCollection(result); + } + + public Collection getDescriptors(){ + return providerDescriptors; + } + + public static AbstractDiagnosticianProvider getDiagnosticianProvider(String providerId) throws CoreException { + for (DiagnosticianProviderRegistry.Descriptor d : INSTANCE.getDescriptors()) { + if (providerId.equals(d.getID())){ + return d.getProvider(); + } + } + throw new CoreException(new Status(IStatus.ERROR, ModelHandlerPlugin.PLUGIN_ID, "No diagnostician provider with id: " + providerId)); //$NON-NLS-1$ + } + + public static class Descriptor { + + private final IConfigurationElement element; + + Descriptor(IConfigurationElement descriptor) { + this.element = descriptor; + } + + public String getID() { + return element.getAttribute("id"); //$NON-NLS-1$ + } + + public AbstractDiagnosticianProvider getProvider() throws CoreException { + return (AbstractDiagnosticianProvider) element.createExecutableExtension("class"); //$NON-NLS-1$ + } + + public String getName() { + return element.getAttribute("name"); //$NON-NLS-1$ + } + + public String getDescription() { + return element.getAttribute("description"); //$NON-NLS-1$ + } + } + +} diff --git a/core/plugins/org.polarsys.capella.core.model.handler/src/org/polarsys/capella/core/model/handler/validation/MultiobjectDiagnostician.java b/core/plugins/org.polarsys.capella.core.model.handler/src/org/polarsys/capella/core/model/handler/validation/MultiobjectDiagnostician.java new file mode 100644 index 0000000000..671ce07481 --- /dev/null +++ b/core/plugins/org.polarsys.capella.core.model.handler/src/org/polarsys/capella/core/model/handler/validation/MultiobjectDiagnostician.java @@ -0,0 +1,35 @@ +/******************************************************************************* + * Copyright (c) 2020 THALES GLOBAL SERVICES. + * + * This program and the accompanying materials are made available under the + * terms of the Eclipse Public License 2.0 which is available at + * http://www.eclipse.org/legal/epl-2.0 + * + * SPDX-License-Identifier: EPL-2.0 + * + * Contributors: + * Thales - initial API and implementation + *******************************************************************************/ +package org.polarsys.capella.core.model.handler.validation; + +import java.util.Collection; +import java.util.Map; + +import org.eclipse.emf.common.util.DiagnosticChain; +import org.eclipse.emf.ecore.EObject; +import org.eclipse.emf.ecore.EValidator; +import org.eclipse.emf.ecore.util.Diagnostician; + +/** + * A {@link Diagnostician} that accepts a collection of {@link EObject}s + * for validation. + */ +public abstract class MultiobjectDiagnostician extends Diagnostician { + + public MultiobjectDiagnostician(EValidator.Registry registry) { + super(registry); + } + + public abstract boolean validate(Collection eObjects, DiagnosticChain diagnostics, Map context); + +} diff --git a/core/plugins/org.polarsys.capella.core.platform.sirius.ui.actions/src/org/polarsys/capella/core/platform/sirius/ui/actions/CapellaValidateAction.java b/core/plugins/org.polarsys.capella.core.platform.sirius.ui.actions/src/org/polarsys/capella/core/platform/sirius/ui/actions/CapellaValidateAction.java index f39f714a5e..e7125e879f 100644 --- a/core/plugins/org.polarsys.capella.core.platform.sirius.ui.actions/src/org/polarsys/capella/core/platform/sirius/ui/actions/CapellaValidateAction.java +++ b/core/plugins/org.polarsys.capella.core.platform.sirius.ui.actions/src/org/polarsys/capella/core/platform/sirius/ui/actions/CapellaValidateAction.java @@ -15,18 +15,24 @@ import java.lang.reflect.InvocationTargetException; import java.util.ArrayList; +import java.util.Collections; import java.util.List; +import java.util.Map; import org.eclipse.core.resources.IFile; import org.eclipse.core.resources.IMarker; import org.eclipse.core.runtime.CoreException; import org.eclipse.core.runtime.IProgressMonitor; import org.eclipse.core.runtime.IStatus; +import org.eclipse.core.runtime.Platform; import org.eclipse.emf.common.notify.AdapterFactory; +import org.eclipse.emf.common.util.BasicDiagnostic; import org.eclipse.emf.common.util.Diagnostic; import org.eclipse.emf.ecore.EObject; import org.eclipse.emf.ecore.resource.Resource; import org.eclipse.emf.ecore.util.Diagnostician; +import org.eclipse.emf.ecore.util.EObjectValidator; +import org.eclipse.emf.edit.domain.AdapterFactoryEditingDomain; import org.eclipse.emf.edit.ui.EMFEditUIPlugin; import org.eclipse.emf.edit.ui.action.ValidateAction; import org.eclipse.jface.dialogs.ProgressMonitorDialog; @@ -36,6 +42,7 @@ import org.eclipse.swt.widgets.Shell; import org.eclipse.ui.PartInitException; import org.eclipse.ui.PlatformUI; +import org.eclipse.ui.statushandlers.StatusManager; import org.polarsys.capella.common.ef.ExecutionManager; import org.polarsys.capella.common.ef.command.AbstractReadOnlyCommand; import org.polarsys.capella.common.helpers.TransactionHelper; @@ -46,7 +53,9 @@ import org.polarsys.capella.common.tools.report.appenders.usage.util.UsageMonitoring.EventStatus; import org.polarsys.capella.core.commands.preferences.service.AbstractPreferencesInitializer; import org.polarsys.capella.core.model.handler.markers.ICapellaValidationConstants; -import org.polarsys.capella.core.model.handler.validation.PluggableDiagnosticianProvider; +import org.polarsys.capella.core.model.handler.validation.AbstractDiagnosticianProvider; +import org.polarsys.capella.core.model.handler.validation.DiagnosticianProviderRegistry; +import org.polarsys.capella.core.model.handler.validation.MultiobjectDiagnostician; import org.polarsys.capella.core.platform.sirius.ui.preferences.ICapellaValidationPreferences; /** @@ -64,79 +73,32 @@ public class CapellaValidateAction extends ValidateAction { */ public CapellaValidateAction() { super(); - eclipseResourcesUtil = new EclipseResourcesUtil() { - - /** - * {@inheritDoc} - */ - @Override - protected String getMarkerID() { - return ICapellaValidationConstants.CAPELLA_MARKER_ID; - } - - /** - * @see org.eclipse.emf.edit.ui.action.ValidateAction.EclipseResourcesUtil#createMarkers(org.eclipse.emf.ecore.resource.Resource, - * org.eclipse.emf.common.util.Diagnostic) - */ - @Override - public void createMarkers(Resource resource, Diagnostic diagnostic) { - // Don't use 'traditional' resource markers. TODO investigate to go back to the traditional ones. - // Original reasons to switch: CDO and too many workspace notifications (especially in transitions) - - // can't use resource, see handleDiagnostics below - LightMarkerRegistry.getInstance().createMarker(getFile(_currentResource), diagnostic, getMarkerID()); - } - - /** - * @see org.eclipse.emf.edit.ui.util.EditUIMarkerHelper#deleteMarkers(java.lang.Object, boolean, int) - */ - @Override - public void deleteMarkers(Object object, boolean includeSubtypes, int depth) { - boolean cleanup = AbstractPreferencesInitializer.getBoolean(ICapellaValidationPreferences.P_CLEAN_PREVIOUS_VALIDATION_RESULTS, false); - if (cleanup) { - List markers = new ArrayList(LightMarkerRegistry.getInstance().getMarkers()); - for (IMarker marker : markers) { - try { - if (marker.getType().equals(getMarkerID())) { - marker.delete(); - } - } catch (CoreException e) { - CapellaActionsActivator.getDefault().log(IStatus.ERROR, e.getMessage(), e); - } - } - } - } - - /** - * Overridden to redirect markers to target to the .aird file so that - * relevant markers can be removed when the corresponding session is closed - * (see {@link org.polarsys.capella.core.ui.reportlog.InformationViewSessionListener}) - */ - @Override - protected IFile getFile(Object datum) { - Object derivedDatum = datum; - if (datum instanceof EObject) { - Session session = SessionManager.INSTANCE.getSession((EObject) datum); - if (session != null) { - derivedDatum = session.getSessionResource(); - } - } else if (datum instanceof Resource) { - Session session = SessionManager.INSTANCE.getSession((Resource) datum); - if (session != null) { - derivedDatum = session.getSessionResource(); - } - } - - return super.getFile(derivedDatum); - } - - }; - + eclipseResourcesUtil = new ResourcesUtil(); } @Override protected Diagnostician createDiagnostician(AdapterFactory adapterFactory, IProgressMonitor progressMonitor) { - return new PluggableDiagnosticianProvider().getDiagnostician(adapterFactory, progressMonitor); + String providerID = getDiagnosticianProviderId(); + if (providerID != null) { + try { + AbstractDiagnosticianProvider provider = DiagnosticianProviderRegistry.getDiagnosticianProvider(providerID); + return provider.getDiagnostician(adapterFactory, progressMonitor); + } catch (CoreException e) { + StatusManager.getManager().handle(e, CapellaActionsActivator.PLUGIN_ID); + } + return null; + } + return new Diagnostician(); + } + + /** + * Get the id for the DiagnosticianProvider to use. This defaults to whatever is + * set in the Capella preferences. + * + * Subclasses may override to use a concrete diagnostician provider. + */ + protected String getDiagnosticianProviderId() { + return Platform.getPreferencesService().getString(org.polarsys.capella.core.preferences.Activator.PLUGIN_ID, ICapellaValidationPreferences.P_DIAGNOSTICIAN_PROVIDER, null, null); } /** @@ -197,19 +159,19 @@ public void run() { runnableWithProgress = eclipseResourcesUtil.getWorkspaceModifyOperation(runnableWithProgress); } - String eventName = "Validation"; - String eventContext = ICommonConstants.EMPTY_STRING; - String addendum = ICommonConstants.EMPTY_STRING; - + String eventName = "Validation"; //$NON-NLS-1$ + String eventContext = ICommonConstants.EMPTY_STRING; + String addendum = ICommonConstants.EMPTY_STRING; + try { - UsageMonitoringLogger.getInstance().log(eventName, eventContext, EventStatus.NONE, addendum); - + UsageMonitoringLogger.getInstance().log(eventName, eventContext, EventStatus.NONE, addendum); + // forks is set to false to make the runnable run in the UI thread. If set to true it will lead // to a deadlock // see Eclipse Bug 105491 : https://bugs.eclipse.org/bugs/show_bug.cgi?id=105491 new ProgressMonitorDialog(shell).run(false, true, runnableWithProgress); - + UsageMonitoringLogger.getInstance().log(eventName, eventContext, EventStatus.OK, addendum); } catch (Exception exception) { EMFEditUIPlugin.INSTANCE.log(exception); @@ -248,4 +210,125 @@ protected void handleDiagnostic(Diagnostic diagnostic) { } } + // Slightly modified from superclass to support MultiobjectDiagnosticians + // and error handling if invalid diagnosticians are specified + protected Diagnostic validate(IProgressMonitor progressMonitor) { + int selectionSize = selectedObjects.size(); + + progressMonitor.beginTask("", IProgressMonitor.UNKNOWN); //$NON-NLS-1$ + + AdapterFactory adapterFactory = + domain instanceof AdapterFactoryEditingDomain ? ((AdapterFactoryEditingDomain)domain).getAdapterFactory() : null; + Diagnostician diagnostician = createDiagnostician(adapterFactory, progressMonitor); + if (diagnostician == null) { + return new BasicDiagnostic(Diagnostic.ERROR, CapellaActionsActivator.PLUGIN_ID, 0, + "Could not create diagnostician", null); //$NON-NLS-1$ + } + + BasicDiagnostic diagnostic; + if (selectionSize == 1){ + diagnostic = diagnostician.createDefaultDiagnostic(selectedObjects.get(0)); + } else { + diagnostic = + new BasicDiagnostic + (EObjectValidator.DIAGNOSTIC_SOURCE, + 0, + EMFEditUIPlugin.INSTANCE.getString("_UI_DiagnosisOfNObjects_message", new String[] { Integer.toString(selectionSize) }), //$NON-NLS-1$ + selectedObjects.toArray()); + } + + Map context = diagnostician.createDefaultContext(); + context.putAll(getContextEntries()); + + if (diagnostician instanceof MultiobjectDiagnostician) { + ((MultiobjectDiagnostician) diagnostician).validate(selectedObjects, diagnostic, context); + } else { + for (EObject eObject : selectedObjects) { + progressMonitor.setTaskName(EMFEditUIPlugin.INSTANCE.getString("_UI_Validating_message", new Object [] { diagnostician.getObjectLabel(eObject) })); //$NON-NLS-1$ + diagnostician.validate(eObject, diagnostic, context); + context.remove(EObjectValidator.ROOT_OBJECT); + } + } + return diagnostic; + } + + protected Map getContextEntries(){ + return Collections.emptyMap(); + } + + + /** + * Subclasses may further customize created validation markers + * @param marker + */ + protected void modifyMarker(IMarker marker) { + // EPF uses this to add the epf file as an additional attribute + } + + protected class ResourcesUtil extends EclipseResourcesUtil { + /** + * {@inheritDoc} + */ + @Override + protected String getMarkerID() { + return ICapellaValidationConstants.CAPELLA_MARKER_ID; + } + + /** + * @see org.eclipse.emf.edit.ui.action.ValidateAction.EclipseResourcesUtil#createMarkers(org.eclipse.emf.ecore.resource.Resource, + * org.eclipse.emf.common.util.Diagnostic) + */ + @Override + public void createMarkers(Resource resource, Diagnostic diagnostic) { + // Don't use 'traditional' resource markers. TODO investigate to go back to the traditional ones. + // Original reasons to switch: CDO and too many workspace notifications (especially in transitions) + + // can't use resource, see handleDiagnostics below + LightMarkerRegistry.getInstance().createMarker(getFile(_currentResource), diagnostic, getMarkerID(), m -> modifyMarker(m)); + } + + /** + * @see org.eclipse.emf.edit.ui.util.EditUIMarkerHelper#deleteMarkers(java.lang.Object, boolean, int) + */ + @Override + public void deleteMarkers(Object object, boolean includeSubtypes, int depth) { + boolean cleanup = AbstractPreferencesInitializer.getBoolean(ICapellaValidationPreferences.P_CLEAN_PREVIOUS_VALIDATION_RESULTS, false); + if (cleanup) { + List markers = new ArrayList(LightMarkerRegistry.getInstance().getMarkers()); + for (IMarker marker : markers) { + try { + if (marker.getType().equals(getMarkerID())) { + marker.delete(); + } + } catch (CoreException e) { + CapellaActionsActivator.getDefault().log(IStatus.ERROR, e.getMessage(), e); + } + } + } + } + + /** + * Overridden to redirect markers to target to the .aird file so that + * relevant markers can be removed when the corresponding session is closed + * (see {@link org.polarsys.capella.core.ui.reportlog.InformationViewSessionListener}) + */ + @Override + protected IFile getFile(Object datum) { + Object derivedDatum = datum; + if (datum instanceof EObject) { + Session session = SessionManager.INSTANCE.getSession((EObject) datum); + if (session != null) { + derivedDatum = session.getSessionResource(); + } + } else if (datum instanceof Resource) { + Session session = SessionManager.INSTANCE.getSession((Resource) datum); + if (session != null) { + derivedDatum = session.getSessionResource(); + } + } + + return super.getFile(derivedDatum); + } + } + } diff --git a/core/plugins/org.polarsys.capella.core.platform.sirius.ui.actions/src/org/polarsys/capella/core/platform/sirius/ui/actions/CheckAction.java b/core/plugins/org.polarsys.capella.core.platform.sirius.ui.actions/src/org/polarsys/capella/core/platform/sirius/ui/actions/CheckAction.java deleted file mode 100644 index c1c18f0105..0000000000 --- a/core/plugins/org.polarsys.capella.core.platform.sirius.ui.actions/src/org/polarsys/capella/core/platform/sirius/ui/actions/CheckAction.java +++ /dev/null @@ -1,39 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2006, 2020 THALES GLOBAL SERVICES. - * - * This program and the accompanying materials are made available under the - * terms of the Eclipse Public License 2.0 which is available at - * http://www.eclipse.org/legal/epl-2.0 - * - * SPDX-License-Identifier: EPL-2.0 - * - * Contributors: - * Thales - initial API and implementation - *******************************************************************************/ - -package org.polarsys.capella.core.platform.sirius.ui.actions; - -import org.eclipse.jface.action.IAction; -import org.eclipse.jface.viewers.StructuredSelection; -import org.eclipse.ui.IActionDelegate; - -import org.polarsys.capella.common.ui.actions.AbstractTigAction; - -/** - */ - -// XXX : to be deleted ... remplaced by a new validation menu -public class CheckAction extends AbstractTigAction implements IActionDelegate { - /** - * @see org.eclipse.ui.IActionDelegate#run(org.eclipse.jface.action.IAction) - */ - public void run(IAction arg0) { - // Create the validate action. - CapellaValidateAction capellaValidateAction = new CapellaValidateAction(); - // Update its selection. - capellaValidateAction.updateSelection(new StructuredSelection(getSelectedElement())); - // Then run it. - // The action handles by itself the call to the execution manager. - capellaValidateAction.run(); - } -} diff --git a/core/plugins/org.polarsys.capella.core.platform.sirius.ui.actions/src/org/polarsys/capella/core/platform/sirius/ui/preferences/CapellaValidationPreferencesInitializer.java b/core/plugins/org.polarsys.capella.core.platform.sirius.ui.actions/src/org/polarsys/capella/core/platform/sirius/ui/preferences/CapellaValidationPreferencesInitializer.java index 6963fb6099..2833291a2c 100644 --- a/core/plugins/org.polarsys.capella.core.platform.sirius.ui.actions/src/org/polarsys/capella/core/platform/sirius/ui/preferences/CapellaValidationPreferencesInitializer.java +++ b/core/plugins/org.polarsys.capella.core.platform.sirius.ui.actions/src/org/polarsys/capella/core/platform/sirius/ui/preferences/CapellaValidationPreferencesInitializer.java @@ -12,8 +12,7 @@ *******************************************************************************/ package org.polarsys.capella.core.platform.sirius.ui.preferences; -import org.eclipse.core.resources.ProjectScope; - +import org.eclipse.core.runtime.preferences.InstanceScope; import org.polarsys.capella.core.commands.preferences.service.AbstractPreferencesInitializer; import org.polarsys.capella.core.platform.sirius.ui.actions.CapellaActionsActivator; @@ -28,7 +27,8 @@ public CapellaValidationPreferencesInitializer() { @Override public void initializeDefaultPreferences() { - putBoolean(ICapellaValidationPreferences.P_CLEAN_PREVIOUS_VALIDATION_RESULTS, true, ProjectScope.class); + putBoolean(ICapellaValidationPreferences.P_CLEAN_PREVIOUS_VALIDATION_RESULTS, true, InstanceScope.class); + putString(ICapellaValidationPreferences.P_DIAGNOSTICIAN_PROVIDER, "org.polarsys.capella.core.validation.legacy", InstanceScope.class); //$NON-NLS-1$ } } diff --git a/core/plugins/org.polarsys.capella.core.platform.sirius.ui.actions/src/org/polarsys/capella/core/platform/sirius/ui/preferences/CapellaValidationPreferencesPage.java b/core/plugins/org.polarsys.capella.core.platform.sirius.ui.actions/src/org/polarsys/capella/core/platform/sirius/ui/preferences/CapellaValidationPreferencesPage.java index ba152c9431..2df94495dd 100644 --- a/core/plugins/org.polarsys.capella.core.platform.sirius.ui.actions/src/org/polarsys/capella/core/platform/sirius/ui/preferences/CapellaValidationPreferencesPage.java +++ b/core/plugins/org.polarsys.capella.core.platform.sirius.ui.actions/src/org/polarsys/capella/core/platform/sirius/ui/preferences/CapellaValidationPreferencesPage.java @@ -12,9 +12,14 @@ *******************************************************************************/ package org.polarsys.capella.core.platform.sirius.ui.preferences; -import org.eclipse.jface.preference.BooleanFieldEditor; +import java.util.Collection; +import org.eclipse.jface.preference.BooleanFieldEditor; +import org.eclipse.jface.preference.RadioGroupFieldEditor; +import org.eclipse.swt.widgets.Group; import org.polarsys.capella.core.commands.preferences.service.AbstractDefaultPreferencePage; +import org.polarsys.capella.core.model.handler.validation.DiagnosticianProviderRegistry; +import org.polarsys.capella.core.model.handler.validation.DiagnosticianProviderRegistry.Descriptor; import org.polarsys.capella.core.platform.sirius.ui.actions.CapellaActionsActivator; /** @@ -43,8 +48,22 @@ public CapellaValidationPreferencesPage() { */ @Override public void createFieldEditors() { + Group generalGroup = createGroup(Messages.CapellaValidationPreferencesPage_General_Group_Label, Messages.CapellaValidationPreferencesPage_General_Group_Tooltip, getFieldEditorParent()); addField(new BooleanFieldEditor(ICapellaValidationPreferences.P_CLEAN_PREVIOUS_VALIDATION_RESULTS, - Messages.ModelValidationPreferencePage_DeletePreviousResults_Title, getFieldEditorParent())); + Messages.ModelValidationPreferencePage_DeletePreviousResults_Title, generalGroup)); + + Collection descriptors = DiagnosticianProviderRegistry.INSTANCE.getDescriptors(); + String[][] labelsAndValues = new String[descriptors.size()][2]; + + int i = 0; + for (Descriptor d : descriptors) { + labelsAndValues[i][0] = d.getName(); + labelsAndValues[i][1] = d.getID(); + i++; + } + + addField(new RadioGroupFieldEditor(ICapellaValidationPreferences.P_DIAGNOSTICIAN_PROVIDER, Messages.CapellaValidationPreferencesPage_ValidationScope_Group_Label , 1, labelsAndValues, getFieldEditorParent(), true)); + } /** diff --git a/core/plugins/org.polarsys.capella.core.platform.sirius.ui.actions/src/org/polarsys/capella/core/platform/sirius/ui/preferences/ICapellaValidationPreferences.java b/core/plugins/org.polarsys.capella.core.platform.sirius.ui.actions/src/org/polarsys/capella/core/platform/sirius/ui/preferences/ICapellaValidationPreferences.java index 2fdaa3fc9b..13699238b5 100644 --- a/core/plugins/org.polarsys.capella.core.platform.sirius.ui.actions/src/org/polarsys/capella/core/platform/sirius/ui/preferences/ICapellaValidationPreferences.java +++ b/core/plugins/org.polarsys.capella.core.platform.sirius.ui.actions/src/org/polarsys/capella/core/platform/sirius/ui/preferences/ICapellaValidationPreferences.java @@ -16,6 +16,6 @@ * Constant definitions for valication preferences */ public class ICapellaValidationPreferences { - public static final String P_CLEAN_PREVIOUS_VALIDATION_RESULTS = "cleanPreviousValidationResults"; //$NON-NLS-1$ + public static final String P_DIAGNOSTICIAN_PROVIDER = "diagnosticianProvider"; //$NON-NLS-1$ } diff --git a/core/plugins/org.polarsys.capella.core.platform.sirius.ui.actions/src/org/polarsys/capella/core/platform/sirius/ui/preferences/Messages.java b/core/plugins/org.polarsys.capella.core.platform.sirius.ui.actions/src/org/polarsys/capella/core/platform/sirius/ui/preferences/Messages.java index a78a93b3a1..82ef9e2354 100644 --- a/core/plugins/org.polarsys.capella.core.platform.sirius.ui.actions/src/org/polarsys/capella/core/platform/sirius/ui/preferences/Messages.java +++ b/core/plugins/org.polarsys.capella.core.platform.sirius.ui.actions/src/org/polarsys/capella/core/platform/sirius/ui/preferences/Messages.java @@ -28,12 +28,15 @@ public class Messages extends NLS { public static String CapellaPreferencePage_Description; public static String CapellaPreferencePage_DetectionVersion_Title; public static String CapellaPreferencePage_Title; + public static String CapellaValidationPreferencesPage_General_Group_Label; + public static String CapellaValidationPreferencesPage_General_Group_Tooltip; + public static String CapellaValidationPreferencesPage_ValidationScope_Group_Tooltip; + public static String CapellaValidationPreferencesPage_ValidationScope_Group_Label; public static String WizardPreferencePage_Description; public static String WizardPreferencePage_Title; public static String ModelValidationPreferencePage_Description; public static String ModelValidationPreferencePage_DeletePreviousResults_Title; public static String DeletePreferencePage_ProtectedElements_Title; - public static String DeletePreferencePage_MultipartGroup_Title; public static String DeletePreferencePage_MultipartGroup_Description; diff --git a/core/plugins/org.polarsys.capella.core.platform.sirius.ui.actions/src/org/polarsys/capella/core/platform/sirius/ui/preferences/messages.properties b/core/plugins/org.polarsys.capella.core.platform.sirius.ui.actions/src/org/polarsys/capella/core/platform/sirius/ui/preferences/messages.properties index 7418705379..dded6c79bb 100644 --- a/core/plugins/org.polarsys.capella.core.platform.sirius.ui.actions/src/org/polarsys/capella/core/platform/sirius/ui/preferences/messages.properties +++ b/core/plugins/org.polarsys.capella.core.platform.sirius.ui.actions/src/org/polarsys/capella/core/platform/sirius/ui/preferences/messages.properties @@ -22,6 +22,10 @@ CapellaPreferencePage_AirdFragmentFileExtension_Title=AIRD Fragment File Extensi CapellaPreferencePage_Description=Capella CapellaPreferencePage_DetectionVersion_Title=Check model version at load time CapellaPreferencePage_Title=Capella preferences +CapellaValidationPreferencesPage_General_Group_Label=General +CapellaValidationPreferencesPage_General_Group_Tooltip=General Validation Preferences +CapellaValidationPreferencesPage_ValidationScope_Group_Tooltip=Validate additional elements based on selection +CapellaValidationPreferencesPage_ValidationScope_Group_Label=Validation Scope WizardPreferencePage_Description=Preferences related to Capella Editors WizardPreferencePage_Title=Editors ModelValidationPreferencePage_Description=Preferences related to Capella Model Validation diff --git a/core/plugins/org.polarsys.capella.core.re/plugin.xml b/core/plugins/org.polarsys.capella.core.re/plugin.xml index e5a67e3607..e429ac69b1 100644 --- a/core/plugins/org.polarsys.capella.core.re/plugin.xml +++ b/core/plugins/org.polarsys.capella.core.re/plugin.xml @@ -477,11 +477,11 @@ mapping="org.polarsys.capella.common.re" purpose="org.polarsys.capella.common.re.scopeElements"> retrieveRelatedElements(EObject element_p, IContext context_p) { - if (element_p instanceof AbstractDeploymentLink) { - return Collections.singleton(((AbstractDeploymentLink) element_p).getDeployedElement()); - } - return null; - } - - /** - * {@inheritDoc} - */ - @Override - public Collection retrieveSharedElements(IContext context_p) { - return null; - } -} diff --git a/core/plugins/org.polarsys.capella.core.re/src/org/polarsys/capella/core/re/handlers/scope/PartTypeRetriever.java b/core/plugins/org.polarsys.capella.core.re/src/org/polarsys/capella/core/re/handlers/scope/PartTypeRetriever.java deleted file mode 100644 index fde94b8205..0000000000 --- a/core/plugins/org.polarsys.capella.core.re/src/org/polarsys/capella/core/re/handlers/scope/PartTypeRetriever.java +++ /dev/null @@ -1,60 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2006, 2020 THALES GLOBAL SERVICES. - * - * This program and the accompanying materials are made available under the - * terms of the Eclipse Public License 2.0 which is available at - * http://www.eclipse.org/legal/epl-2.0 - * - * SPDX-License-Identifier: EPL-2.0 - * - * Contributors: - * Thales - initial API and implementation - *******************************************************************************/ -package org.polarsys.capella.core.re.handlers.scope; - -import java.util.Collection; -import java.util.Collections; - -import org.eclipse.core.runtime.IStatus; -import org.eclipse.core.runtime.Status; -import org.eclipse.emf.ecore.EObject; - -import org.polarsys.capella.core.data.cs.Part; -import org.polarsys.capella.core.transition.common.handlers.scope.IScopeRetriever; -import org.polarsys.kitalpha.transposer.rules.handler.rules.api.IContext; - -/** - * - */ -public class PartTypeRetriever implements IScopeRetriever { - - @Override - public IStatus init(IContext context_p) { - return Status.OK_STATUS; - } - - @Override - public IStatus dispose(IContext context_p) { - return Status.OK_STATUS; - } - - /** - * {@inheritDoc} - */ - @Override - public Collection retrieveRelatedElements(EObject element_p, IContext context_p) { - if (element_p instanceof Part) { - return Collections.singleton(((Part) element_p).getAbstractType()); - } - return null; - } - - /** - * {@inheritDoc} - */ - @Override - public Collection retrieveSharedElements(IContext context_p) { - return null; - } - -} diff --git a/core/plugins/org.polarsys.capella.core.transition.system/META-INF/MANIFEST.MF b/core/plugins/org.polarsys.capella.core.transition.system/META-INF/MANIFEST.MF index a8de41782b..b76cadac86 100644 --- a/core/plugins/org.polarsys.capella.core.transition.system/META-INF/MANIFEST.MF +++ b/core/plugins/org.polarsys.capella.core.transition.system/META-INF/MANIFEST.MF @@ -27,6 +27,7 @@ Export-Package: org.polarsys.capella.core.transition.system, org.polarsys.capella.core.transition.system.handlers.log, org.polarsys.capella.core.transition.system.handlers.merge, org.polarsys.capella.core.transition.system.handlers.optimize, + org.polarsys.capella.core.transition.system.handlers.scope, org.polarsys.capella.core.transition.system.handlers.traceability, org.polarsys.capella.core.transition.system.handlers.transformation, org.polarsys.capella.core.transition.system.helpers, diff --git a/core/plugins/org.polarsys.capella.core.transition.system/src/org/polarsys/capella/core/transition/system/handlers/scope/DeployedElementRetriever.java b/core/plugins/org.polarsys.capella.core.transition.system/src/org/polarsys/capella/core/transition/system/handlers/scope/DeployedElementRetriever.java new file mode 100644 index 0000000000..a62a6f8a3b --- /dev/null +++ b/core/plugins/org.polarsys.capella.core.transition.system/src/org/polarsys/capella/core/transition/system/handlers/scope/DeployedElementRetriever.java @@ -0,0 +1,22 @@ +/******************************************************************************* + * Copyright (c) 2020 THALES GLOBAL SERVICES. + * + * This program and the accompanying materials are made available under the + * terms of the Eclipse Public License 2.0 which is available at + * http://www.eclipse.org/legal/epl-2.0 + * + * SPDX-License-Identifier: EPL-2.0 + * + * Contributors: + * Thales - initial API and implementation + *******************************************************************************/ +package org.polarsys.capella.core.transition.system.handlers.scope; + +import org.polarsys.capella.core.data.cs.CsPackage; +import org.polarsys.capella.core.transition.common.handlers.scope.EReferenceScopeRetriever; + +public class DeployedElementRetriever extends EReferenceScopeRetriever { + public DeployedElementRetriever() { + super(CsPackage.Literals.ABSTRACT_DEPLOYMENT_LINK__DEPLOYED_ELEMENT); + } +} diff --git a/core/plugins/org.polarsys.capella.core.transition.system/src/org/polarsys/capella/core/transition/system/handlers/scope/PartTypeRetriever.java b/core/plugins/org.polarsys.capella.core.transition.system/src/org/polarsys/capella/core/transition/system/handlers/scope/PartTypeRetriever.java new file mode 100644 index 0000000000..477ae358c9 --- /dev/null +++ b/core/plugins/org.polarsys.capella.core.transition.system/src/org/polarsys/capella/core/transition/system/handlers/scope/PartTypeRetriever.java @@ -0,0 +1,37 @@ +/******************************************************************************* + * Copyright (c) 2020 THALES GLOBAL SERVICES. + * + * This program and the accompanying materials are made available under the + * terms of the Eclipse Public License 2.0 which is available at + * http://www.eclipse.org/legal/epl-2.0 + * + * SPDX-License-Identifier: EPL-2.0 + * + * Contributors: + * Thales - initial API and implementation + *******************************************************************************/ +package org.polarsys.capella.core.transition.system.handlers.scope; + +import java.util.Collection; +import java.util.Collections; + +import org.eclipse.emf.ecore.EObject; +import org.polarsys.capella.core.data.cs.Part; +import org.polarsys.capella.core.transition.common.handlers.scope.TypedScopeRetriever; +import org.polarsys.kitalpha.transposer.rules.handler.rules.api.IContext; + +public class PartTypeRetriever extends TypedScopeRetriever { + + public PartTypeRetriever() { + super(Part.class); + } + + @Override + public Collection doRetrieveRelatedElements(Part part, IContext context_p) { + if (part.getAbstractType() != null) { + return Collections.singleton(part.getAbstractType()); + } + return Collections.emptyList(); + } + +} diff --git a/core/plugins/org.polarsys.capella.core.validation.commandline/META-INF/MANIFEST.MF b/core/plugins/org.polarsys.capella.core.validation.commandline/META-INF/MANIFEST.MF index 8efa3ff752..06b8b0bf27 100644 --- a/core/plugins/org.polarsys.capella.core.validation.commandline/META-INF/MANIFEST.MF +++ b/core/plugins/org.polarsys.capella.core.validation.commandline/META-INF/MANIFEST.MF @@ -5,12 +5,10 @@ Bundle-SymbolicName: org.polarsys.capella.core.validation.commandline;singleton: Bundle-Version: 5.0.0.qualifier Bundle-Activator: org.polarsys.capella.core.validation.commandline.Activator Bundle-Vendor: %providerName -Require-Bundle: org.eclipse.core.runtime, - org.polarsys.capella.core.platform.sirius.ui.actions, - org.polarsys.capella.core.model.helpers, +Require-Bundle: org.polarsys.capella.core.platform.sirius.ui.actions, org.polarsys.capella.core.platform.sirius.ui.project, - org.polarsys.capella.core.model.handler, - org.polarsys.capella.core.commandline.core.ui + org.polarsys.capella.core.commandline.core.ui, + org.polarsys.capella.core.validation Bundle-RequiredExecutionEnvironment: JavaSE-1.8 Bundle-ActivationPolicy: lazy Export-Package: org.polarsys.capella.core.validation.commandline diff --git a/core/plugins/org.polarsys.capella.core.validation.commandline/src/org/polarsys/capella/core/validation/commandline/CapellaValidateComlineAction.java b/core/plugins/org.polarsys.capella.core.validation.commandline/src/org/polarsys/capella/core/validation/commandline/CapellaValidateComlineAction.java index 3ffba1331b..a804849fd4 100644 --- a/core/plugins/org.polarsys.capella.core.validation.commandline/src/org/polarsys/capella/core/validation/commandline/CapellaValidateComlineAction.java +++ b/core/plugins/org.polarsys.capella.core.validation.commandline/src/org/polarsys/capella/core/validation/commandline/CapellaValidateComlineAction.java @@ -29,11 +29,24 @@ public class CapellaValidateComlineAction extends CapellaValidateAction { private Resource resourceToValidate; private Diagnostic diagnostic; + private String providerId; public void setSelectedObjects(List selectedObjects) { this.selectedObjects = selectedObjects; } + public void setDiagnosticianProviderId(String id) { + this.providerId = id; + } + + @Override + protected String getDiagnosticianProviderId() { + if (providerId != null) { + return providerId; + } + return super.getDiagnosticianProviderId(); + } + /** * {@inheritDoc} */ @@ -45,7 +58,7 @@ public void run() { handleDiagnostic(diagnostic); } } - + private boolean isSetEditingDomain(){ if(domain == null && !selectedObjects.isEmpty()){ ExecutionManager executionManager = TransactionHelper.getExecutionManager(selectedObjects); diff --git a/core/plugins/org.polarsys.capella.core.validation.commandline/src/org/polarsys/capella/core/validation/commandline/ValidationArgumentHelper.java b/core/plugins/org.polarsys.capella.core.validation.commandline/src/org/polarsys/capella/core/validation/commandline/ValidationArgumentHelper.java index b490ae8380..ebf8638806 100644 --- a/core/plugins/org.polarsys.capella.core.validation.commandline/src/org/polarsys/capella/core/validation/commandline/ValidationArgumentHelper.java +++ b/core/plugins/org.polarsys.capella.core.validation.commandline/src/org/polarsys/capella/core/validation/commandline/ValidationArgumentHelper.java @@ -19,6 +19,7 @@ public class ValidationArgumentHelper extends CommandLineArgumentHelper { private String validationContext; private String validationRuleSet; + private String providerId; /** * {@inheritDoc} @@ -33,9 +34,10 @@ public void parseArgs(String[] args) { if (ValidationCommandLineConstants.VALIDATION_CONTEXT.equalsIgnoreCase(arg)) { validationContext = args[++i]; - } else if (ValidationCommandLineConstants.VALIDATION_RULE_SET.equalsIgnoreCase(arg)) { validationRuleSet = args[++i]; + } else if (ValidationCommandLineConstants.DIAGNOSTICIAN_PROVIDER_ID.equalsIgnoreCase(arg)) { + providerId = args[++i]; } } } @@ -53,4 +55,12 @@ public String getValidationContext() { public String getValidationRuleSet() { return validationRuleSet; } + + /** + * @return The diagnostician provider ID + */ + public String getDiagnosticianProviderId() { + return providerId; + } + } diff --git a/core/plugins/org.polarsys.capella.core.validation.commandline/src/org/polarsys/capella/core/validation/commandline/ValidationCommandLine.java b/core/plugins/org.polarsys.capella.core.validation.commandline/src/org/polarsys/capella/core/validation/commandline/ValidationCommandLine.java index 0eb3d3e114..bb18dcc211 100644 --- a/core/plugins/org.polarsys.capella.core.validation.commandline/src/org/polarsys/capella/core/validation/commandline/ValidationCommandLine.java +++ b/core/plugins/org.polarsys.capella.core.validation.commandline/src/org/polarsys/capella/core/validation/commandline/ValidationCommandLine.java @@ -110,7 +110,7 @@ private IStatus execute(final URI airdURI) { if (!isEmtyOrNull(validationRuleSetFile)) {// validate selected EObjects List ruleSet = readRules(validationRuleSetFile); - ensureEMFValidationActivation(); + ModelValidationService.getInstance().loadXmlConstraintDeclarations(); for (String ruleId : ruleSet) { EMFModelValidationPreferences.setConstraintDisabled(ruleId, true); } @@ -127,6 +127,9 @@ private IStatus execute(final URI airdURI) { capellaValidateCLineAction.setSelectedObjects(semanticRootResource.getContents()); } + capellaValidateCLineAction + .setDiagnosticianProviderId(((ValidationArgumentHelper) argHelper).getDiagnosticianProviderId()); + // Run the validation capellaValidateCLineAction.run(); @@ -144,16 +147,6 @@ private IStatus execute(final URI airdURI) { return status; } - /** - * Ensure that all constraints have been loaded. - */ - public static void ensureEMFValidationActivation() { - - ModelValidationService.getInstance().loadXmlConstraintDeclarations(); - - return; - } - /** * Returns list of disabled rule IDs * diff --git a/core/plugins/org.polarsys.capella.core.validation.commandline/src/org/polarsys/capella/core/validation/commandline/ValidationCommandLineConstants.java b/core/plugins/org.polarsys.capella.core.validation.commandline/src/org/polarsys/capella/core/validation/commandline/ValidationCommandLineConstants.java index 83f1da092a..6452acaa78 100644 --- a/core/plugins/org.polarsys.capella.core.validation.commandline/src/org/polarsys/capella/core/validation/commandline/ValidationCommandLineConstants.java +++ b/core/plugins/org.polarsys.capella.core.validation.commandline/src/org/polarsys/capella/core/validation/commandline/ValidationCommandLineConstants.java @@ -15,8 +15,7 @@ /** */ public class ValidationCommandLineConstants { - public static final String VALIDATION_CONTEXT = "-validationcontext";//$NON-NLS-1$ public static final String VALIDATION_RULE_SET = "-validationruleset";//$NON-NLS-1$ - + public static final String DIAGNOSTICIAN_PROVIDER_ID = "-diagnosticianProviderId"; //$NON-NLS-1$ } diff --git a/core/plugins/org.polarsys.capella.core.validation.ui/META-INF/MANIFEST.MF b/core/plugins/org.polarsys.capella.core.validation.ui/META-INF/MANIFEST.MF index f3f9ba8dac..9894b33d62 100644 --- a/core/plugins/org.polarsys.capella.core.validation.ui/META-INF/MANIFEST.MF +++ b/core/plugins/org.polarsys.capella.core.validation.ui/META-INF/MANIFEST.MF @@ -5,17 +5,13 @@ Bundle-SymbolicName: org.polarsys.capella.core.validation.ui;singleton:=true Bundle-Version: 5.0.0.qualifier Bundle-Activator: org.polarsys.capella.core.validation.ui.CapellaValidationUIActivator Bundle-Vendor: %providerName -Require-Bundle: org.eclipse.core.runtime, - org.polarsys.capella.core.validation, - org.polarsys.capella.common.ui.services, - org.polarsys.capella.core.ui.reportlog, - org.polarsys.capella.core.preferences, +Require-Bundle: org.polarsys.capella.core.validation, org.polarsys.capella.core.platform.sirius.ui.actions, - org.polarsys.capella.core.menu.dynamic + org.polarsys.capella.core.menu.dynamic, + org.polarsys.capella.common.tools.report.appenders.usage Bundle-RequiredExecutionEnvironment: JavaSE-1.8 Bundle-Localization: plugin Bundle-ActivationPolicy: lazy -Import-Package: org.polarsys.capella.common.tools.report.appenders.reportlogview Export-Package: org.polarsys.capella.core.validation.helpers, org.polarsys.capella.core.validation.service, org.polarsys.capella.core.validation.ui, diff --git a/core/plugins/org.polarsys.capella.core.validation.ui/src/org/polarsys/capella/core/validation/service/EPFValidatorAdapter.java b/core/plugins/org.polarsys.capella.core.validation.ui/src/org/polarsys/capella/core/validation/service/EPFValidatorAdapter.java deleted file mode 100644 index 414f1af08d..0000000000 --- a/core/plugins/org.polarsys.capella.core.validation.ui/src/org/polarsys/capella/core/validation/service/EPFValidatorAdapter.java +++ /dev/null @@ -1,60 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2006, 2020 THALES GLOBAL SERVICES. - * - * This program and the accompanying materials are made available under the - * terms of the Eclipse Public License 2.0 which is available at - * http://www.eclipse.org/legal/epl-2.0 - * - * SPDX-License-Identifier: EPL-2.0 - * - * Contributors: - * Thales - initial API and implementation - *******************************************************************************/ -package org.polarsys.capella.core.validation.service; - -import org.eclipse.core.runtime.IStatus; -import org.eclipse.emf.common.util.DiagnosticChain; -import org.eclipse.emf.validation.model.IConstraintStatus; -import org.eclipse.emf.validation.service.IBatchValidator; - -import org.polarsys.capella.common.helpers.validation.ConstraintStatusDiagnostic; -import org.polarsys.capella.core.validation.CapellaValidatorAdapter; - -/** - */ -public class EPFValidatorAdapter extends CapellaValidatorAdapter { - - /** - * - */ - public EPFValidatorAdapter() { - } - - /** - * @see org.polarsys.capella.core.validation.EValidatorAdapter#appendDiagnostics(org.eclipse.core.runtime.IStatus, - * org.eclipse.emf.common.util.DiagnosticChain) - */ - @Override - protected void appendDiagnostics(IStatus status, DiagnosticChain diagnostics) { - // Deal recursively with multi status. - if (status.isMultiStatus()) { - IStatus[] children = status.getChildren(); - for (IStatus element : children) { - appendDiagnostics(element, diagnostics); - } - } else if (status instanceof IConstraintStatus) { - diagnostics.add(new ConstraintStatusDiagnostic((IConstraintStatus) status)); - } - - } - - /** - * @see org.polarsys.capella.core.validation.EValidatorAdapter#getValidator() - */ - @Override - public IBatchValidator getValidator() { - - return super.getValidator(); - } - -} diff --git a/core/plugins/org.polarsys.capella.core.validation.ui/src/org/polarsys/capella/core/validation/ui/CapellaValidationUIActivator.java b/core/plugins/org.polarsys.capella.core.validation.ui/src/org/polarsys/capella/core/validation/ui/CapellaValidationUIActivator.java index 3b49089930..9fbc4694df 100644 --- a/core/plugins/org.polarsys.capella.core.validation.ui/src/org/polarsys/capella/core/validation/ui/CapellaValidationUIActivator.java +++ b/core/plugins/org.polarsys.capella.core.validation.ui/src/org/polarsys/capella/core/validation/ui/CapellaValidationUIActivator.java @@ -13,9 +13,8 @@ package org.polarsys.capella.core.validation.ui; import org.osgi.framework.BundleContext; - import org.polarsys.capella.common.ui.services.AbstractUIActivator; -import org.polarsys.capella.core.validation.service.EPFValidatorAdapter; + /** * The activator class controls the plug-in life cycle @@ -29,11 +28,7 @@ public class CapellaValidationUIActivator extends AbstractUIActivator { // The shared instance private static CapellaValidationUIActivator plugin; - private EPFValidatorAdapter efpValidatorAdapter; - public EPFValidatorAdapter getEfpValidatorAdapter() { - return efpValidatorAdapter; - } /** * The constructor @@ -48,9 +43,6 @@ public CapellaValidationUIActivator() { @Override public void start(BundleContext context) throws Exception { super.start(context); - efpValidatorAdapter = new EPFValidatorAdapter(); - // Add a constraints filter, to disable all constraints that are not capella ones, e.g GMF ones. - // efpValidatorAdapter.getValidator().addConstraintFilter(new EPFConstraintFilter()); plugin = this; } diff --git a/core/plugins/org.polarsys.capella.core.validation.ui/src/org/polarsys/capella/core/validation/ui/DynamicActionProvider.java b/core/plugins/org.polarsys.capella.core.validation.ui/src/org/polarsys/capella/core/validation/ui/DynamicActionProvider.java index b19541a33e..4e0ec13e83 100644 --- a/core/plugins/org.polarsys.capella.core.validation.ui/src/org/polarsys/capella/core/validation/ui/DynamicActionProvider.java +++ b/core/plugins/org.polarsys.capella.core.validation.ui/src/org/polarsys/capella/core/validation/ui/DynamicActionProvider.java @@ -42,29 +42,11 @@ */ public class DynamicActionProvider extends AbstractActionProvider { - /** - * - */ private ValidateAction defaultValidationAction; - - /* - * - */ private List userValidationActions; - - /* - * - */ private ImageDescriptor imageDescriptor; - - /* - * - */ private ISelectionProvider selectionProvider; - /** - * - */ public DynamicActionProvider() { // Initialize the action provider to force it to load menu contributors. ActionContributionProvider.getInstance(); @@ -82,7 +64,7 @@ protected void initActions(Shell shell, IWorkbenchPage page, ISelectionProvider userValidationActions = new ArrayList(); defaultValidationAction = createDefaultValidation(); // createValidationAction(false, null, selectionProvider, imageDescriptor); for (IFile file : PreferencesHelper.retrieveUserDefinedPreferenceFiles(selectionProvider, EPFValidationAction.EPF_EXTNAME)) { - userValidationActions.add(createValidationAction(false, file, selectionProvider, imageDescriptor)); + userValidationActions.add(createValidationAction(file, selectionProvider, imageDescriptor)); } } @@ -159,8 +141,8 @@ public void fillActionBars(IActionBars actionBars) { * @param imageDescriptor * @return */ - protected ValidateAction createValidationAction(boolean isRootAction, IFile file, ISelectionProvider selectionProvider, ImageDescriptor imageDescriptor) { - ValidateAction validationAction = new EPFValidationAction(isRootAction, file); + protected ValidateAction createValidationAction(IFile file, ISelectionProvider selectionProvider, ImageDescriptor imageDescriptor) { + ValidateAction validationAction = new EPFValidationAction(file); validationAction.setImageDescriptor(imageDescriptor); diff --git a/core/plugins/org.polarsys.capella.core.validation.ui/src/org/polarsys/capella/core/validation/ui/actions/EPFValidationAction.java b/core/plugins/org.polarsys.capella.core.validation.ui/src/org/polarsys/capella/core/validation/ui/actions/EPFValidationAction.java index b7961a8ddb..92a6bda8a9 100644 --- a/core/plugins/org.polarsys.capella.core.validation.ui/src/org/polarsys/capella/core/validation/ui/actions/EPFValidationAction.java +++ b/core/plugins/org.polarsys.capella.core.validation.ui/src/org/polarsys/capella/core/validation/ui/actions/EPFValidationAction.java @@ -12,11 +12,8 @@ *******************************************************************************/ package org.polarsys.capella.core.validation.ui.actions; -import java.io.File; -import java.io.FileInputStream; import java.io.IOException; -import java.lang.reflect.InvocationTargetException; -import java.util.ArrayList; +import java.io.InputStream; import java.util.HashMap; import java.util.List; import java.util.Map; @@ -24,114 +21,50 @@ import org.eclipse.core.resources.IFile; import org.eclipse.core.resources.IMarker; -import org.eclipse.core.resources.IWorkspace; -import org.eclipse.core.resources.ResourcesPlugin; import org.eclipse.core.runtime.CoreException; -import org.eclipse.core.runtime.IProgressMonitor; import org.eclipse.core.runtime.IStatus; import org.eclipse.core.runtime.Status; -import org.eclipse.emf.common.util.Diagnostic; -import org.eclipse.emf.ecore.EObject; -import org.eclipse.emf.ecore.EPackage; -import org.eclipse.emf.ecore.EValidator; -import org.eclipse.emf.ecore.resource.Resource; -import org.eclipse.emf.edit.ui.EMFEditUIPlugin; import org.eclipse.emf.validation.preferences.EMFModelValidationPreferences; import org.eclipse.emf.validation.service.IBatchValidator; import org.eclipse.emf.validation.service.IConstraintDescriptor; -import org.eclipse.jface.dialogs.ProgressMonitorDialog; -import org.eclipse.jface.operation.IRunnableWithProgress; -import org.eclipse.swt.widgets.Shell; -import org.eclipse.ui.PartInitException; -import org.eclipse.ui.PlatformUI; -import org.polarsys.capella.common.ef.ExecutionManager; -import org.polarsys.capella.common.ef.command.AbstractReadOnlyCommand; -import org.polarsys.capella.common.helpers.TransactionHelper; +import org.eclipse.ui.statushandlers.StatusManager; import org.polarsys.capella.common.helpers.validation.IValidationConstants; import org.polarsys.capella.common.mdsofa.common.constant.ICommonConstants; -import org.polarsys.capella.common.tools.report.appenders.reportlogview.LightMarkerRegistry; -import org.polarsys.capella.common.tools.report.appenders.reportlogview.MarkerView; -import org.polarsys.capella.core.commands.preferences.service.AbstractPreferencesInitializer; -import org.polarsys.capella.core.model.handler.markers.ICapellaValidationConstants; import org.polarsys.capella.core.platform.sirius.ui.actions.CapellaValidateAction; -import org.polarsys.capella.core.platform.sirius.ui.preferences.ICapellaValidationPreferences; +import org.polarsys.capella.core.validation.EValidatorAdapter; import org.polarsys.capella.core.validation.service.EPFConstraintFilter; -import org.polarsys.capella.core.validation.service.EPFValidatorAdapter; import org.polarsys.capella.core.validation.ui.CapellaValidationUIActivator; import org.polarsys.capella.core.validation.utils.ValidationHelper; public class EPFValidationAction extends CapellaValidateAction { - /* - * - */ - public static Map desabledConstraints = new HashMap(0); - - /* - * Resource hosting the elements of the current diagnostic (see {@link #handleDiagnostic(Diagnostic)}). - */ - protected Resource currentResource; - - /* - * - */ public final static String EPF_EXTNAME = "epf"; //$NON-NLS-1$ - /* - * - */ public final static String EPF_EXTPATTERN = "." + EPF_EXTNAME; //$NON-NLS-1$ - /* - * - */ public final static String KEY_PREFIX = "/instance/org.eclipse.emf.validation//con.disabled/"; //$NON-NLS-1$ - - /* - * - */ - public final static String DEFAULT_VALIDATION_COMMANDNAME = "Default validation"; //$NON-NLS-1$ - - /* - * - */ - public final static String DEFAULT_ROOT_VALIDATION_COMMANDNAME = "Validate Model"; //$NON-NLS-1$ public final static List constraints = ValidationHelper.getAllCapellaConstraintDescriptors(); - /* - * - */ private IFile epf; - /* - * - */ protected Properties properties; - private boolean isParent; - - private HashMap oldPreferences; - /** * @param isRootAction * @param epf */ - public EPFValidationAction(boolean isRootAction, IFile epf) { - this.isParent = isRootAction; - initilizeMarkersResources(); - setEpf(epf); + public EPFValidationAction(IFile epf) { + this.epf = epf; + } - if (null != getEpf()) { - try (FileInputStream fileInput = new FileInputStream(new File(getEpf().getLocation().toOSString()))) { - properties = new Properties(); - properties.load(fileInput); - fileInput.close(); - - } catch (IOException exception) { - exception.printStackTrace(); - } - } + @Override + protected Map getContextEntries() { + Map entries = new HashMap(super.getContextEntries()); + IBatchValidator validator = ValidationHelper.newDefaultCapellaBatchValidator(); + validator.addConstraintFilter(new EPFConstraintFilter(properties)); + entries.put(EValidatorAdapter.BATCH_VALIDATOR, validator); + return entries; } /** @@ -139,149 +72,61 @@ public EPFValidationAction(boolean isRootAction, IFile epf) { */ @Override public void run() { - oldPreferences = new HashMap(); - disableEPFConstraint(); // disable current EPF constraints - - EPFConstraintFilter epfFilter = new EPFConstraintFilter(properties); - - Map oldValidatorRegistry = new HashMap(); - - EPFValidatorAdapter epfValidatorAdapter = CapellaValidationUIActivator.getDefault().getEfpValidatorAdapter(); - - IBatchValidator validator = epfValidatorAdapter.getValidator(); - try { - validator.addConstraintFilter(epfFilter); - oldValidatorRegistry.putAll(EValidator.Registry.INSTANCE); - epfValidatorAdapter.initializeValidatorRegistry(); - - doExecute(); - + IStatus status = Status.OK_STATUS; + try (InputStream stream = epf.getContents()){ + properties = new Properties(); + properties.load(stream); + } catch (IOException exception) { + status = new Status(IStatus.ERROR, + CapellaValidationUIActivator.getDefault().getPluginId(), + exception.getLocalizedMessage(), exception); + } catch (CoreException e) { + status = new Status(e.getStatus().getSeverity(), + CapellaValidationUIActivator.getDefault().getPluginId(), + e.getLocalizedMessage(), e); + } + if (status.isOK()) { + Map oldPreferences = disableEPFConstraint(); try { - MarkerView view = (MarkerView) PlatformUI.getWorkbench().getActiveWorkbenchWindow().getActivePage().showView(MarkerView.MARKER_ID); - IWorkspace workspace = ResourcesPlugin.getWorkspace(); - view.getViewer().setInput(workspace.getRoot()); - view.setAutomaticRefresh(true); - view.getViewer().refresh(); - restoreOldPreference(); - - } catch (PartInitException e) { - CapellaValidationUIActivator.getDefault().log(IStatus.ERROR, e.getMessage(), e); + super.run(); + } finally { + restoreOldPreference(oldPreferences); } - - } finally { - // restore old Validator registry, used in case of other non Capella context - validator.removeConstraintFilter(epfFilter); - EValidator.Registry.INSTANCE.putAll(oldValidatorRegistry); - } - - try { - PlatformUI.getWorkbench().getActiveWorkbenchWindow().getActivePage().showView(MarkerView.VIEW_ID); - } catch (PartInitException e) { - CapellaValidationUIActivator.getDefault().log(IStatus.ERROR, e.getMessage(), e); + } else { + StatusManager.getManager().handle(status, StatusManager.SHOW | StatusManager.LOG); } } - /** - * for EPF constraint validation - * @param activate - */ - private void disableEPFConstraint() { - - for (IConstraintDescriptor iConstraintDescriptor : constraints) { - - String id = iConstraintDescriptor.getId(); - - // save user preferences - oldPreferences.put(id, new Boolean(EMFModelValidationPreferences.isConstraintDisabled(id))); - - // HERE: we need to restore Capella default prefs before applying validation profile since the validation profile was computed from the default prefs so - // it should be applied to default prefs. - boolean constraintDisabledByDefault = EMFModelValidationPreferences.isConstraintDisabledByDefault(id); - EMFModelValidationPreferences.setConstraintDisabled(id, constraintDisabledByDefault); - - String value = properties != null ? properties.getProperty(EPFConstraintFilter.KEY_PREFIX + id) : null; - + + // The epf file only contains an entry for a rule if the current enablement state of the rule + // is different to the default enablement state of the rule. + // This means that all enablement states must be reset to the default before applying + // the values from the epf file. + // After validation, the current enablement state is restored. + private Map disableEPFConstraint() { + Map oldPreferences = new HashMap<>(); + for (IConstraintDescriptor descriptor : constraints) { + String id = descriptor.getId(); + oldPreferences.put(id, EMFModelValidationPreferences.isConstraintDisabled(id)); + boolean disabled = false; + String value = properties.getProperty(EPFConstraintFilter.KEY_PREFIX + id); if (value != null) { - EMFModelValidationPreferences.setConstraintDisabled(id, Boolean.parseBoolean(value)); + disabled = Boolean.parseBoolean(value); + } else { + disabled = EMFModelValidationPreferences.isConstraintDisabledByDefault(id); } - } - - EMFModelValidationPreferences.save(); + EMFModelValidationPreferences.setConstraintDisabled(id, disabled); + } + EMFModelValidationPreferences.save(); + return oldPreferences; } - - /** - * - */ - private void restoreOldPreference() { - for (String string : oldPreferences.keySet()) { - String key = string; + + + private void restoreOldPreference(Map oldPreferences) { + for (String key : oldPreferences.keySet()) { EMFModelValidationPreferences.setConstraintDisabled(key, oldPreferences.get(key)); } EMFModelValidationPreferences.save(); - } - - /** - * - */ - private void doExecute() { - ExecutionManager executionManager = TransactionHelper.getExecutionManager(selectedObjects); - // Precondition. - // Need for an execution manager. - if (null == executionManager) { - return; - } - // Set editing domain, if required. - if (null == domain) { - domain = executionManager.getEditingDomain(); - } - - // Execution action as a read only command. - executionManager.execute(new AbstractReadOnlyCommand() { - @Override - public void run() { - - execute(); - - } - }); - } - - public void execute() { - final Shell shell = PlatformUI.getWorkbench().getActiveWorkbenchWindow().getShell(); - IRunnableWithProgress runnableWithProgress = new IRunnableWithProgress() { - @SuppressWarnings("synthetic-access") - @Override - public void run(final IProgressMonitor progressMonitor) throws InvocationTargetException, InterruptedException { - try { - final Diagnostic diagnostic = validate(progressMonitor); - shell.getDisplay().asyncExec(new Runnable() { - @Override - public void run() { - if (progressMonitor.isCanceled()) { - handleDiagnostic(Diagnostic.CANCEL_INSTANCE); - } else { - handleDiagnostic(diagnostic); - } - } - }); - } finally { - progressMonitor.done(); - } - } - }; - - if (eclipseResourcesUtil != null) { - runnableWithProgress = eclipseResourcesUtil.getWorkspaceModifyOperation(runnableWithProgress); - } - - try { - // This runs the operation, and shows progress. - // (It appears to be a bad thing to fork this onto another thread.) - // - new ProgressMonitorDialog(shell).run(false, true, runnableWithProgress); - } catch (Exception exception) { - EMFEditUIPlugin.INSTANCE.log(exception); - } } /** @@ -289,111 +134,17 @@ public void run() { */ @Override public String getText() { - if (null != getEpf()) { - return getEpf().getName().replace(EPF_EXTPATTERN, ICommonConstants.EMPTY_STRING); - } else if (isParent) { - return DEFAULT_ROOT_VALIDATION_COMMANDNAME; - } - return DEFAULT_VALIDATION_COMMANDNAME; + return epf.getName().replace(EPF_EXTPATTERN, ICommonConstants.EMPTY_STRING); } - /** - * @see org.eclipse.emf.edit.ui.action.ValidateAction.EclipseResourcesUtil#createMarkers(org.eclipse.emf.ecore.resource.Resource, - * org.eclipse.emf.common.util.Diagnostic) - */ - - public void initilizeMarkersResources() { - eclipseResourcesUtil = new EclipseResourcesUtil() { - /** - * {@inheritDoc} - */ - @Override - protected String getMarkerID() { - return ICapellaValidationConstants.CAPELLA_MARKER_ID; - } - - /** - * @see org.eclipse.emf.edit.ui.action.ValidateAction.EclipseResourcesUtil#createMarkers(org.eclipse.emf.ecore.resource.Resource, - * org.eclipse.emf.common.util.Diagnostic) - */ - @Override - public void createMarkers(Resource resource, Diagnostic diagnostic) { - // Don't use 'traditional' resource markers. - // TODO investigate to go back to the traditional ones. - // Original reasons to switch: CDO and too many workspace - // notifications (especially in transitions) - // can't use resource, see handleDiagnostics below - final String epf = getEpf() == null ? "Default" : getEpf().getName(); - LightMarkerRegistry.getInstance().createMarker(getFile(currentResource), diagnostic, getMarkerID(), new LightMarkerRegistry.IMarkerModification() { - @Override - public void modify(IMarker marker) { - try { - marker.setAttribute(IValidationConstants.TAG_PREFERENCE_EPF_FILE, epf); - } catch (CoreException e) { - CapellaValidationUIActivator.getDefault().getLog().log( - new Status(e.getStatus().getSeverity(), CapellaValidationUIActivator.getDefault().getBundle().getSymbolicName(), e.getMessage(), e)); - } - } - }); - } - - /** - * @see org.eclipse.emf.edit.ui.util.EditUIMarkerHelper#deleteMarkers(java.lang.Object, boolean, int) - */ - @Override - public void deleteMarkers(Object object, boolean includeSubtypes, int depth) { - boolean cleanup = AbstractPreferencesInitializer.getBoolean(ICapellaValidationPreferences.P_CLEAN_PREVIOUS_VALIDATION_RESULTS, true); - if (cleanup) { - List markers = new ArrayList(LightMarkerRegistry.getInstance().getMarkers()); - for (IMarker marker : markers) { - try { - if (marker.getType().equals(ICapellaValidationConstants.CAPELLA_MARKER_ID)) { - marker.delete(); - } - } catch (CoreException e) { - CapellaValidationUIActivator.getDefault().log(IStatus.ERROR, e.getMessage(), e); - } - } - } - - } - - }; - - } - - /** - * @see org.eclipse.emf.edit.ui.action.ValidateAction#handleDiagnostic(org.eclipse.emf.common.util.Diagnostic) - */ - @Override - protected void handleDiagnostic(Diagnostic diagnostic) { - // This is all about tweaking the default behavior (that picks the first - // opened resource). + protected void modifyMarker(IMarker marker) { + final String epf = getEpf() == null ? "Default" : getEpf().getName(); //$NON-NLS-1$ try { - // Get diagnostic data. - List data = diagnostic.getData(); - // Check content availability. - if ((null != data) && (data.size() > 0)) { - // Search for a resource holder. - for (Object object : data) { - // That has to be an EObject. - if (object instanceof EObject) { - // Retain current resource... - currentResource = ((EObject) object).eResource(); - // ... and stop the search. - break; - } - } - } - // Go for default behavior. - // Markers will be tagged with current resource at creation time - // (see constructor). - super.handleDiagnostic(diagnostic); - } finally { - // Reset current resource, whatever its value may be. - currentResource = null; - // updateValidationPreferences(false); + marker.setAttribute(IValidationConstants.TAG_PREFERENCE_EPF_FILE, epf); + } catch (CoreException e) { + CapellaValidationUIActivator.getDefault().getLog().log( + new Status(e.getStatus().getSeverity(), CapellaValidationUIActivator.getDefault().getBundle().getSymbolicName(), e.getMessage(), e)); } } @@ -404,11 +155,4 @@ public IFile getEpf() { return epf; } - /** - * @param epf the epf to set - */ - public void setEpf(IFile epf) { - this.epf = epf; - } - } diff --git a/core/plugins/org.polarsys.capella.core.validation.ui/src/org/polarsys/capella/core/validation/ui/actions/ValidationActionProvider.java b/core/plugins/org.polarsys.capella.core.validation.ui/src/org/polarsys/capella/core/validation/ui/actions/ValidationActionProvider.java index 11867d2b11..e3aee95b91 100644 --- a/core/plugins/org.polarsys.capella.core.validation.ui/src/org/polarsys/capella/core/validation/ui/actions/ValidationActionProvider.java +++ b/core/plugins/org.polarsys.capella.core.validation.ui/src/org/polarsys/capella/core/validation/ui/actions/ValidationActionProvider.java @@ -110,8 +110,8 @@ public void init(ICommonActionExtensionSite site) { * @param imageDescriptor * @return */ - protected ValidateAction createValidationAction(boolean isRootAction, IFile file, ISelectionProvider selectionProvider, ImageDescriptor imageDescriptor) { - ValidateAction validationAction = new EPFValidationAction(isRootAction, file); + protected ValidateAction createValidationAction(IFile file, ISelectionProvider selectionProvider, ImageDescriptor imageDescriptor) { + ValidateAction validationAction = new EPFValidationAction(file); validationAction.setImageDescriptor(imageDescriptor); @@ -170,20 +170,16 @@ public void fillContextMenu(IMenuManager menu) { imageDescriptor = CapellaValidationUIActivator.getDefault().getImageDescriptor(CapellaValidationUIActivator.IMG_ENABLED_VALIDATE); userValidationActions = new ArrayList(); menu.prependToGroup("group.validation", defaultValidationAction); //$NON-NLS-1$ - } } - /** - * - */ private void initActions() { ISelectionProvider selectionProvider = commonViewSite.getSelectionProvider(); imageDescriptor = CapellaValidationUIActivator.getDefault().getImageDescriptor(CapellaValidationUIActivator.IMG_ENABLED_VALIDATE); userValidationActions = new ArrayList(); defaultValidationAction = createDefaultValidation();// ValidationAction(false, null, selectionProvider, imageDescriptor); for (IFile file : PreferencesHelper.retrieveUserDefinedPreferenceFiles(selectionProvider, EPFValidationAction.EPF_EXTNAME)) { - userValidationActions.add(createValidationAction(false, file, selectionProvider, imageDescriptor)); + userValidationActions.add(createValidationAction(file, selectionProvider, imageDescriptor)); } } diff --git a/core/plugins/org.polarsys.capella.core.validation/META-INF/MANIFEST.MF b/core/plugins/org.polarsys.capella.core.validation/META-INF/MANIFEST.MF index fe8708a152..1feb086ec7 100644 --- a/core/plugins/org.polarsys.capella.core.validation/META-INF/MANIFEST.MF +++ b/core/plugins/org.polarsys.capella.core.validation/META-INF/MANIFEST.MF @@ -9,10 +9,14 @@ Bundle-Localization: plugin Require-Bundle: org.eclipse.core.expressions, org.eclipse.emf.validation;visibility:=reexport, org.polarsys.capella.core.model.helpers;visibility:=reexport, - org.polarsys.capella.core.model.handler;visibility:=reexport, org.polarsys.capella.core.model.preferences;visibility:=reexport, org.polarsys.capella.common.re.gen, - org.polarsys.capella.common.ui + org.polarsys.capella.common.ui, + org.polarsys.kitalpha.transposer.rules.handler, + org.polarsys.kitalpha.cadence.core, + org.polarsys.capella.common.transition, + org.polarsys.capella.common.transition, + org.polarsys.capella.core.transition.system Export-Package: org.polarsys.capella.core.validation, org.polarsys.capella.core.validation.export, org.polarsys.capella.core.validation.expressions, @@ -20,6 +24,7 @@ Export-Package: org.polarsys.capella.core.validation, org.polarsys.capella.core.validation.filter.group, org.polarsys.capella.core.validation.prefs, org.polarsys.capella.core.validation.rule, + org.polarsys.capella.core.validation.scope, org.polarsys.capella.core.validation.utils Bundle-ActivationPolicy: lazy Bundle-Activator: org.polarsys.capella.core.validation.CapellaValidationActivator diff --git a/core/plugins/org.polarsys.capella.core.validation/plugin.xml b/core/plugins/org.polarsys.capella.core.validation/plugin.xml index 3af9554a9f..336bbffe38 100644 --- a/core/plugins/org.polarsys.capella.core.validation/plugin.xml +++ b/core/plugins/org.polarsys.capella.core.validation/plugin.xml @@ -188,12 +188,6 @@ The difference between Completeness and Coverage can appear subtle. Completeness value="false"> - - - - + + + + + + + + + + + + + + + + + + diff --git a/core/plugins/org.polarsys.capella.core.validation/src/org/polarsys/capella/core/validation/CapellaValidationActivator.java b/core/plugins/org.polarsys.capella.core.validation/src/org/polarsys/capella/core/validation/CapellaValidationActivator.java index 7fca0a0395..3ca59d94a8 100644 --- a/core/plugins/org.polarsys.capella.core.validation/src/org/polarsys/capella/core/validation/CapellaValidationActivator.java +++ b/core/plugins/org.polarsys.capella.core.validation/src/org/polarsys/capella/core/validation/CapellaValidationActivator.java @@ -12,23 +12,26 @@ *******************************************************************************/ package org.polarsys.capella.core.validation; +import org.eclipse.emf.ecore.EPackage; +import org.eclipse.emf.ecore.EValidator; +import org.eclipse.emf.ecore.impl.EValidatorRegistryImpl; import org.eclipse.emf.validation.service.ConstraintRegistry; import org.osgi.framework.BundleContext; - import org.polarsys.capella.common.mdsofa.common.activator.AbstractActivator; -import org.polarsys.capella.core.validation.filter.CapellaConstraintFilter; +import org.polarsys.capella.common.re.RePackage; +import org.polarsys.capella.core.model.helpers.registry.CapellaPackageRegistry; +import org.polarsys.capella.core.validation.utils.ValidationHelper; -/** - */ public class CapellaValidationActivator extends AbstractActivator { /** * Singleton instance. */ private static CapellaValidationActivator __plugin; - /** - * Capella validator adapter. + + /* + * This plugin manages its own validator registry */ - private CapellaValidatorAdapter _capellaValidatorAdapter; + private final EValidator.Registry registry = new EValidatorRegistryImpl(EValidator.Registry.INSTANCE); /** * @see org.eclipse.core.runtime.Plugin#start(org.osgi.framework.BundleContext) @@ -36,13 +39,8 @@ public class CapellaValidationActivator extends AbstractActivator { @Override public void start(BundleContext context) throws Exception { super.start(context); - _capellaValidatorAdapter = new CapellaValidatorAdapter(); - // Add a constraints filter, to disable all constraints that are not capella ones, e.g GMF ones. - _capellaValidatorAdapter.getValidator().addConstraintFilter(new CapellaConstraintFilter()); - _capellaValidatorAdapter.initializeValidatorRegistry(); - + initializeCapellaValidatorRegistry(); ConstraintRegistry.getInstance().addConstraintListener(CapellaConstraintListener.getInstance()); - __plugin = this; } @@ -64,10 +62,21 @@ public static CapellaValidationActivator getDefault() { } /** - * Get the capella validator adapter. - * @return a not null instance. + * Returns the validator registry for capella validation. The registry is configured to + * funnel standard EMF validation through to EMF Constraint Validation via constraints by using an + * {@link CapellaValidatorAdapter} as the validator for all Capella packages and as the default + * for other EPackages. */ - public CapellaValidatorAdapter getCapellaValidatorAdapter() { - return _capellaValidatorAdapter; + public EValidator.Registry getCapellaValidatorRegistry() { + return registry; + } + + private void initializeCapellaValidatorRegistry() { + CapellaValidatorAdapter adapter = new CapellaValidatorAdapter(ValidationHelper.newDefaultCapellaBatchValidator()); + for (EPackage p : CapellaPackageRegistry.getAllCapellaPackages()) { + registry.put(p, adapter); + } + registry.put(RePackage.eINSTANCE, adapter); + registry.put(null, adapter); } } diff --git a/core/plugins/org.polarsys.capella.core.validation/src/org/polarsys/capella/core/validation/CapellaValidatorAdapter.java b/core/plugins/org.polarsys.capella.core.validation/src/org/polarsys/capella/core/validation/CapellaValidatorAdapter.java index 6944d08892..7b7b9dd3cd 100644 --- a/core/plugins/org.polarsys.capella.core.validation/src/org/polarsys/capella/core/validation/CapellaValidatorAdapter.java +++ b/core/plugins/org.polarsys.capella.core.validation/src/org/polarsys/capella/core/validation/CapellaValidatorAdapter.java @@ -12,51 +12,30 @@ *******************************************************************************/ package org.polarsys.capella.core.validation; -import java.util.List; - import org.eclipse.core.runtime.IStatus; import org.eclipse.emf.common.util.DiagnosticChain; -import org.eclipse.emf.ecore.EPackage; -import org.eclipse.emf.ecore.EValidator; import org.eclipse.emf.validation.model.IConstraintStatus; import org.eclipse.emf.validation.service.IBatchValidator; -import org.polarsys.capella.common.data.activity.ActivityPackage; -import org.polarsys.capella.common.data.behavior.BehaviorPackage; -import org.polarsys.capella.common.data.modellingcore.ModellingcorePackage; import org.polarsys.capella.common.helpers.validation.ConstraintStatusDiagnostic; -import org.polarsys.capella.common.re.RePackage; -import org.polarsys.capella.core.data.capellacommon.CapellacommonPackage; -import org.polarsys.capella.core.data.capellacore.CapellacorePackage; -import org.polarsys.capella.core.data.capellamodeller.CapellamodellerPackage; -import org.polarsys.capella.core.data.cs.CsPackage; -import org.polarsys.capella.core.data.ctx.CtxPackage; -import org.polarsys.capella.core.data.epbs.EpbsPackage; -import org.polarsys.capella.core.data.fa.FaPackage; -import org.polarsys.capella.core.data.information.InformationPackage; -import org.polarsys.capella.core.data.information.communication.CommunicationPackage; -import org.polarsys.capella.core.data.information.datatype.DatatypePackage; -import org.polarsys.capella.core.data.information.datavalue.DatavaluePackage; -import org.polarsys.capella.core.data.interaction.InteractionPackage; -import org.polarsys.capella.core.data.la.LaPackage; -import org.polarsys.capella.core.data.oa.OaPackage; -import org.polarsys.capella.core.data.pa.PaPackage; -import org.polarsys.capella.core.data.requirement.RequirementPackage; -import org.polarsys.capella.core.data.sharedmodel.SharedmodelPackage; /** * A specialized validator adapter that handles rule-aware constraints. + * */ +// FIXME what are 'rule-aware' constraints.. public class CapellaValidatorAdapter extends EValidatorAdapter { /** - * - */ - public CapellaValidatorAdapter() { + * @see EValidatorAdapter + */ + public CapellaValidatorAdapter(IBatchValidator defaultBatchValidator) { + super(defaultBatchValidator); } /** * @see org.polarsys.capella.core.validation.EValidatorAdapter#appendDiagnostics(org.eclipse.core.runtime.IStatus, * org.eclipse.emf.common.util.DiagnosticChain) + * FIXME but... i _want_ multistatus constraints!! clients have asked for it multiple times.. */ @Override protected void appendDiagnostics(IStatus status_p, DiagnosticChain diagnostics_p) { @@ -72,48 +51,5 @@ protected void appendDiagnostics(IStatus status_p, DiagnosticChain diagnostics_p } - /** - * @see org.polarsys.capella.core.validation.EValidatorAdapter#getValidator() - */ - @Override - public IBatchValidator getValidator() { - return super.getValidator(); - } - /** - * - */ - public void initializeValidatorRegistry() { - - // capella meta-models - EValidator.Registry.INSTANCE.put(CapellacommonPackage.eINSTANCE, this); - EValidator.Registry.INSTANCE.put(CapellacorePackage.eINSTANCE, this); - EValidator.Registry.INSTANCE.put(CsPackage.eINSTANCE, this); - EValidator.Registry.INSTANCE.put(CtxPackage.eINSTANCE, this); - EValidator.Registry.INSTANCE.put(EpbsPackage.eINSTANCE, this); - EValidator.Registry.INSTANCE.put(FaPackage.eINSTANCE, this); - EValidator.Registry.INSTANCE.put(InformationPackage.eINSTANCE, this); - EValidator.Registry.INSTANCE.put(CommunicationPackage.eINSTANCE, this); - EValidator.Registry.INSTANCE.put(DatatypePackage.eINSTANCE, this); - EValidator.Registry.INSTANCE.put(DatavaluePackage.eINSTANCE, this); - EValidator.Registry.INSTANCE.put(InteractionPackage.eINSTANCE, this); - EValidator.Registry.INSTANCE.put(LaPackage.eINSTANCE, this); - EValidator.Registry.INSTANCE.put(CapellamodellerPackage.eINSTANCE, this); - EValidator.Registry.INSTANCE.put(OaPackage.eINSTANCE, this); - EValidator.Registry.INSTANCE.put(PaPackage.eINSTANCE, this); - EValidator.Registry.INSTANCE.put(RequirementPackage.eINSTANCE, this); - EValidator.Registry.INSTANCE.put(SharedmodelPackage.eINSTANCE, this); - // re meta-model - EValidator.Registry.INSTANCE.put(RePackage.eINSTANCE, this); - // shared meta-models - EValidator.Registry.INSTANCE.put(ActivityPackage.eINSTANCE, this); - EValidator.Registry.INSTANCE.put(BehaviorPackage.eINSTANCE, this); - EValidator.Registry.INSTANCE.put(ModellingcorePackage.eINSTANCE, this); - - } - - public void registerAdditionalPackages(List packages) { - for (EPackage ePkg : packages) - EValidator.Registry.INSTANCE.put(ePkg, this); - } } diff --git a/core/plugins/org.polarsys.capella.core.validation/src/org/polarsys/capella/core/validation/EValidatorAdapter.java b/core/plugins/org.polarsys.capella.core.validation/src/org/polarsys/capella/core/validation/EValidatorAdapter.java index abdef5410c..76bf51db3d 100644 --- a/core/plugins/org.polarsys.capella.core.validation/src/org/polarsys/capella/core/validation/EValidatorAdapter.java +++ b/core/plugins/org.polarsys.capella.core.validation/src/org/polarsys/capella/core/validation/EValidatorAdapter.java @@ -20,49 +20,40 @@ import org.eclipse.emf.common.util.BasicDiagnostic; import org.eclipse.emf.common.util.DiagnosticChain; import org.eclipse.emf.ecore.EClass; -import org.eclipse.emf.ecore.EDataType; import org.eclipse.emf.ecore.EObject; import org.eclipse.emf.ecore.util.EObjectValidator; -import org.eclipse.emf.validation.model.EvaluationMode; import org.eclipse.emf.validation.model.IConstraintStatus; import org.eclipse.emf.validation.service.IBatchValidator; -import org.eclipse.emf.validation.service.ModelValidationService; /** * An adapter that plugs the EMF Model Validation Service API into the {@link org.eclipse.emf.ecore.EValidator} API. */ public class EValidatorAdapter extends EObjectValidator { - /** - * Model Validation Service interface for batch validation of EMF elements. - */ - private IBatchValidator _validator; /** - * Constructor.
- * Default constructor includes live constraints, does not report successes. + * Clients may provide their own batch validator instance by + * storing it under this key in the validation context. */ - public EValidatorAdapter() { - this(true, false); - } + public static final Object BATCH_VALIDATOR = IBatchValidator.class; - /** - * Get the underlying batch validator. - * @return the validator - */ - protected IBatchValidator getValidator() { - return _validator; + private final IBatchValidator defaultValidator; + + private IBatchValidator getValidator(Map context) { + IBatchValidator validator = (IBatchValidator) context.get(EValidatorAdapter.BATCH_VALIDATOR); + if (validator == null) { + validator = defaultValidator; + } + return validator; } /** - * Constructor. - * @param includeLiveConstraints_p - * @param reportSuccesses_p + * Create an adapter that uses the argument as the default batch validator. + * Clients that invoke validation can override this validator + * by passing their own under the {@link #BATCH_VALIDATOR} key in + * the validation context. */ - public EValidatorAdapter(boolean includeLiveConstraints_p, boolean reportSuccesses_p) { - super(); - _validator = (IBatchValidator) ModelValidationService.getInstance().newValidator(EvaluationMode.BATCH); - _validator.setIncludeLiveConstraints(includeLiveConstraints_p); - _validator.setReportSuccesses(reportSuccesses_p); + public EValidatorAdapter(IBatchValidator defaultBatchValidator) { + defaultValidator = defaultBatchValidator; } /** @@ -78,70 +69,14 @@ public boolean validate(EObject eObject_p, DiagnosticChain diagnostics_p, Map context_p) { - // First, do whatever the basic EcoreValidator does - super.validate(eClass_p, eObject_p, diagnostics_p, context_p); - IStatus status = Status.OK_STATUS; - // No point in validating if we can't report results - if (null != diagnostics_p) { - // if EMF Mode Validation Service already covered the sub-tree, - // which it does for efficient computation and error reporting, - // then don't repeat (the Diagnostician does the recursion - // externally). If there is no context map, then we can't - // help it - if (!hasProcessed(eObject_p, context_p)) { - status = getValidator().validate(eObject_p, new NullProgressMonitor()); - processed(eObject_p, context_p, status); - appendDiagnostics(status, diagnostics_p); - } - } - return status.isOK(); - } - - /** - * Direct validation of {@link EDataType}s is not supported by the EMF validation framework; they are validated indirectly via the {@link EObject}s that - * hold their values. - */ - @Override - public boolean validate(EDataType eDataType_p, Object value_p, DiagnosticChain diagnostics_p, Map context_p) { - return super.validate(eDataType_p, value_p, diagnostics_p, context_p); - } - - /** - * If we have a context map, record this object's status in it so that we will know later that we have processed it and its sub-tree. - * @param eObject_p an element that we have validated - * @param context_p the context (may be null) - * @param status_p the element's validation status - */ - protected void processed(EObject eObject_p, Map context_p, IStatus status_p) { - if (null != context_p) { - context_p.put(eObject_p, status_p); + if (context_p.get(ROOT_OBJECT) == null) { + status = getValidator(context_p).validate(eObject_p, new NullProgressMonitor()); + appendDiagnostics(status, diagnostics_p); } + return super.validate(eClass_p, eObject_p, diagnostics_p, context_p) && status.isOK(); } - /** - * Determines whether we have processed this eObject before, by automatic recursion of the EMF Model Validation Service. This is only possible - * if we do, indeed, have a context. - * @param eObject_p an element to be validated (we hope not) - * @param context_p the context (may be null) - * @return true if the context is not null and the eObject or one of its containers has already been validated; - * false, otherwise - */ - protected boolean hasProcessed(EObject eObject_p, Map context_p) { - boolean result = false; - if (null != context_p) { - EObject eObject = eObject_p; - // This is O(NlogN) but there's no helping it - while ((null != eObject) && !result) { - if (context_p.containsKey(eObject)) { - result = true; - } else { - eObject = eObject.eContainer(); - } - } - } - return result; - } /** * Converts a status result from the EMF validation service to diagnostics. diff --git a/core/plugins/org.polarsys.capella.core.validation/src/org/polarsys/capella/core/validation/DiagnosticianProvider.java b/core/plugins/org.polarsys.capella.core.validation/src/org/polarsys/capella/core/validation/LegacyDiagnosticianProvider.java similarity index 59% rename from core/plugins/org.polarsys.capella.core.validation/src/org/polarsys/capella/core/validation/DiagnosticianProvider.java rename to core/plugins/org.polarsys.capella.core.validation/src/org/polarsys/capella/core/validation/LegacyDiagnosticianProvider.java index 77be598b86..7e6c11df77 100644 --- a/core/plugins/org.polarsys.capella.core.validation/src/org/polarsys/capella/core/validation/DiagnosticianProvider.java +++ b/core/plugins/org.polarsys.capella.core.validation/src/org/polarsys/capella/core/validation/LegacyDiagnosticianProvider.java @@ -20,18 +20,13 @@ import org.polarsys.capella.core.model.handler.validation.CapellaDiagnostician; /** - * Provide a Diagnostician to Capella validate actions via the diagnosticianProvider extension point. - * A side-effect of using this extension point is that we ensure that this plugin can make any required - * modifications to the global EValidator.Registry before any validation action is run. - * @see CapellaValidationActivator + * Provides the old Tree+Part/Type diagnostician. */ -public class DiagnosticianProvider extends AbstractDiagnosticianProvider { +public class LegacyDiagnosticianProvider extends AbstractDiagnosticianProvider { @Override - public Diagnostician getDiagnostician(AdapterFactory adapterFactory_p, IProgressMonitor progressMonitor_p) { - // just return a capella diagnostician.. - // the wanted side effect is that the plugin has been activated at this point - return new CapellaDiagnostician(adapterFactory_p, progressMonitor_p); + public Diagnostician getDiagnostician(AdapterFactory adapterFactory, IProgressMonitor progressMonitor) { + return new CapellaDiagnostician(CapellaValidationActivator.getDefault().getCapellaValidatorRegistry(), adapterFactory, progressMonitor); } } diff --git a/core/plugins/org.polarsys.capella.core.validation/src/org/polarsys/capella/core/validation/filter/CapellaConstraintFilter.java b/core/plugins/org.polarsys.capella.core.validation/src/org/polarsys/capella/core/validation/filter/CapellaConstraintFilter.java index eceeaf0ffe..8b86260a6e 100644 --- a/core/plugins/org.polarsys.capella.core.validation/src/org/polarsys/capella/core/validation/filter/CapellaConstraintFilter.java +++ b/core/plugins/org.polarsys.capella.core.validation/src/org/polarsys/capella/core/validation/filter/CapellaConstraintFilter.java @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (c) 2006, 2020 THALES GLOBAL SERVICES. + * Copyright (c) 2006, 2020 THALES GLOBAL SERVICES. * * This program and the accompanying materials are made available under the * terms of the Eclipse Public License 2.0 which is available at @@ -20,9 +20,16 @@ import org.eclipse.emf.validation.service.IConstraintFilter; /** - * Base class to implement constraint filters for Capella. + * Only constraints in the capella.category {@link Category} pass + * this filter. */ -public class CapellaConstraintFilter implements IConstraintFilter { +public final class CapellaConstraintFilter implements IConstraintFilter { + + public static final CapellaConstraintFilter INSTANCE = new CapellaConstraintFilter(); + + private CapellaConstraintFilter() { + } + /** * Category path for Common constraints. */ diff --git a/core/plugins/org.polarsys.capella.core.validation/src/org/polarsys/capella/core/validation/scope/DefaultScopedDiagnosticianProvider.java b/core/plugins/org.polarsys.capella.core.validation/src/org/polarsys/capella/core/validation/scope/DefaultScopedDiagnosticianProvider.java new file mode 100644 index 0000000000..995ef181dd --- /dev/null +++ b/core/plugins/org.polarsys.capella.core.validation/src/org/polarsys/capella/core/validation/scope/DefaultScopedDiagnosticianProvider.java @@ -0,0 +1,24 @@ +/******************************************************************************* + * Copyright (c) 2006, 2020 THALES GLOBAL SERVICES. + * + * This program and the accompanying materials are made available under the + * terms of the Eclipse Public License 2.0 which is available at + * http://www.eclipse.org/legal/epl-2.0 + * + * SPDX-License-Identifier: EPL-2.0 + * + * Contributors: + * Thales - initial API and implementation + *******************************************************************************/ +package org.polarsys.capella.core.validation.scope; + +import org.polarsys.capella.core.validation.CapellaValidationActivator; + +public class DefaultScopedDiagnosticianProvider extends ScopedDiagnosticianProvider { + + public DefaultScopedDiagnosticianProvider() { + super("org.polarsys.capella.core.validation", + "org.polarsys.capella.core.validation.extended", + CapellaValidationActivator.getDefault().getCapellaValidatorRegistry()); + } +} diff --git a/core/plugins/org.polarsys.capella.core.validation/src/org/polarsys/capella/core/validation/scope/DefaultValidationScopeFilter.java b/core/plugins/org.polarsys.capella.core.validation/src/org/polarsys/capella/core/validation/scope/DefaultValidationScopeFilter.java new file mode 100644 index 0000000000..b6a40404fd --- /dev/null +++ b/core/plugins/org.polarsys.capella.core.validation/src/org/polarsys/capella/core/validation/scope/DefaultValidationScopeFilter.java @@ -0,0 +1,54 @@ +/******************************************************************************* + * Copyright (c) 2006, 2020 THALES GLOBAL SERVICES. + * + * This program and the accompanying materials are made available under the + * terms of the Eclipse Public License 2.0 which is available at + * http://www.eclipse.org/legal/epl-2.0 + * + * SPDX-License-Identifier: EPL-2.0 + * + * Contributors: + * Thales - initial API and implementation + *******************************************************************************/ +package org.polarsys.capella.core.validation.scope; + +import org.eclipse.emf.ecore.EObject; +import org.eclipse.emf.ecore.util.EcoreUtil; +import org.polarsys.capella.core.data.cs.Interface; +import org.polarsys.capella.core.data.fa.ComponentExchange; +import org.polarsys.capella.core.data.fa.FunctionalExchange; +import org.polarsys.capella.core.transition.common.handlers.scope.IScopeFilter; +import org.polarsys.kitalpha.transposer.rules.handler.rules.api.IContext; + +public class DefaultValidationScopeFilter implements IScopeFilter { + + @Override + public boolean isValidScopeElement(EObject element, IContext context) { + + ScopedDiagnostician.Context tContext = (ScopedDiagnostician.Context) context; + + // Only validate extended scope interfaces if one provider and one requirer are in the scope + if (element instanceof Interface) { + boolean providerInScope = ((Interface) element).getProvidingComponentPorts().stream().anyMatch(cp -> EcoreUtil.isAncestor(tContext.getValidationRoots(), cp)); + boolean requirerInScope = ((Interface) element).getRequiringComponentPorts().stream().anyMatch(cp -> EcoreUtil.isAncestor(tContext.getValidationRoots(), cp)); + return providerInScope && requirerInScope; + } + + // Only validate extended scope exchanges if source and target are in the scope + if (element instanceof ComponentExchange) { + ComponentExchange ce = (ComponentExchange) element; + boolean sourceInScope = EcoreUtil.isAncestor(tContext.getValidationRoots(), ce.getSource()); + boolean targetInScope = EcoreUtil.isAncestor(tContext.getValidationRoots(), ce.getTarget()); + return sourceInScope && targetInScope; + } + if (element instanceof FunctionalExchange) { + FunctionalExchange fe = (FunctionalExchange) element; + boolean sourceInScope = EcoreUtil.isAncestor(tContext.getValidationRoots(), fe.getSource()); + boolean targetInScope = EcoreUtil.isAncestor(tContext.getValidationRoots(), fe.getTarget()); + return sourceInScope && targetInScope; + } + + return true; + } + +} diff --git a/core/plugins/org.polarsys.capella.core.validation/src/org/polarsys/capella/core/validation/scope/DefaultValidationScopeRetriever.java b/core/plugins/org.polarsys.capella.core.validation/src/org/polarsys/capella/core/validation/scope/DefaultValidationScopeRetriever.java new file mode 100644 index 0000000000..60d1c4047e --- /dev/null +++ b/core/plugins/org.polarsys.capella.core.validation/src/org/polarsys/capella/core/validation/scope/DefaultValidationScopeRetriever.java @@ -0,0 +1,47 @@ +/******************************************************************************* + * Copyright (c) 2006, 2020 THALES GLOBAL SERVICES. + * + * This program and the accompanying materials are made available under the + * terms of the Eclipse Public License 2.0 which is available at + * http://www.eclipse.org/legal/epl-2.0 + * + * SPDX-License-Identifier: EPL-2.0 + * + * Contributors: + * Thales - initial API and implementation + *******************************************************************************/ +package org.polarsys.capella.core.validation.scope; + +import java.util.Arrays; +import java.util.Collection; +import java.util.LinkedHashSet; + +import org.eclipse.emf.ecore.EObject; +import org.polarsys.capella.core.data.fa.FaPackage; +import org.polarsys.capella.core.data.information.InformationPackage; +import org.polarsys.capella.core.transition.common.handlers.scope.EReferenceScopeRetriever; +import org.polarsys.capella.core.transition.common.handlers.scope.IScopeRetriever; +import org.polarsys.capella.core.transition.system.handlers.scope.DeployedElementRetriever; +import org.polarsys.capella.core.transition.system.handlers.scope.PartTypeRetriever; +import org.polarsys.kitalpha.transposer.rules.handler.rules.api.IContext; + +public class DefaultValidationScopeRetriever implements IScopeRetriever { + + @Override + public Collection retrieveRelatedElements(EObject element, IContext context) { + Collection subs = Arrays.asList( + new PartTypeRetriever(), + new DeployedElementRetriever(), + new EReferenceScopeRetriever(FaPackage.Literals.ABSTRACT_FUNCTIONAL_BLOCK__ALLOCATED_FUNCTIONS), + new EReferenceScopeRetriever(FaPackage.Literals.COMPONENT_PORT__COMPONENT_EXCHANGES), + new EReferenceScopeRetriever(FaPackage.Literals.FUNCTION_OUTPUT_PORT__OUTGOING_FUNCTIONAL_EXCHANGES), + new EReferenceScopeRetriever(FaPackage.Literals.FUNCTION_INPUT_PORT__INCOMING_FUNCTIONAL_EXCHANGES), + new EReferenceScopeRetriever(InformationPackage.Literals.PORT__PROVIDED_INTERFACES), + new EReferenceScopeRetriever(InformationPackage.Literals.PORT__REQUIRED_INTERFACES) + ); + Collection result = new LinkedHashSet(); + subs.forEach(sub -> result.addAll(sub.retrieveRelatedElements(element, context))); + return result; + } + +} diff --git a/core/plugins/org.polarsys.capella.core.validation/src/org/polarsys/capella/core/validation/scope/ScopedDiagnostician.java b/core/plugins/org.polarsys.capella.core.validation/src/org/polarsys/capella/core/validation/scope/ScopedDiagnostician.java new file mode 100644 index 0000000000..016af5c0f1 --- /dev/null +++ b/core/plugins/org.polarsys.capella.core.validation/src/org/polarsys/capella/core/validation/scope/ScopedDiagnostician.java @@ -0,0 +1,163 @@ +/******************************************************************************* + * Copyright (c) 2006, 2020 THALES GLOBAL SERVICES. + * + * This program and the accompanying materials are made available under the + * terms of the Eclipse Public License 2.0 which is available at + * http://www.eclipse.org/legal/epl-2.0 + * + * SPDX-License-Identifier: EPL-2.0 + * + * Contributors: + * Thales - initial API and implementation + *******************************************************************************/ +package org.polarsys.capella.core.validation.scope; + +import java.util.ArrayDeque; +import java.util.ArrayList; +import java.util.Collection; +import java.util.Collections; +import java.util.Deque; +import java.util.HashMap; +import java.util.Iterator; +import java.util.Map; +import java.util.stream.Collectors; + +import org.eclipse.emf.common.notify.AdapterFactory; +import org.eclipse.emf.common.util.DiagnosticChain; +import org.eclipse.emf.common.util.TreeIterator; +import org.eclipse.emf.ecore.EObject; +import org.eclipse.emf.ecore.EValidator; +import org.eclipse.emf.ecore.util.EObjectValidator; +import org.eclipse.emf.ecore.util.EcoreUtil; +import org.eclipse.emf.edit.provider.IItemLabelProvider; +import org.polarsys.capella.core.model.handler.validation.MultiobjectDiagnostician; +import org.polarsys.capella.core.transition.common.ExtensionHelper; +import org.polarsys.capella.core.transition.common.constants.ISchemaConstants; +import org.polarsys.capella.core.transition.common.handlers.scope.IScopeFilter; +import org.polarsys.capella.core.transition.common.handlers.scope.IScopeRetriever; +import org.polarsys.kitalpha.transposer.generic.GenericContext; +import org.polarsys.kitalpha.transposer.rules.handler.rules.api.IContext; + +/** + * ScopedDiagnosticians calculate a set of validation roots from + * a set of {@link IScopeRetriever}s and {@link IScopeFilter}s. These filters and retrievers + * are selected by providing the mapping/purpose id under which they are registered + * via the org.polarsys.capella.core.transition.handlers extension point. + */ +public class ScopedDiagnostician extends MultiobjectDiagnostician { + + private final AdapterFactory adapterFactory; + private final String mapping; + private final String purpose; + + public ScopedDiagnostician(EValidator.Registry registry, AdapterFactory adapterFactory, String purpose, String mapping) { + super(registry); + this.adapterFactory = adapterFactory; + this.purpose = purpose; + this.mapping = mapping; + } + + public static class Context extends GenericContext { + private Collection selection; + private Collection roots; + Context(HashMap map){ + _repository = map; + } + public Collection getSelection() { + return Collections.unmodifiableCollection(selection); + } + public Collection getValidationRoots(){ + return roots; + } + @Override + public void reset() { + super.reset(); + selection = null; + roots = null; + } + } + + public Map createDefaultContext(){ + HashMap defaultContext = new HashMap<>(); + IContext gc = new Context(defaultContext); + gc.put(EValidator.SubstitutionLabelProvider.class, this); + gc.put(EValidator.class, this); + gc.put(IContext.class, gc); + return defaultContext; + } + + @Override + public String getObjectLabel(EObject eObject) { + if (adapterFactory != null && !eObject.eIsProxy()) { + IItemLabelProvider itemLabelProvider = (IItemLabelProvider)adapterFactory.adapt(eObject, IItemLabelProvider.class); + if (itemLabelProvider != null) { + return itemLabelProvider.getText(eObject); + } + } + return super.getObjectLabel(eObject); + } + + public boolean validate(Collection eObjects, DiagnosticChain diagnostics, Map context) { + + Context tContext = (Context) context.get(IContext.class); + tContext.reset(); + tContext.selection = eObjects; + Collection roots = new ArrayList<>(); + + Collection retrievers = ExtensionHelper.collectFromExtensions(tContext, ISchemaConstants.EXTENSION_ID, + ISchemaConstants.SCOPE_RETRIEVER, purpose, mapping).stream().filter(r -> r.init(tContext).isOK()).collect(Collectors.toList()); + + Deque work = new ArrayDeque(eObjects); + while (!work.isEmpty()) { + EObject pseudoRoot = work.pop(); + if (!EcoreUtil.isAncestor(roots, pseudoRoot)) { + for (TreeIterator it = EcoreUtil.getAllContents(Collections.singleton(pseudoRoot)); it.hasNext();) { + EObject next = it.next(); + if (roots.remove(next)) { + it.prune(); + } else { + reportProgress(); + retrievers.forEach(r->work.addAll(r.retrieveRelatedElements(next, tContext))); + } + } + roots.add(pseudoRoot); + } + } + retrievers.forEach(r -> r.dispose(tContext)); + + // + // Every IScopeFilter is given a chance to remove any of the root elements from the validation, unless the root element is part of the initial selection. + // + tContext.roots = roots; + Collection filters = ExtensionHelper.collectFromExtensions(tContext, ISchemaConstants.EXTENSION_ID, ISchemaConstants.SCOPE_FILTER, purpose, mapping) + .stream().filter(f -> f.init(tContext).isOK()).collect(Collectors.toList()); + + for (Iterator it = roots.iterator(); it.hasNext();) { + EObject next = it.next(); + if (!EcoreUtil.isAncestor(tContext.getSelection(), next)) { + if (filters.stream().anyMatch(f -> !f.isValidScopeElement(next, tContext))) { + it.remove(); + } + } + } + filters.forEach(f -> f.dispose(tContext)); + + boolean result = true; + for (EObject e : roots) { + result &= super.validate(e, diagnostics, context); + context.remove(EObjectValidator.ROOT_OBJECT); + } + return result; + } + + @Override + public boolean validate(EObject eObject, DiagnosticChain diagnostics, Map context) { + return validate(Collections.singleton(eObject), diagnostics, context); + } + + /** + * Subclasses can override this hook to report progress to the surrounding context. + */ + protected void reportProgress() {} + +} diff --git a/core/plugins/org.polarsys.capella.core.validation/src/org/polarsys/capella/core/validation/scope/ScopedDiagnosticianProvider.java b/core/plugins/org.polarsys.capella.core.validation/src/org/polarsys/capella/core/validation/scope/ScopedDiagnosticianProvider.java new file mode 100644 index 0000000000..7feabece32 --- /dev/null +++ b/core/plugins/org.polarsys.capella.core.validation/src/org/polarsys/capella/core/validation/scope/ScopedDiagnosticianProvider.java @@ -0,0 +1,56 @@ +/******************************************************************************* + * Copyright (c) 2020 THALES GLOBAL SERVICES. + * + * This program and the accompanying materials are made available under the + * terms of the Eclipse Public License 2.0 which is available at + * http://www.eclipse.org/legal/epl-2.0 + * + * SPDX-License-Identifier: EPL-2.0 + * + * Contributors: + * Thales - initial API and implementation + *******************************************************************************/ +package org.polarsys.capella.core.validation.scope; + +import java.util.Map; + +import org.eclipse.core.runtime.IProgressMonitor; +import org.eclipse.emf.common.notify.AdapterFactory; +import org.eclipse.emf.common.util.DiagnosticChain; +import org.eclipse.emf.ecore.EClass; +import org.eclipse.emf.ecore.EObject; +import org.eclipse.emf.ecore.EValidator; +import org.eclipse.emf.ecore.util.Diagnostician; +import org.polarsys.capella.core.model.handler.validation.AbstractDiagnosticianProvider; + +public class ScopedDiagnosticianProvider extends AbstractDiagnosticianProvider { + + private final String purpose; + private final String mapping; + private final EValidator.Registry registry; + + protected ScopedDiagnosticianProvider(String purpose, String mapping, EValidator.Registry registry) { + this.purpose = purpose; + this.mapping = mapping; + this.registry = registry; + } + + @Override + public Diagnostician getDiagnostician(AdapterFactory adapterFactory, IProgressMonitor progressMonitor) { + return new ScopedDiagnostician( + registry, adapterFactory, purpose, mapping) { + @Override + protected boolean doValidate(EValidator eValidator, EClass eClass, EObject eObject, DiagnosticChain diagnostics, + Map context) { + progressMonitor.worked(1); + return super.doValidate(eValidator, eClass, eObject, diagnostics, context); + } + + @Override + protected void reportProgress() { + progressMonitor.worked(1); + } + }; + } + +} diff --git a/core/plugins/org.polarsys.capella.core.validation/src/org/polarsys/capella/core/validation/utils/ValidationHelper.java b/core/plugins/org.polarsys.capella.core.validation/src/org/polarsys/capella/core/validation/utils/ValidationHelper.java index 38ef00ef22..ab2ed4d2f5 100644 --- a/core/plugins/org.polarsys.capella.core.validation/src/org/polarsys/capella/core/validation/utils/ValidationHelper.java +++ b/core/plugins/org.polarsys.capella.core.validation/src/org/polarsys/capella/core/validation/utils/ValidationHelper.java @@ -13,12 +13,16 @@ package org.polarsys.capella.core.validation.utils; import java.util.ArrayList; +import java.util.Collection; import java.util.List; import java.util.Set; import org.eclipse.emf.validation.model.Category; +import org.eclipse.emf.validation.model.EvaluationMode; import org.eclipse.emf.validation.service.ConstraintRegistry; +import org.eclipse.emf.validation.service.IBatchValidator; import org.eclipse.emf.validation.service.IConstraintDescriptor; +import org.eclipse.emf.validation.service.IValidator; import org.eclipse.emf.validation.service.ModelValidationService; import org.polarsys.capella.core.validation.filter.CapellaConstraintFilter; @@ -30,21 +34,16 @@ */ public class ValidationHelper { + static { + ModelValidationService.getInstance().loadXmlConstraintDeclarations(); + } + /** * Get all constraints contributed via the EMF Validation framework * @return */ public static List getAllConstraintDescriptors() { - - List result = new ArrayList(); - - ensureEMFValidationActivation(); - - ConstraintRegistry registry = ConstraintRegistry.getInstance(); - - result.addAll(registry.getAllDescriptors()); - - return result; + return new ArrayList(ConstraintRegistry.getInstance().getAllDescriptors()); } /** @@ -53,12 +52,8 @@ public static List getAllConstraintDescriptors() { * @return */ public static List getAllCapellaConstraintDescriptors() { - List result = new ArrayList(); - - ensureEMFValidationActivation(); - - for (IConstraintDescriptor icd: getAllConstraintDescriptors()) { + for (IConstraintDescriptor icd: ConstraintRegistry.getInstance().getAllDescriptors()) { Set categories = icd.getCategories(); for (Category category : categories) { String categoryPath = category.getPath(); @@ -68,18 +63,33 @@ public static List getAllCapellaConstraintDescriptors() { } } } - return result; } - + + @SuppressWarnings("unchecked") /** - * Ensure that all constraints have been loaded. + * Create a new filtering validator. + * @param ruleIDs the IDs of constraints to validate. */ - public static void ensureEMFValidationActivation() { - - ModelValidationService.getInstance().loadXmlConstraintDeclarations(); - - return; + public static > V newValidator(Collection ruleIDs, EvaluationMode mode) { + IValidator validator = ModelValidationService.getInstance().newValidator(mode); + validator.addConstraintFilter((constraint, target) -> ruleIDs.contains(constraint.getId())); + return (V) validator; + } + + /** + * Creates and configures a standard batch validator for usage in Capella. + * - Live constraints are enabled + * - Report Sucesses is disabled + * - CapellaConstraintFilter is installed + */ + public static IBatchValidator newDefaultCapellaBatchValidator() { + IBatchValidator defaultBatchValidator = ModelValidationService.getInstance().newValidator(EvaluationMode.BATCH); + defaultBatchValidator.setIncludeLiveConstraints(true); + defaultBatchValidator.setReportSuccesses(false); + defaultBatchValidator.addConstraintFilter(CapellaConstraintFilter.INSTANCE); + return defaultBatchValidator; } + } diff --git a/tests/plugins/org.polarsys.capella.test.projection.ju/src/org/polarsys/capella/test/projection/ju/Rule_DWF_I_23.java b/tests/plugins/org.polarsys.capella.test.projection.ju/src/org/polarsys/capella/test/projection/ju/Rule_DWF_I_23.java index b60a8ca18d..e19166e591 100644 --- a/tests/plugins/org.polarsys.capella.test.projection.ju/src/org/polarsys/capella/test/projection/ju/Rule_DWF_I_23.java +++ b/tests/plugins/org.polarsys.capella.test.projection.ju/src/org/polarsys/capella/test/projection/ju/Rule_DWF_I_23.java @@ -16,55 +16,29 @@ import java.util.List; import org.eclipse.core.runtime.IStatus; -import org.eclipse.emf.ecore.EObject; import org.eclipse.emf.ecore.util.EcoreUtil; +import org.eclipse.emf.validation.model.EvaluationMode; import org.eclipse.emf.validation.model.IConstraintStatus; -import org.eclipse.emf.validation.service.ConstraintRegistry; import org.eclipse.emf.validation.service.IBatchValidator; -import org.eclipse.emf.validation.service.IConstraintDescriptor; -import org.eclipse.emf.validation.service.IConstraintFilter; -import org.eclipse.emf.validation.service.ModelValidationService; import org.polarsys.capella.core.data.cs.Component; import org.polarsys.capella.core.projection.interfaces.validation.DWF_I_23_GenerateInterfacesValidator; -import org.polarsys.capella.core.validation.CapellaValidationActivator; +import org.polarsys.capella.core.validation.utils.ValidationHelper; import org.polarsys.capella.test.framework.api.BasicCommandTestCase; /** * Runs model validation for components, and compares actual and expected validation results for related * interfaces/exchange items */ -// FIXME cannot use ValidationRuleTest for this because of https://bugs.polarsys.org/show_bug.cgi?id=1342 +// FIXME cannot use ValidationRuleTest for this because of https://bugs.eclipse.org/bugs/show_bug.cgi?id=554209 public class Rule_DWF_I_23 extends BasicCommandTestCase { - IBatchValidator validator; - IConstraintFilter filter; + private IBatchValidator validator; protected void setUp() throws Exception { super.setUp(); - - // init validator - validator = CapellaValidationActivator.getDefault().getCapellaValidatorAdapter().getValidator(); - ModelValidationService.getInstance().loadXmlConstraintDeclarations();// load the xml definition of constraints - // get the descriptor of the rule to test - ConstraintRegistry registry = ConstraintRegistry.getInstance(); - final IConstraintDescriptor ruleDescriptor = registry.getDescriptor(DWF_I_23_GenerateInterfacesValidator.RULE_ID); - assertNotNull(ruleDescriptor); - - filter = new IConstraintFilter() { - public boolean accept(IConstraintDescriptor constraint, EObject target) { - return ruleDescriptor == constraint; - } - }; - validator.addConstraintFilter(filter); + validator = ValidationHelper.newValidator(Collections.singleton(DWF_I_23_GenerateInterfacesValidator.RULE_ID), EvaluationMode.BATCH); } - @Override - protected void tearDown() throws Exception { - validator.removeConstraintFilter(filter); - super.tearDown(); - } - - @Override public List getRequiredTestModels() { return Collections.singletonList("testInterfacesFromAllocatedFunctions"); //$NON-NLS-1$ diff --git a/tests/plugins/org.polarsys.capella.test.validation.rules.ju/src/org/polarsys/capella/test/validation/rules/ju/testcases/ValidationRuleTestCase.java b/tests/plugins/org.polarsys.capella.test.validation.rules.ju/src/org/polarsys/capella/test/validation/rules/ju/testcases/ValidationRuleTestCase.java index bd12be539b..47b88096d2 100644 --- a/tests/plugins/org.polarsys.capella.test.validation.rules.ju/src/org/polarsys/capella/test/validation/rules/ju/testcases/ValidationRuleTestCase.java +++ b/tests/plugins/org.polarsys.capella.test.validation.rules.ju/src/org/polarsys/capella/test/validation/rules/ju/testcases/ValidationRuleTestCase.java @@ -14,8 +14,10 @@ import java.util.ArrayList; import java.util.Collections; +import java.util.HashMap; import java.util.Hashtable; import java.util.List; +import java.util.Map; import java.util.stream.Collectors; import org.eclipse.core.resources.IMarker; @@ -42,6 +44,8 @@ import org.polarsys.capella.core.libraries.model.ICapellaModel; import org.polarsys.capella.core.model.handler.markers.ICapellaValidationConstants; import org.polarsys.capella.core.validation.CapellaValidationActivator; +import org.polarsys.capella.core.validation.EValidatorAdapter; +import org.polarsys.capella.core.validation.utils.ValidationHelper; import org.polarsys.capella.test.framework.api.BasicTestCase; import org.polarsys.capella.test.framework.api.OracleDefinition; @@ -100,7 +104,8 @@ protected void setUp() throws Exception { super.setUp(); // init validator - validator = CapellaValidationActivator.getDefault().getCapellaValidatorAdapter().getValidator(); + validator = ValidationHelper.newDefaultCapellaBatchValidator(); + ModelValidationService.getInstance().loadXmlConstraintDeclarations();// load the xml definition of constraints // get the descriptor of the rule to test ConstraintRegistry registry = ConstraintRegistry.getInstance(); @@ -162,12 +167,15 @@ public void test() throws Exception { } // check the validation result for each objects List failedObjects = new ArrayList(); - Diagnostician diagnostician = new Diagnostician(); + Diagnostician diagnostician = new Diagnostician(CapellaValidationActivator.getDefault().getCapellaValidatorRegistry()); + Map contextEntries = new HashMap<>(); + contextEntries.put(EValidatorAdapter.BATCH_VALIDATOR, validator); + for (EObject object : objectsToValidate) { String objectID = getId(object); OracleDefinition oracleDef = objectID2OracleDefinition.get(objectID); - Diagnostic diagnostic = diagnostician.validate(object); - + Diagnostic diagnostic = diagnostician.validate(object, contextEntries); + if ((diagnostic.getSeverity() == Diagnostic.OK) && (oracleDef != null) && oracleDef.getNbExpectedErrors() > 0) { fail("Validation rule " + ruleID + " has not detected an error on object " + objectID + " while it must be the case"); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ } else { @@ -224,7 +232,7 @@ protected void assertExpectedRuleHasBeenThrown(Diagnostic diagnostic, EObject ob String ruleIdThrown = ((ConstraintStatusDiagnostic) nestedDiag).getConstraintStatus().getConstraint() .getDescriptor().getId(); assertEquals("Validation rule " + ruleIdThrown + " has detected an error but " + ruleID + " expected", - ruleIdThrown, ruleID); + ruleID, ruleIdThrown); } protected String getAirdURI(EObject object) { diff --git a/tests/plugins/org.polarsys.capella.test.validation.rules.ju/src/org/polarsys/capella/test/validation/rules/ju/testcases/misc/CheckAllRulesCodeTest.java b/tests/plugins/org.polarsys.capella.test.validation.rules.ju/src/org/polarsys/capella/test/validation/rules/ju/testcases/misc/CheckAllRulesCodeTest.java index e3f8db6c67..fcad50b0ff 100644 --- a/tests/plugins/org.polarsys.capella.test.validation.rules.ju/src/org/polarsys/capella/test/validation/rules/ju/testcases/misc/CheckAllRulesCodeTest.java +++ b/tests/plugins/org.polarsys.capella.test.validation.rules.ju/src/org/polarsys/capella/test/validation/rules/ju/testcases/misc/CheckAllRulesCodeTest.java @@ -16,21 +16,23 @@ import org.eclipse.emf.ecore.EClass; import org.eclipse.emf.ecore.EObject; +import org.eclipse.emf.validation.model.EvaluationMode; import org.eclipse.emf.validation.service.IBatchValidator; import org.eclipse.emf.validation.service.IConstraintDescriptor; import org.eclipse.emf.validation.service.IConstraintFilter; +import org.eclipse.emf.validation.service.ModelValidationService; import org.eclipse.osgi.util.NLS; import org.junit.Assert; import org.polarsys.capella.core.data.capellamodeller.Project; import org.polarsys.capella.core.libraries.model.CapellaModel; -import org.polarsys.capella.core.validation.CapellaValidationActivator; import org.polarsys.capella.core.validation.utils.ValidationHelper; import org.polarsys.capella.test.framework.api.OracleDefinition; import org.polarsys.capella.test.validation.rules.ju.testcases.ValidationRuleTestCase; /** * Check "code" of all constraints on a various enough model. - * This test apply each rules and check their state after operation. + * This test apply each rules and check their state after operation. + * */ public class CheckAllRulesCodeTest extends ValidationRuleTestCase { @@ -65,11 +67,13 @@ static public void checkIfConstraintIsInError(IConstraintDescriptor icd_p, Strin } @Override + // FIXME This doesn't execute disabled rules, also, why not validate just once?! + // FIXME public void test() throws Exception { CapellaModel model = getTestModel(getRequiredTestModel()); Project project = model.getProject(getSessionForTestModel(getRequiredTestModel()).getTransactionalEditingDomain()); if (project != null) { - IBatchValidator validator = CapellaValidationActivator.getDefault().getCapellaValidatorAdapter().getValidator(); + IBatchValidator validator = ModelValidationService.getInstance().newValidator(EvaluationMode.BATCH); for (final IConstraintDescriptor icd : ValidationHelper.getAllConstraintDescriptors()) { IConstraintFilter filter = new IConstraintFilter() { public boolean accept(IConstraintDescriptor constraint_p, EObject target_p) { diff --git a/tests/plugins/org.polarsys.capella.test.validation.rules.ju/src/org/polarsys/capella/test/validation/rules/ju/testcases/misc/NoDuplicateRuleIdsTest.java b/tests/plugins/org.polarsys.capella.test.validation.rules.ju/src/org/polarsys/capella/test/validation/rules/ju/testcases/misc/NoDuplicateRuleIdsTest.java index f3dbda939f..947d77c53b 100644 --- a/tests/plugins/org.polarsys.capella.test.validation.rules.ju/src/org/polarsys/capella/test/validation/rules/ju/testcases/misc/NoDuplicateRuleIdsTest.java +++ b/tests/plugins/org.polarsys.capella.test.validation.rules.ju/src/org/polarsys/capella/test/validation/rules/ju/testcases/misc/NoDuplicateRuleIdsTest.java @@ -24,6 +24,7 @@ import org.eclipse.emf.validation.internal.EMFModelValidationPlugin; import org.eclipse.emf.validation.internal.EMFModelValidationStatusCodes; import org.eclipse.emf.validation.service.IConstraintDescriptor; +import org.eclipse.emf.validation.service.ModelValidationService; import org.polarsys.capella.common.mdsofa.common.constant.ICommonConstants; import org.polarsys.capella.core.validation.ui.ide.internal.quickfix.CapellaQuickFixExtPointUtil; import org.polarsys.capella.core.validation.ui.ide.quickfix.AbstractCapellaMarkerResolution; @@ -67,10 +68,10 @@ public void logging(IStatus status_p, String plugin_p) { logged.add(status_p); } }); - + // force loading of constraint descriptors. - ValidationHelper.ensureEMFValidationActivation(); - + ModelValidationService.getInstance().loadXmlConstraintDeclarations(); + // EMF validation logs an error if it finds descriptors with the same ID. if (!logged.isEmpty()){ StringBuilder builder = new StringBuilder();