ClassifierCreationHelper.java
/**
* Copyright (c) 2004-2025 Carnegie Mellon University and others. (see Contributors file).
* All Rights Reserved.
*
* NO WARRANTY. ALL MATERIAL IS FURNISHED ON AN "AS-IS" BASIS. CARNEGIE MELLON UNIVERSITY MAKES NO WARRANTIES OF ANY
* KIND, EITHER EXPRESSED OR IMPLIED, AS TO ANY MATTER INCLUDING, BUT NOT LIMITED TO, WARRANTY OF FITNESS FOR PURPOSE
* OR MERCHANTABILITY, EXCLUSIVITY, OR RESULTS OBTAINED FROM USE OF THE MATERIAL. CARNEGIE MELLON UNIVERSITY DOES NOT
* MAKE ANY WARRANTY OF ANY KIND WITH RESPECT TO FREEDOM FROM PATENT, TRADEMARK, OR COPYRIGHT INFRINGEMENT.
*
* This program and the accompanying materials are made available under the terms of the Eclipse Public License 2.0
* which is available at https://www.eclipse.org/legal/epl-2.0/
* SPDX-License-Identifier: EPL-2.0
*
* Created, in part, with funding and support from the United States Government. (see Acknowledgments file).
*
* This program includes and/or can make use of certain third party source code, object code, documentation and other
* files ("Third Party Software"). The Third Party Software that is used by this program is dependent upon your system
* configuration. By using this program, You agree to comply with any and all relevant Third Party Software terms and
* conditions contained in any such Third Party Software or separate license file distributed with such Third Party
* Software. The parties who own the Third Party Software ("Third Party Licensors") are intended third party benefici-
* aries to this license with respect to the terms applicable to their Third Party Software. Third Party Software li-
* censes only apply to the Third Party Software and not any other portion of this program or this program as a whole.
*/
package org.osate.ge.aadl2.internal.util.classifiers;
import java.util.Objects;
import java.util.function.Supplier;
import org.eclipse.emf.ecore.resource.ResourceSet;
import org.osate.aadl2.AadlPackage;
import org.osate.aadl2.Classifier;
import org.osate.aadl2.ComponentImplementation;
import org.osate.aadl2.ComponentType;
import org.osate.aadl2.ComponentTypeRename;
import org.osate.aadl2.NamedElement;
import org.osate.aadl2.Namespace;
import org.osate.aadl2.PackageSection;
import org.osate.aadl2.PublicPackageSection;
import org.osate.ge.aadl2.internal.AadlNamingUtil;
import org.osate.ge.aadl2.internal.util.AadlNameUtil;
import org.osate.ge.internal.util.AgeEmfUtil;
public class ClassifierCreationHelper {
private final ResourceSet resourceSet;
public static class RenamedTypeDetails {
public final String aliasName;
public final boolean exists;
public RenamedTypeDetails(final String aliasName, final boolean exists) {
this.aliasName = Objects.requireNonNull(aliasName, "aliasName must not be null");
this.exists = exists;
}
}
public ClassifierCreationHelper(final ResourceSet resourceSet) {
this.resourceSet = Objects.requireNonNull(resourceSet, "resourceSet must not be null");
}
// Gets the name to use to reference a type from a specified section in another package.
public RenamedTypeDetails getRenamedType(final PackageSection section, final AadlPackage typePackage,
final String baseTypeName) {
final String qualifiedTypeName = typePackage.getQualifiedName() + "::" + baseTypeName;
// Look for an existing component type renames
for (final ComponentTypeRename ctr : section.getOwnedComponentTypeRenames()) {
if (AadlNameUtil.namesAreEqual(ctr.getRenamedComponentType().getQualifiedName(), qualifiedTypeName)
&& ctr.getName() != null) {
return new RenamedTypeDetails(ctr.getName(), true);
}
}
final String baseAlias = qualifiedTypeName.replace("::", "_");
return new RenamedTypeDetails(AadlNamingUtil.buildUniqueIdentifier(section, baseAlias), false);
}
// The returned name is the name of type and the complete "<type>.impl" for implementation.
// Will return null if it is unable to build a name.
public String getName(final ClassifierOperationPart primaryPart, final ClassifierOperationPart basePart) {
return buildName(primaryPart.getType(), () -> getResolvedPackage(primaryPart.getSelectedPackage()),
primaryPart.getIdentifier(), basePart);
}
public String buildName(final ClassifierOperationPartType primaryType, final AadlPackage pkg,
final String identifier, final ClassifierOperationPart basePart) {
return buildName(primaryType, () -> pkg, identifier, basePart);
}
public String buildName(final ClassifierOperationPartType primaryType, final Supplier<AadlPackage> primaryPkgSupplier,
final String identifier, final ClassifierOperationPart basePart) {
final String newName;
if (primaryType == ClassifierOperationPartType.NEW_COMPONENT_IMPLEMENTATION) {
if (basePart == null) {
throw new RuntimeException("Base operation in invalid");
}
final AadlPackage primaryPkg = primaryPkgSupplier.get();
final PackageSection section = primaryPkg.getPublicSection();
// Determine details about the type specified by the base operation part.
final String baseTypeName;
final AadlPackage typePackage;
// Get the name of the type and the package in which it is contained.
if (ClassifierOperationPartType.isCreate(basePart.getType())) {
typePackage = getResolvedPackage(basePart.getSelectedPackage());
baseTypeName = basePart.getIdentifier();
} else if (basePart.getType() == ClassifierOperationPartType.EXISTING) {
final Classifier classifier = getResolvedClassifier(basePart.getSelectedClassifier());
final ComponentType ct = getResolvedComponentType(classifier);
if (ct == null) {
return null;
}
typePackage = getPackage(ct);
baseTypeName = ct.getName();
} else {
throw new RuntimeException("Invalid base operation part: " + basePart.getType());
}
// Handle type not being in same package as implementation
final boolean samePackage = AadlNameUtil.namesAreEqual(primaryPkg, typePackage);
final String localBaseTypeName = samePackage ? baseTypeName
: getRenamedType(section, typePackage, baseTypeName).aliasName;
newName = localBaseTypeName + "." + identifier;
} else {
newName = identifier;
}
return newName;
}
private static AadlPackage getPackage(final NamedElement ne) {
if (ne == null) {
return null;
}
final Namespace ns = ne.getNamespace();
if (ns == null) {
return null;
}
return ns.getOwner() instanceof AadlPackage ? (AadlPackage) ns.getOwner() : null;
}
private ComponentType getResolvedComponentType(final Classifier c) {
if (c instanceof ComponentType) {
return (ComponentType) c;
} else if (c instanceof ComponentImplementation) {
final ComponentImplementation ci = (ComponentImplementation) c;
return AgeEmfUtil.resolveOrNull(ci.getType(), ComponentType.class, resourceSet);
} else {
throw new RuntimeException("Unexpected case: " + c);
}
}
public AadlPackage getResolvedPackage(final Object value) {
return AgeEmfUtil.resolveOrNull(value, AadlPackage.class, resourceSet);
}
public PublicPackageSection getResolvedPublicSection(final Object pkgValue) {
final AadlPackage pkg = getResolvedPackage(pkgValue);
return pkg == null ? null : pkg.getPublicSection();
}
public Classifier getResolvedClassifier(final Object value) {
return AgeEmfUtil.resolveOrNull(value, Classifier.class, resourceSet);
}
}