Skip to content

Commit e24e224

Browse files
adaussyAxelRICHARD
authored andcommitted
[1075] Fix ClassCastException while importing a model with name conflict
Bug: #1075 Signed-off-by: Arthur Daussy <arthur.daussy@obeo.fr>
1 parent e83c8e7 commit e24e224

File tree

7 files changed

+109
-479
lines changed

7 files changed

+109
-479
lines changed

CHANGELOG.adoc

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -17,8 +17,9 @@
1717

1818
=== Bug fixes
1919

20-
- https://github.com/eclipse-syson/syson/issues/870[#870] Fix an issue while computing the name of `VariantMembership`.
21-
- https://github.com/eclipse-syson/syson/issues/1083[#1083] Fix an issue where resolving against "unrestricted" name did not work
20+
- https://github.com/eclipse-syson/syson/issues/870[#870] [metamodel] Fix an issue while computing the name of `VariantMembership`.
21+
- https://github.com/eclipse-syson/syson/issues/1083[#1083] [metamodel] Fix an issue where resolving against "unrestricted" name did not work
22+
- https://github.com/eclipse-syson/syson/issues/1075[#1075] [import] Fix a ClassCastException thrown while importing a model with a name conflict.
2223

2324
=== Improvements
2425

backend/application/syson-application/src/test/java/org/eclipse/syson/application/imports/ImportSysMLModelTest.java

Lines changed: 90 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@
1414

1515
import static org.assertj.core.api.Assertions.assertThat;
1616
import static org.junit.Assert.assertNotNull;
17+
import static org.junit.Assert.assertNull;
1718
import static org.junit.jupiter.api.Assertions.assertEquals;
1819

1920
import java.io.IOException;
@@ -27,10 +28,14 @@
2728
import org.eclipse.syson.sysml.ConjugatedPortDefinition;
2829
import org.eclipse.syson.sysml.Feature;
2930
import org.eclipse.syson.sysml.Membership;
31+
import org.eclipse.syson.sysml.PartUsage;
3032
import org.eclipse.syson.sysml.PortDefinition;
3133
import org.eclipse.syson.sysml.PortUsage;
34+
import org.eclipse.syson.sysml.Redefinition;
3235
import org.eclipse.syson.sysml.ReferenceUsage;
36+
import org.eclipse.syson.sysml.Specialization;
3337
import org.eclipse.syson.sysml.SuccessionAsUsage;
38+
import org.eclipse.syson.sysml.Type;
3439
import org.eclipse.syson.sysml.helper.EMFUtils;
3540
import org.eclipse.syson.sysml.upload.SysMLExternalResourceLoaderService;
3641
import org.junit.jupiter.api.BeforeEach;
@@ -65,6 +70,91 @@ public void setUp() {
6570
this.checker = new SysMLv2SemanticImportChecker(this.sysmlResourceLoader, this.editingDomainFactory, this.sysMLEditingContextProcessor);
6671
}
6772

73+
@Test
74+
@DisplayName("Given a model with duplicated names, when importing the model, then the resolution of name shoud match the closest matching element")
75+
public void checkNameResolutionProcessWithDuplicatedName() throws IOException {
76+
var input = """
77+
package p1 {
78+
part pa1 {
79+
part pa11 :> pa1;
80+
part pa1;
81+
}
82+
}""";
83+
84+
this.checker.checkImportedModel(resource -> {
85+
PartUsage pa11 = EMFUtils.allContainedObjectOfType(resource, PartUsage.class)
86+
.filter(pa -> "pa11".equals(pa.getDeclaredName()))
87+
.findFirst().get();
88+
89+
assertThat(pa11.getOwnedSpecialization()).hasSize(1);
90+
91+
Specialization specialization = pa11.getOwnedSpecialization().get(0);
92+
93+
Type general = specialization.getGeneral();
94+
95+
assertNotNull(general);
96+
assertThat(general.getQualifiedName()).isEqualTo("p1::pa1::pa1"); // And not "p1::pa1"
97+
98+
}).check(input);
99+
}
100+
101+
@Test
102+
@DisplayName("Given a model with a Redefintion, when importing the model, then the resolution of name should special Redefinition rules")
103+
public void checkNameResolutionProcessInRedifinition() throws IOException {
104+
var input = """
105+
package p1 {
106+
part pa2 :> pa0 {
107+
part pa11 :>> pa1;
108+
}
109+
part pa0 {
110+
part pa1;
111+
}
112+
}""";
113+
114+
this.checker.checkImportedModel(resource -> {
115+
PartUsage pa11 = EMFUtils.allContainedObjectOfType(resource, PartUsage.class)
116+
.filter(pa -> "pa11".equals(pa.getDeclaredName()))
117+
.findFirst().get();
118+
119+
assertThat(pa11.getOwnedRedefinition()).hasSize(1);
120+
121+
Redefinition redefinition = pa11.getOwnedRedefinition().get(0);
122+
123+
Feature redefinedFeature = redefinition.getRedefinedFeature();
124+
125+
assertNotNull(redefinedFeature);
126+
assertThat(redefinedFeature.getQualifiedName()).isEqualTo("p1::pa0::pa1");
127+
128+
}).check(input);
129+
}
130+
131+
@Test
132+
@DisplayName("Given a model with a reference to an invalid type, when importing the model then the resolution of name shoud not set a reference with an incompatible target")
133+
public void checkNameResolutionProcessWithInvalidTargetName() throws IOException {
134+
var input = """
135+
package p1 {
136+
part pa1 {
137+
part pa11 :> pa1; // <-- 'pa1' resolve to the Package "pa1" in the current namespace. This model is not valid.
138+
package pa1;
139+
}
140+
}""";
141+
142+
this.checker.checkImportedModel(resource -> {
143+
PartUsage pa11 = EMFUtils.allContainedObjectOfType(resource, PartUsage.class)
144+
.filter(pa -> "pa11".equals(pa.getDeclaredName()))
145+
.findFirst().get();
146+
147+
assertThat(pa11.getOwnedSpecialization()).hasSize(1);
148+
149+
Specialization specialization = pa11.getOwnedSpecialization().get(0);
150+
151+
Type general = specialization.getGeneral();
152+
153+
assertNull(general);
154+
155+
}).check(input);
156+
}
157+
68158
@Test
69159
@DisplayName("Given a model with PortDefinitions, when importing the model, then a conjugated port is create for each conjugated ports")
70160
public void checkConjugatedPortCreation() throws IOException {

backend/application/syson-sysml-import/src/main/java/org/eclipse/syson/sysml/parser/ProxyResolver.java

Lines changed: 15 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*******************************************************************************
2-
* Copyright (c) 2024 Obeo.
2+
* Copyright (c) 2024, 2025 Obeo.
33
* This program and the accompanying materials
44
* are made available under the terms of the Eclipse Public License v2.0
55
* which accompanies this distribution, and is available at
@@ -72,18 +72,9 @@ public boolean resolveProxy(final ProxiedReference proxiedReference) {
7272
proxiedReference.owner().eSet(proxiedReference.reference(), resultCollection);
7373
}
7474
} else {
75-
// Manage specific case of conjugated port
76-
if (proxiedReference.owner() instanceof ConjugatedPortTyping && realElement instanceof PortDefinition elementPortDefinition) {
77-
realElement = elementPortDefinition.getConjugatedPortDefinition();
78-
}
7975
proxiedReference.owner().eSet(proxiedReference.reference(), realElement);
80-
if (realElement != null) {
81-
LOGGER.debug("Set the reference {} of object {} with the resolved proxy {} to target {}", proxiedReference.reference().getName(), proxiedReference.owner(),
82-
proxiedReference.targetProxy().eProxyURI().fragment(), realElement);
83-
} else {
84-
LOGGER.debug("Unable to set the reference {} of object {} because of the unresolved proxy {}.", proxiedReference.reference().getName(), proxiedReference.owner(),
85-
proxiedReference.targetProxy().eProxyURI().fragment());
86-
}
76+
LOGGER.debug("Set the reference {} of object {} with the resolved proxy {} to target {}", proxiedReference.reference().getName(), proxiedReference.owner(),
77+
proxiedReference.targetProxy().eProxyURI().fragment(), realElement);
8778
}
8879
return true;
8980
}
@@ -108,13 +99,24 @@ private EObject findProxyTarget(final EObject owner, final InternalEObject proxy
10899
if (membership != null) {
109100
if (SysmlPackage.eINSTANCE.getMembership().isSuperTypeOf(proxyObject.eClass())) {
110101
target = membership;
111-
} else {
102+
} else if (eReference.getEType().isInstance(membership.getMemberElement())) {
112103
target = membership.getMemberElement();
104+
} else if (this.isConjufatedPortReference(owner, membership.getMemberElement())) {
105+
// Manage specific case of conjugated port
106+
target = ((PortDefinition) membership.getMemberElement()).getConjugatedPortDefinition();
113107
}
114108
}
109+
// Return the first matching element
110+
if (target != null) {
111+
return target;
112+
}
115113
}
116114
}
117115

118116
return target;
119117
}
118+
119+
private boolean isConjufatedPortReference(final EObject owner, final Element target) {
120+
return owner instanceof ConjugatedPortTyping && target instanceof PortDefinition elementPortDefinition;
121+
}
120122
}

backend/application/syson-sysml-import/src/test/java/org/eclipse/syson/sysml/ASTTransformerTest.java

Lines changed: 0 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -419,38 +419,6 @@ void nonUniqueFeatureTest() {
419419

420420
}
421421

422-
@DisplayName("Test Conjugated")
423-
@Test
424-
void convertConjugatedPortTest() {
425-
Resource testResource = this.getResourceFromFile("ASTTransformerTest/convertConjugatedPortTest/conjugatedPort.ast.json", true);
426-
assertNotNull(testResource);
427-
428-
Namespace namespace = (Namespace) testResource.getContents().get(0);
429-
Package packageObject = (Package) namespace.getMember().get(0);
430-
431-
AttributeDefinition tempAttributeDefinition = (AttributeDefinition) packageObject.getMember().get(0);
432-
assertEquals("Temp", tempAttributeDefinition.getName());
433-
434-
PortDefinition tempPortPortDefinition = (PortDefinition) packageObject.getMember().get(1);
435-
assertEquals("TempPort", tempPortPortDefinition.getName());
436-
AttributeUsage temperatureAttributeUsage = tempPortPortDefinition.getOwnedAttribute().get(0);
437-
assertEquals("temperature", temperatureAttributeUsage.getName());
438-
assertEquals(tempAttributeDefinition, temperatureAttributeUsage.getOwnedSpecialization().get(0).getGeneral());
439-
440-
PartDefinition tempPortClassicPartDefinition = (PartDefinition) packageObject.getMember().get(2);
441-
assertEquals("TempPortClassic", tempPortClassicPartDefinition.getName());
442-
PortUsage tempPortClassicPortUsage = tempPortClassicPartDefinition.getOwnedPort().get(0);
443-
assertEquals("tempPortClassic", tempPortClassicPortUsage.getName());
444-
assertEquals(tempPortPortDefinition, tempPortClassicPortUsage.getOwnedSpecialization().get(0).getGeneral());
445-
446-
PartDefinition tempPortConjPartDefinition = (PartDefinition) packageObject.getMember().get(3);
447-
assertEquals("TempPortConj", tempPortConjPartDefinition.getName());
448-
PortUsage tempPortConjPortUsage = tempPortConjPartDefinition.getOwnedPort().get(0);
449-
assertEquals("tempPortConj", tempPortConjPortUsage.getName());
450-
451-
assertEquals(1, tempPortConjPortUsage.getOwnedTyping().size());
452-
}
453-
454422
@DisplayName("Test Subclassification")
455423
@Test
456424
void convertSubclassificationTest() {

0 commit comments

Comments
 (0)