Skip to content

Commit

Permalink
[1673] Detect illegal inter model references in validation rule
Browse files Browse the repository at this point in the history
This replaces the
"ResourceSetListenerForInterModelInconsistencyDetection" with a new live
validation rule I_39.

The preference "Prevent on the fly inter-model dependency violation"
from the Model tab has been removed.

Change-Id: I1f7fb096f589f9dcda346363a390b7b30461c0bb
Signed-off-by: Felix Dorner <felix.dorner@gmail.com>
  • Loading branch information
felixdo committed Mar 21, 2018
1 parent 66349b4 commit 1e61787
Show file tree
Hide file tree
Showing 22 changed files with 463 additions and 352 deletions.
@@ -1,10 +1,10 @@
/*******************************************************************************
* Copyright (c) 2006, 2017 THALES GLOBAL SERVICES.
* Copyright (c) 2006, 2018 THALES GLOBAL SERVICES.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/epl-v10.html
*
*
* Contributors:
* Thales - initial API and implementation
*******************************************************************************/
Expand Down Expand Up @@ -39,13 +39,9 @@ public class Messages extends NLS {
public static String SyncPreferencePage_SyncPhysicalPort2FunctionPortOnPhysicalLinkAllowed_Title;
public static String SyncPreferencePage_SyncPhysicalPort2FunctionPortOnPhysicalPathAllowed_Title;

public static String interModelIntegrity_Group_Title;

public static String interModelIntegrity_PreventInterModelDependencyViolation_Title;

public static String ModeAndState_Group_Title;
public static String ModeAndState_MixedHierarchy_Title;

public static String PhysicalComponenentProperties_Group_Title;
public static String PhysicalComponenentNatureChange_Title;

Expand Down
@@ -1,10 +1,10 @@
/*******************************************************************************
* Copyright (c) 2006, 2017 THALES GLOBAL SERVICES.
* Copyright (c) 2006, 2018 THALES GLOBAL SERVICES.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/epl-v10.html
*
*
* Contributors:
* Thales - initial API and implementation
*******************************************************************************/
Expand All @@ -21,7 +21,6 @@
import org.polarsys.capella.core.model.preferences.IDataPreferences;
import org.polarsys.capella.core.model.preferences.IDeploymentPreferences;
import org.polarsys.capella.core.model.preferences.IInheritancePreferences;
import org.polarsys.capella.core.model.preferences.IInterModelIntegrityPreferences;
import org.polarsys.capella.core.model.preferences.IModeAndStateManagementPreferences;
import org.polarsys.capella.core.model.preferences.IReuseComponentsPreferences;
import org.polarsys.capella.core.model.preferences.ISynchronizationPreferences;
Expand All @@ -34,7 +33,7 @@ public class ModelPreferencePage extends AbstractDefaultPreferencePage {
public static final String PROPERTY_PAGE_ID = "org.polarsys.capella.common.ui.resources.prefs.property.modelPage"; //$NON-NLS-1$

/**
*
*
*/
public ModelPreferencePage() {
super(PROPERTY_PAGE_ID);
Expand Down Expand Up @@ -78,7 +77,7 @@ protected void createFieldEditors() {
ProjectScope.class);

addField(new SpacerFieldEditor(fieldEditorParent));

Group group1 = createGroup(Messages.InheritancePreferencePage_Group_Title,
Messages.InheritancePreferencePage_Group_Title, fieldEditorParent);
addField(new PreferenceField(IInheritancePreferences.PREFS_ALLOW_MULTIPLE_INHERITANCE,
Expand All @@ -89,23 +88,23 @@ protected void createFieldEditors() {
ProjectScope.class);

addField(new SpacerFieldEditor(fieldEditorParent));

Group group2 = createGroup(Messages.DeploymentPreferencePage_Group_Title,
Messages.DeploymentPreferencePage_Group_Title, fieldEditorParent);
addField(new PreferenceField(IDeploymentPreferences.PREFS_ALLOW_MULTIPLE_DEPLOYMENT,
Messages.DeploymentPreferencePage_Allowed_Title, group2), UserProfileModeEnum.Expert, group2,
ProjectScope.class);

addField(new SpacerFieldEditor(fieldEditorParent));

Group group3 = createGroup(Messages.DataPreferencePage_Group_Title, Messages.DataPreferencePage_Group_Title,
fieldEditorParent);
addField(new PreferenceField(IDataPreferences.PREFS_ALLOW_PRIMITIVE_SYNCHRONIZATION,
Messages.DataPreferencePage_PrimitiveSynchroAllowed_Title, group3), UserProfileModeEnum.Expert, group3,
ProjectScope.class);

addField(new SpacerFieldEditor(fieldEditorParent));

Group group4 = createGroup(Messages.SyncPreferencePage_Group_Title, Messages.SyncPreferencePage_Group_Title,
fieldEditorParent);
addField(new PreferenceField(ISynchronizationPreferences.PREFS_ALLOW_SYNC_COMPONENTPORT_TO_FUNCTIONPORT,
Expand All @@ -121,21 +120,13 @@ protected void createFieldEditors() {
UserProfileModeEnum.Expert, group4, ProjectScope.class);

addField(new SpacerFieldEditor(fieldEditorParent));

Group group5 = createGroup(Messages.interModelIntegrity_Group_Title, Messages.interModelIntegrity_Group_Title,
fieldEditorParent);
addField(new PreferenceField(IInterModelIntegrityPreferences.PREFS_PREVENT_ON_THE_FLY_DEPENDENCY_VIOLATION,
Messages.interModelIntegrity_PreventInterModelDependencyViolation_Title, group5), UserProfileModeEnum.Expert,
group5, ProjectScope.class);

addField(new SpacerFieldEditor(fieldEditorParent));

Group group6 = createGroup(Messages.ModeAndState_Group_Title, Messages.ModeAndState_Group_Title, fieldEditorParent);
addField(new PreferenceField(IModeAndStateManagementPreferences.PREFS_MIXED_MODE_STATE_ALLOWED,
Messages.ModeAndState_MixedHierarchy_Title, group6), UserProfileModeEnum.Expert, group6, ProjectScope.class);

addField(new SpacerFieldEditor(fieldEditorParent));

Group group7 = createGroup(Messages.PhysicalComponenentProperties_Group_Title, Messages.PhysicalComponenentProperties_Group_Title, fieldEditorParent);
addField(new PreferenceField(IDataPreferences.PREFS_ALLOW_PHYSICAL_COMPONENT_NATURE_CHANGE,
Messages.PhysicalComponenentNatureChange_Title, group7), UserProfileModeEnum.Expert, group7, ProjectScope.class);
Expand Down
@@ -1,5 +1,5 @@
#===============================================================================
# Copyright (c) 2006, 2017 THALES GLOBAL SERVICES.
# Copyright (c) 2006, 2018 THALES GLOBAL SERVICES.
# All rights reserved. This program and the accompanying materials
# are made available under the terms of the Eclipse Public License v1.0
# which accompanies this distribution, and is available at
Expand Down Expand Up @@ -30,9 +30,6 @@ SyncPreferencePage_SyncComponentPort2FunctionPortAllowed_Title=Synchronize Compo
SyncPreferencePage_SyncPhysicalPort2FunctionPortOnPhysicalLinkAllowed_Title=Synchronize Physical Port to Component Port delegation when allocating Component Exchanges to Physical Links
SyncPreferencePage_SyncPhysicalPort2FunctionPortOnPhysicalPathAllowed_Title=Synchronize Physical Port to Component Port delegation when allocating Component Exchanges to Physical Paths

interModelIntegrity_Group_Title=Inter-model integrity
interModelIntegrity_PreventInterModelDependencyViolation_Title=Prevent on the fly inter-model dependency violation (notice that performances may be impacted)

ModeAndState_Group_Title=Modes and States Management
ModeAndState_MixedHierarchy_Title=Mode/State mixed hierarchy allowed

Expand Down
@@ -1,7 +1,7 @@
<?xml version="1.0" encoding="UTF-8"?>
<?eclipse version="3.2"?>
<!--
Copyright (c) 2006, 2017 THALES GLOBAL SERVICES.
Copyright (c) 2006, 2018 THALES GLOBAL SERVICES.
All rights reserved. This program and the accompanying materials
are made available under the terms of the Eclipse Public License v1.0
which accompanies this distribution, and is available at
Expand Down Expand Up @@ -394,6 +394,25 @@ This rule checks that an capella element doesn&apos;t contain any naming conflic
class="CapellaElement">
</target>
</constraint>
<constraint
class="org.polarsys.capella.core.data.core.validation.constraint.InterModelConsistencyValidationRule"
id="I_39"
isEnabledByDefault="true"
lang="Java"
mode="Live"
name="I_39 - Validate inter-model references"
severity="ERROR"
statusCode="1">
<message>
''{0}'' in model ''{1}'' cannot reference ''{2}'' in model ''{3}'' via ''{4}''
</message>
<description>
An element in model A can only reference an element in model B if A has declared a "Library Reference" to B.
</description>
<target
class="CapellaElement">
</target>
</constraint>
</constraints>
</constraintProvider>
<constraintProvider>
Expand Down
@@ -0,0 +1,105 @@
/*******************************************************************************
* Copyright (c) 2006, 2018 THALES GLOBAL SERVICES.
* All rights reserved. This program and the accompanying materiTals
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/epl-v10.html
*
* Contributors:
* Thales - initial API and implementation
*******************************************************************************/
package org.polarsys.capella.core.data.core.validation.constraint;

import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;

import org.eclipse.core.runtime.IStatus;
import org.eclipse.emf.common.notify.Notification;
import org.eclipse.emf.ecore.EObject;
import org.eclipse.emf.ecore.EReference;
import org.eclipse.emf.transaction.TransactionalEditingDomain;
import org.eclipse.emf.transaction.util.TransactionUtil;
import org.eclipse.emf.validation.EMFEventType;
import org.eclipse.emf.validation.IValidationContext;
import org.eclipse.emf.validation.model.ConstraintStatus;
import org.polarsys.capella.common.libraries.ILibraryManager;
import org.polarsys.capella.common.platform.sirius.ted.SemanticEditingDomainFactory.SemanticEditingDomain;
import org.polarsys.capella.core.model.handler.command.CapellaResourceHelper;
import org.polarsys.capella.core.model.helpers.intermodelInconsistencyDetection.DependencyChecker;
import org.polarsys.capella.core.model.helpers.intermodelInconsistencyDetection.DependencyViolation;
import org.polarsys.capella.core.validation.rule.AbstractValidationRule;

/**
* An element in model A can only reference an element in model B if there is a LibraryReference
* from A to B. This live validation rule finds references that violate this restriction.
*/
public class InterModelConsistencyValidationRule extends AbstractValidationRule {

@Override
public IStatus validate(IValidationContext ctx) {

DependencyChecker linkChecker = null;

if (ctx.getEventType() == EMFEventType.NULL) {
return ctx.createSuccessStatus();
}

for (Notification n : ctx.getAllEvents()) {

if (n.getNotifier() instanceof EObject) {
// make sure this rule is evaluated only once per transaction
ctx.skipCurrentConstraintFor((EObject) n.getNotifier());
if (CapellaResourceHelper.isSemanticElement(n.getNotifier())) {
if (linkChecker == null) {
TransactionalEditingDomain domain = TransactionUtil.getEditingDomain(n.getNotifier());
if (domain instanceof SemanticEditingDomain) {
linkChecker = new DependencyChecker((SemanticEditingDomain) domain);
} else {
continue;
}
}

if (n.getFeature() instanceof EReference) {
EReference ref = (EReference) n.getFeature();
Collection<EObject> check = Collections.emptyList();
if (n.getEventType() == Notification.SET || n.getEventType() == Notification.ADD) {
EObject newValue = (EObject) n.getNewValue();
if (newValue != null) {
check = Collections.singleton(newValue);
}
} else if (n.getEventType() == Notification.ADD_MANY) {
check = ((Collection<EObject>)n.getNewValue());
}
if (ref.isContainment()) {
for (EObject e : check) {
linkChecker.checkAllLinks(e);
}
} else {
for (EObject e : check) {
linkChecker.checkLink((EObject) n.getNotifier(), e, ref);
}
}
}
}
}
}

if (linkChecker != null && linkChecker.getDependencyViolations().size() > 0) {
Collection<IStatus> children = new ArrayList<IStatus>();
for (DependencyViolation v : linkChecker.getDependencyViolations()) {
Object[] args = new Object[] {
v.getSource(),
ILibraryManager.INSTANCE.getModel(v.getSource()).getIdentifier().getName(),
v.getTarget(),
ILibraryManager.INSTANCE.getModel(v.getTarget()).getIdentifier().getName(),
v.getEReference()
};
children.add(ctx.createFailureStatus(args));
}
return ConstraintStatus.createMultiStatus(ctx, children);
}

return ctx.createSuccessStatus();
}
}
Expand Up @@ -13,7 +13,6 @@ Require-Bundle: org.polarsys.capella.common.flexibility.properties,
Bundle-RequiredExecutionEnvironment: JavaSE-1.7
Bundle-ActivationPolicy: lazy
Export-Package: org.polarsys.capella.core.libraries,
org.polarsys.capella.core.libraries.interModelInconsistencyDetection,
org.polarsys.capella.core.libraries.model,
org.polarsys.capella.core.libraries.nature,
org.polarsys.capella.core.libraries.properties,
Expand Down
8 changes: 1 addition & 7 deletions core/plugins/org.polarsys.capella.core.libraries/plugin.xml
@@ -1,7 +1,7 @@
<?xml version="1.0" encoding="UTF-8"?>
<?eclipse version="3.4"?>
<!--
Copyright (c) 2006, 2014 THALES GLOBAL SERVICES.
Copyright (c) 2006, 2018 THALES GLOBAL SERVICES.
All rights reserved. This program and the accompanying materials
are made available under the terms of the Eclipse Public License v1.0
which accompanies this distribution, and is available at
Expand Down Expand Up @@ -91,11 +91,5 @@
</derivedSemanticResourceProvider>
</extension>

<extension
point="org.eclipse.sirius.sessionManagerListener">
<listener
class="org.polarsys.capella.core.libraries.interModelInconsistencyDetection.CapellaSessionListenerForInterModelInconsistencyDetection">
</listener>
</extension>

</plugin>

This file was deleted.

0 comments on commit 1e61787

Please sign in to comment.