Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -21,12 +21,12 @@
package org.omg.sysml.adapter;

import org.eclipse.emf.ecore.EObject;
import org.omg.sysml.lang.sysml.FeatureMembership;
import org.omg.sysml.lang.sysml.PartDefinition;
import org.omg.sysml.lang.sysml.PartUsage;
import org.omg.sysml.lang.sysml.PortDefinition;
import org.omg.sysml.lang.sysml.PortUsage;
import org.omg.sysml.lang.sysml.Type;
import org.omg.sysml.util.UsageUtil;

public class PortUsageAdapter extends UsageAdapter {

Expand All @@ -44,12 +44,9 @@ public PortUsage getTarget() {
public void postProcess() {
super.postProcess();
PortUsage target = getTarget();
EObject container = target.eContainer();
if (container instanceof FeatureMembership) {
Type owningType = ((FeatureMembership)container).getOwningType();
if (!(owningType instanceof PortDefinition || owningType instanceof PortUsage)) {
target.setIsComposite(false);
}
EObject featuringType = UsageUtil.getExpectedFeaturingTypeOf(target);
if (!(featuringType instanceof PortDefinition || featuringType instanceof PortUsage)) {
target.setIsComposite(false);
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -62,9 +62,7 @@ public void postProcess () {
if (target.isVariation()) {
target.setIsAbstract(true);
}
if (target.getDirection() != null || target.isEnd() ||
// Note: A parsed Usage can only get a featuring type if it is owned via a FeatureMembership.
!(target.eContainer() instanceof FeatureMembership)) {
if (target.getDirection() != null || target.isEnd() || !UsageUtil.hasFeaturingType(target)) {
target.setIsComposite(false);
}
}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
/*******************************************************************************
* SysML 2 Pilot Implementation
* Copyright (c) 2021-2025 Model Driven Solutions, Inc.
* Copyright (c) 2021-2026 Model Driven Solutions, Inc.
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the Eclipse Public License as published by
Expand All @@ -26,6 +26,7 @@

import org.eclipse.emf.common.util.BasicEList;
import org.eclipse.emf.common.util.EList;
import org.eclipse.emf.ecore.EObject;
import org.omg.sysml.adapter.UsageAdapter;
import org.omg.sysml.lang.sysml.AcceptActionUsage;
import org.omg.sysml.lang.sysml.ActionUsage;
Expand Down Expand Up @@ -90,6 +91,33 @@ public static boolean mayTimeVary(Usage usage) {
return getUsageAdapter(usage).mayTimeVary();
}

// Featuring Types

/**
* Determine the featuringType a Usage is expected to have after transformation,
* without actually computing the full derivation for featuringType. Assumes that
* a Usage in SysML can only get a featuringType in one of two ways:
* 1. If it is an ownedFeature.
* 2. If it is a variant of a variation Usage that has a featuringType.
* Note that the special featuringTypes of variable features are ignored.
*/
public static Type getExpectedFeaturingTypeOf(Usage usage) {
EObject container = usage.eContainer();
if (container instanceof FeatureMembership featureMembership) {
return featureMembership.getOwningType();
} else if (container != null &&
Comment thread
AxelRICHARD marked this conversation as resolved.
container.eContainer() instanceof Usage containingUsage &&
containingUsage.isVariation()) {
return getExpectedFeaturingTypeOf(containingUsage);
} else {
return null;
}
}

public static boolean hasFeaturingType(Usage usage) {
return getExpectedFeaturingTypeOf(usage) != null;
}

// Variants

public static boolean isVariant(Usage usage) {
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,138 @@
/*******************************************************************************
* SysML 2 Pilot Implementation
* Copyright (c) 2026 Model Driven Solutions, Inc.
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the Eclipse Public License as published by
* the Eclipse Foundation, version 2 of the License.
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* Eclipse Public License for more details.
*
* You should have received a copy of theEclipse Public License
* along with this program. If not, see <https://www.eclipse.org/legal/epl-2.0/>.
*
* @license EPL-2.0 <http://spdx.org/licenses/EPL-2.0>
*
*******************************************************************************/
package org.omg.sysml.logic;

import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertTrue;

import java.lang.reflect.InvocationTargetException;

import org.eclipse.emf.ecore.EClass;
import org.junit.BeforeClass;
import org.junit.Test;
import org.omg.sysml.lang.sysml.Element;
import org.omg.sysml.lang.sysml.FeatureDirectionKind;
import org.omg.sysml.lang.sysml.Namespace;
import org.omg.sysml.lang.sysml.Package;
import org.omg.sysml.lang.sysml.SysMLFactory;
import org.omg.sysml.lang.sysml.SysMLPackage;
import org.omg.sysml.lang.sysml.Usage;
import org.omg.sysml.lang.sysml.VariantMembership;
import org.omg.sysml.util.ElementUtil;
import org.omg.sysml.util.NamespaceUtil;
import org.omg.sysml.util.TypeUtil;

public class UsagePostProcessTest {

@BeforeClass
public static void setUp() {
SysMLLogicStandaloneSetup.doSetup();
SysMLPackage.eINSTANCE.eClass();
}

/**
* Test that Usage.postProcess sets the property "composite" to false in appropriate cases.
* @throws InvocationTargetException
*/
@Test
public void settingCompositeToFalse() throws InvocationTargetException {
/*
* package Test {\n"
* part p {
* attribute a;
* part x;
* in part y
* variation part z {
* variant variation part u {
* variant part v;
* }
* variant port w;
* }
* }
* variation part q {
* variant part r;
* }
* }
*/
Package test = (Package) createElement(SysMLPackage.Literals.PACKAGE, "test", null);
Usage p = (Usage) createElement(SysMLPackage.Literals.PART_USAGE, "p", test);
Usage a = (Usage) createElement(SysMLPackage.Literals.ATTRIBUTE_USAGE, "a", p);
Usage x = (Usage) createElement(SysMLPackage.Literals.PART_USAGE, "x", p);
Usage y = (Usage) createElement(SysMLPackage.Literals.PART_USAGE, "y", p);
y.setDirection(FeatureDirectionKind.IN);
Usage z = (Usage) createElement(SysMLPackage.Literals.PART_USAGE, "z", p);
z.setIsVariation(true);
Usage u = (Usage) createElement(SysMLPackage.Literals.PART_USAGE, "u", z);
u.setIsVariation(true);
Usage v = (Usage) createElement(SysMLPackage.Literals.PART_USAGE, "v", u);
Usage w = (Usage) createElement(SysMLPackage.Literals.PORT_USAGE, "w", u);
Usage q = (Usage) createElement(SysMLPackage.Literals.PART_USAGE, "q", test);
q.setIsVariation(true);
Usage r = (Usage) createElement(SysMLPackage.Literals.PART_USAGE, "r", q);

// Post-process after creating the entire model.
postProcess(p, a, x, y, z, u, v, w, q, r);

assertTrue(p.isReference());
assertTrue(a.isReference());
assertFalse(x.isReference());
assertTrue(y.isReference());
assertFalse(z.isReference());
assertFalse(u.isReference());
assertFalse(v.isReference());
assertTrue(w.isReference());
assertTrue(q.isReference());
assertTrue(r.isReference());
}

/**
* Create an Element with the given eClass, name and parent. If the created Element and the parent
* are both Usages, then the Element is added to the parent as a variant, if the parent is a variation,
* or as an ownedFeature, if the parent is not a variation. Otherwise, the Element is added as an
* ownedMember of the parent. (Adding ownedFeatures of Definitions is not currently needed.)
*/
protected static Element createElement(EClass eClass, String name, Namespace parent) {
Element element = (Element)SysMLFactory.eINSTANCE.create(eClass);
element.setDeclaredName(name);
if (element instanceof Usage usage && parent instanceof Usage parentUsage) {
if (parentUsage.isVariation()) {
VariantMembership membership = SysMLFactory.eINSTANCE.createVariantMembership();
membership.setOwnedVariantUsage(usage);
parentUsage.getOwnedRelationship().add(membership);
} else {
TypeUtil.addOwnedFeatureTo(parentUsage, usage);
}
} else if (parent != null) {
NamespaceUtil.addOwnedMemberTo(parent, element);
}
return element;
}

/**
* Call the postProcess method of the ElementAdapter of the given array of elements.
*/
protected static void postProcess(Element... elements) {
for (Element element: elements) {
ElementUtil.getElementAdapter(element).postProcess();
}
}

}
Loading