Skip to content

Commit

Permalink
Merge pull request #557 from Systems-Modeling/ST6RI-762
Browse files Browse the repository at this point in the history
ST6RI-762: %viz command causes ConcurrentModificationException
  • Loading branch information
seidewitz authored Apr 11, 2024
2 parents 84996a6 + 69bf624 commit 56d19ff
Show file tree
Hide file tree
Showing 9 changed files with 40 additions and 17 deletions.
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
/*****************************************************************************
* SysML 2 Pilot Implementation, PlantUML Visualization
* Copyright (c) 2022-2023 Mgnite Inc.
* Copyright (c) 2022-2024 Mgnite Inc.
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
/*****************************************************************************
* SysML 2 Pilot Implementation, PlantUML Visualization
* Copyright (c) 2020-2023 Mgnite Inc.
* Copyright (c) 2020-2024 Mgnite Inc.
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -128,7 +128,7 @@ public String caseSuccession(Succession su) {
private boolean resolveReference(Feature f, ActionUsage au, boolean send) {
if (!(f instanceof ReferenceUsage)) return false;
boolean flag = true;
for (Membership m: f.getOwnedMembership()) {
for (Membership m: toOwnedMembershipArray(f)) {
if (m instanceof FeatureValue) {
FeatureValue fv = (FeatureValue) m;
Expression e = fv.getValue();
Expand Down Expand Up @@ -235,7 +235,7 @@ private String convertToDescription(TransitionUsage tu) {
String guardString = null;
String effectString = null;

for (FeatureMembership fm: tu.getOwnedFeatureMembership()) {
for (FeatureMembership fm: toOwnedFeatureMembershipArray(tu)) {
if (!(fm instanceof TransitionFeatureMembership)) continue;
TransitionFeatureMembership tfm = (TransitionFeatureMembership) fm;
Step s = tfm.getTransitionFeature();
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
/*****************************************************************************
* SysML 2 Pilot Implementation, PlantUML Visualization
* Copyright (c) 2020-2023 Mgnite Inc.
* Copyright (c) 2020-2024 Mgnite Inc.
* Copyright (c) 2021-2023 Model Driven Solutions, Inc.
*
* This program is free software: you can redistribute it and/or modify
Expand Down Expand Up @@ -203,7 +203,7 @@ private class CompTree {
private final CompartmentEntry parent;

public void process(Feature f) {
for (Membership m: f.getOwnedMembership()) {
for (Membership m: toOwnedMembershipArray(f)) {
Element e = m.getMemberElement();
if (e instanceof Expression) {
// Do not show it
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
/*****************************************************************************
* SysML 2 Pilot Implementation, PlantUML Visualization
* Copyright (c) 2020-2023 Mgnite Inc.
* Copyright (c) 2020-2024 Mgnite Inc.
* Copyright (c) 2020-2023 Model Driven Solutions, Inc.
*
* This program is free software: you can redistribute it and/or modify
Expand Down Expand Up @@ -263,7 +263,7 @@ public String caseDependency(Dependency dep) {
}

protected static boolean isEmptyFeature(Feature f) {
for (FeatureMembership fm: f.getOwnedFeatureMembership()) {
for (FeatureMembership fm: toOwnedFeatureMembershipArray(f)) {
if (fm.getOwnedMemberFeature() instanceof BindingConnector) continue;
return false;
}
Expand All @@ -272,7 +272,7 @@ protected static boolean isEmptyFeature(Feature f) {

protected Relationship findBindingLikeRel(Feature f) {
Relationship ret = null;
for (Relationship rel : f.getOwnedRelationship()) {
for (Relationship rel : toOwnedRelationshipArray(f)) {
if (rel instanceof FeatureValue) {
// first priority
return rel;
Expand Down
4 changes: 2 additions & 2 deletions org.omg.sysml.plantuml/src/org/omg/sysml/plantuml/VPath.java
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
/*****************************************************************************
* SysML 2 Pilot Implementation, PlantUML Visualization
* Copyright (c) 2020-2023 Mgnite Inc.
* Copyright (c) 2020-2024 Mgnite Inc.
* Copyright (c) 2022 Model Driven Solutions, Inc.
*
* This program is free software: you can redistribute it and/or modify
Expand Down Expand Up @@ -306,7 +306,7 @@ private InheritKey makeInheritKeyOfOwner(Feature f) {
}
*/
private static Feature getIOTarget(ItemFlowEnd ife) {
for (FeatureMembership fm: ife.getOwnedFeatureMembership()) {
for (FeatureMembership fm: toOwnedFeatureMembershipArray(ife)) {
Feature f = fm.getOwnedMemberFeature();
for (Redefinition rd: f.getOwnedRedefinition()) {
return rd.getRedefinedFeature();
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
/*****************************************************************************
* SysML 2 Pilot Implementation, PlantUML Visualization
* Copyright (c) 2020-2023 Mgnite Inc.
* Copyright (c) 2020-2024 Mgnite Inc.
* Copyright (c) 2021-2023 Model Driven Solutions, Inc.
*
* This program is free software: you can redistribute it and/or modify
Expand Down Expand Up @@ -140,7 +140,7 @@ protected boolean appendFeatureValue(FeatureValue fv) {

private boolean addFeatureMembershipText(Feature f) {
boolean flag = false;
for (Membership m: f.getOwnedMembership()) {
for (Membership m: toOwnedMembershipArray(f)) {
if (m instanceof FeatureValue) {
return appendFeatureValue((FeatureValue) m);
} else if (m instanceof ResultExpressionMembership) {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
/*****************************************************************************
* SysML 2 Pilot Implementation, PlantUML Visualization
* Copyright (c) 2020-2023 Mgnite Inc.
* Copyright (c) 2020-2024 Mgnite Inc.
* Copyright (c) 2022 Model Driven Solutions, Inc.
*
* This program is free software: you can redistribute it and/or modify
Expand Down Expand Up @@ -84,15 +84,15 @@ private static boolean isModelLibrary(Element e) {
}

private void traverseInternal(Namespace n, Set<Element> covered) {
for (Relationship r: n.getOwnedRelationship()) {
for (Relationship r: toOwnedRelationshipArray(n)) {
if (r instanceof Membership) {
Membership ms = (Membership) r;
setInherited(false);
Element e = ms.getMemberElement();
markRedefining(e, covered);
this.currentMembership = ms;
visit(ms);
for (Relationship r2: ms.getOwnedRelationship()) {
for (Relationship r2: toOwnedRelationshipArray(ms)) {
setInherited(false);
visit(r2);
}
Expand Down
25 changes: 24 additions & 1 deletion org.omg.sysml.plantuml/src/org/omg/sysml/plantuml/Visitor.java
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
/*****************************************************************************
* SysML 2 Pilot Implementation, PlantUML Visualization
* Copyright (c) 2020-2023 Mgnite Inc.
* Copyright (c) 2020-2024 Mgnite Inc.
* Copyright (c) 2023 Model Driven Solutions, Inc.
*
* This program is free software: you can redistribute it and/or modify
Expand Down Expand Up @@ -36,13 +36,15 @@
import org.omg.sysml.lang.sysml.Element;
import org.omg.sysml.lang.sysml.Feature;
import org.omg.sysml.lang.sysml.FeatureChaining;
import org.omg.sysml.lang.sysml.FeatureMembership;
import org.omg.sysml.lang.sysml.FeatureTyping;
import org.omg.sysml.lang.sysml.Membership;
import org.omg.sysml.lang.sysml.Multiplicity;
import org.omg.sysml.lang.sysml.MultiplicityRange;
import org.omg.sysml.lang.sysml.Namespace;
import org.omg.sysml.lang.sysml.Redefinition;
import org.omg.sysml.lang.sysml.ReferenceSubsetting;
import org.omg.sysml.lang.sysml.Relationship;
import org.omg.sysml.lang.sysml.Subsetting;
import org.omg.sysml.lang.sysml.Type;
import org.omg.sysml.lang.sysml.util.SysMLSwitch;
Expand Down Expand Up @@ -748,4 +750,25 @@ public String visit(Element e) {
s2p.countVisits();
return doSwitch(e);
}

// Accessing relationships may cause ConcurrentModificationException over iterators
// because it may trigger "on-demand" transformation. So we introduce utility methods
// to copy them into an array.
public static Relationship[] toOwnedRelationshipArray(Element e) {
List<Relationship> rels = e.getOwnedRelationship();
Relationship[] array = new Relationship[rels.size()];
return rels.toArray(array);
}

public static Membership[] toOwnedMembershipArray(Namespace ns) {
List<Membership> ms = ns.getOwnedMembership();
Membership[] array = new Membership[ms.size()];
return ms.toArray(array);
}

public static FeatureMembership[] toOwnedFeatureMembershipArray(Feature f) {
List<FeatureMembership> fms = f.getOwnedFeatureMembership();
FeatureMembership[] array = new FeatureMembership[fms.size()];
return fms.toArray(array);
}
}

0 comments on commit 56d19ff

Please sign in to comment.