use of org.osate.aadl2.ParameterConnection in project osate2 by osate.
the class ComponentImplementationImpl method createOwnedParameterConnection.
/**
* <!-- begin-user-doc -->
* <!-- end-user-doc -->
* @generated
*/
public ParameterConnection createOwnedParameterConnection() {
ParameterConnection newOwnedParameterConnection = (ParameterConnection) create(Aadl2Package.eINSTANCE.getParameterConnection());
getOwnedParameterConnections().add(newOwnedParameterConnection);
return newOwnedParameterConnection;
}
use of org.osate.aadl2.ParameterConnection in project osate2 by osate.
the class CreateConnectionsSwitch method appendSegment.
/**
* appendSegment Append a segment to a connection instance.
*
* @param newSegment
* the declarative connection to be added to the connection
* instance
* @param ci
* the component that contains the new segment
* @param goOpposite
* the current declarative connection is bidirectional and we are
* following it toward its source
* @param conni
* the connection instance representing the semantic connection
*/
// TODO-LW: set 'complete' in conn info
private void appendSegment(ConnectionInfo connInfo, final Connection newSegment, final ComponentInstance ci, final boolean goOpposite) {
final boolean didModeTransitionConnection = doModeTransitionConnections(ci, connInfo, newSegment);
final ConnectionEnd fromEnd = goOpposite ? newSegment.getAllDestination() : newSegment.getAllSource();
final Context fromCtx = goOpposite ? newSegment.getAllDestinationContext() : newSegment.getAllSourceContext();
ConnectionEnd toEnd = goOpposite ? newSegment.getAllSource() : newSegment.getAllDestination();
final Context toCtx = goOpposite ? newSegment.getAllSourceContext() : newSegment.getAllDestinationContext();
final ComponentInstance toCi = (toCtx instanceof Subcomponent) ? ci.findSubcomponentInstance((Subcomponent) toCtx) : null;
final boolean finalComponent = isConnectionEndingComponent(toCtx);
final boolean dstEmpty = toCtx instanceof Subcomponent && toCi.getComponentInstances().isEmpty();
ConnectionInstanceEnd fromFi = null;
ConnectionInstanceEnd toFi = null;
FeatureInstance pushedFeature = null;
FeatureInstance poppedFeature = null;
FeatureInstance downedFeature = null;
/*
* FIX JD If we have a data component directly connected to a subprogram
* parameter, we do not handle it because we do not deal with parameter
* connection within the instance model. See bug #220
*/
if ((toEnd instanceof ParameterImpl) && ((fromEnd instanceof DataSubcomponent) || (fromEnd instanceof DataAccess))) {
return;
}
/*
* Fix JD bug #222.
* Tweaked again for Issue #2162: changed to check if the context is a subprogram call
* rather than just checking if the feature is contained in a subprogram.
*/
if ((toEnd instanceof DataAccess) && (toCtx instanceof SubprogramCall)) {
return;
}
if (toCtx instanceof Subcomponent && toCi == null) {
if (!(toCtx instanceof SubprogramSubcomponent)) {
error(ci, "Instantiation error: no component instance for subcomponent " + toCtx.getName());
}
return;
}
if (!(fromEnd instanceof Subcomponent)) {
// fromEnd is a feature
final ComponentInstance fromCi = (fromCtx instanceof Subcomponent) ? ci.findSubcomponentInstance((Subcomponent) fromCtx) : null;
if (fromCtx instanceof Subcomponent && fromCi == null) {
if (!(fromCtx instanceof SubprogramSubcomponent)) {
error(ci, "Instantiation error: no component instance for subcomponent " + fromCtx.getName());
}
return;
}
List<FeatureInstance> fiList = null;
if (fromCtx instanceof FeatureGroup) {
// TODO phf: find index and compare with stack
FeatureInstance fgi = (FeatureInstance) AadlUtil.findNamedElementInList(ci.getFeatureInstances(), fromCtx.getName());
if (fgi != null) {
fiList = fgi.getFeatureInstances();
fromFi = (FeatureInstance) AadlUtil.findNamedElementInList(fiList, fromEnd.getName());
}
if (fromFi != null) {
if (!upFeature.empty()) {
FeatureInstance popfi = upFeature.peek();
// match against stack only if we don't reach deeper into feature group
if (connInfo.dstToMatch == null && !Aadl2InstanceUtil.isSame(popfi, (FeatureInstance) fromFi)) {
// did not match
return;
} else {
poppedFeature = upFeature.pop();
}
} else {
downFeature.push((FeatureInstance) fromFi);
downedFeature = (FeatureInstance) fromFi;
}
}
} else {
fiList = (fromCi != null ? fromCi : ci).getFeatureInstances();
fromFi = (FeatureInstance) AadlUtil.findNamedElementInList(fiList, fromEnd.getName());
}
} else {
fromFi = ci.findSubcomponentInstance((Subcomponent) fromEnd);
}
if (!(toEnd instanceof Subcomponent)) {
List<FeatureInstance> fiList = null;
if (toCtx instanceof FeatureGroup) {
FeatureInstance fgi = (FeatureInstance) AadlUtil.findNamedElementInList(ci.getFeatureInstances(), toCtx.getName());
if (fgi != null) {
fiList = fgi.getFeatureInstances();
toFi = (FeatureInstance) AadlUtil.findNamedElementInList(fiList, toEnd.getName());
}
if (toFi != null) {
upFeature.push((FeatureInstance) toFi);
pushedFeature = (FeatureInstance) toFi;
}
} else {
fiList = (toCi != null ? toCi : ci).getFeatureInstances();
toFi = (FeatureInstance) AadlUtil.findNamedElementInList(fiList, toEnd.getName());
}
} else {
toFi = ci.findSubcomponentInstance((Subcomponent) toEnd);
}
/*
* Issue 2032: We do not want connections that go from abstract subcomponent to the ports of
* their containing components if the containing component is final. We specifically are
* checking that the connection starts at a port feature and ends at a feature that is a feature
* of the containing component and the containing component is a connection ending component. We don't
* have to check that the end feature is a port because AADL semantics guarantee that it will be.
*/
if (fromFi instanceof FeatureInstance && ((FeatureInstance) fromFi).getFeature() instanceof Port && toFi.eContainer().equals(ci) && isConnectionEndingCategory(ci.getCategory())) {
return;
}
try {
boolean[] keep = { false };
boolean valid = connInfo.addSegment(newSegment, fromFi, toFi, ci, goOpposite, keep);
if (!keep[0]) {
return;
}
if (!valid) {
if (toFi == null) {
error(ci, "Connection from " + connInfo.src.getInstanceObjectPath() + " via " + newSegment.getQualifiedName() + " has no valid direction. Connection instance not created.");
} else {
error(ci, "Connection from " + connInfo.src.getInstanceObjectPath() + " to " + toFi.getInstanceObjectPath() + " has no valid direction. Connection instance not created.");
}
return;
}
// first check if the connection must end with the new segment
if (toEnd instanceof Subcomponent) {
ComponentInstance toInstance = ci.findSubcomponentInstance((Subcomponent) toEnd);
if (toInstance == null) {
// happens if conn leaves system to aggregate data port
warning(ci, "Connection to " + toEnd.getQualifiedName() + " could not be instantiated.");
} else {
// connection ends at a shared data, bus, or subprogram (group)
connInfo.complete = true;
finalizeConnectionInstance(ci.getSystemInstance(), connInfo, toInstance);
}
} else if (toEnd instanceof InternalFeature || toEnd instanceof ProcessorFeature) {
// can't handle these
// FIXME: What if a connection from outside goes to one of these?
warning(ci, "Connection to " + toEnd.getQualifiedName() + " could not be instantiated.");
} else {
Feature toFeature = (Feature) toEnd;
if (toEnd instanceof Parameter) {
// connection ends at a parameter
FeatureInstance dstFi = toCi.findFeatureInstance(toFeature);
if (dstFi == null) {
error(toCi, "Destination feature " + toFeature.getName() + " not found. No connection created.");
} else {
connInfo.complete = true;
finalizeConnectionInstance(ci, connInfo, dstFi);
}
} else if (dstEmpty) {
// connection ends because the destination component does not
// contain any subcomponents
FeatureInstance dstFi = toCi.findFeatureInstance(toFeature);
if (dstFi == null) {
error(toCi, "Destination feature " + toFeature.getName() + " not found. No connection created.");
} else {
connInfo.complete = true;
finalizeConnectionInstance(ci, connInfo, dstFi);
}
} else if (!(toCtx instanceof Subcomponent)) {
// implementation
if (ci instanceof SystemInstance) {
if (toCtx instanceof FeatureGroup) {
// XXX: PHF: going up into an element of a feature group
// should we go to the FG or to the feature?
finalizeConnectionInstance(ci, connInfo, ci.findFeatureInstance((FeatureGroup) toCtx));
} else {
finalizeConnectionInstance(ci, connInfo, ci.findFeatureInstance(toFeature));
}
} else {
if (toCtx instanceof FeatureGroup) {
toFeature = (FeatureGroup) toCtx;
// toFeature now points to the enclosing feature group
// this should be the starting feature for the next
// connection
}
ComponentInstance nextCi = ci.getContainingComponentInstance();
List<Connection> parentConns = InstanceUtil.getComponentImplementation(nextCi, 0, classifierCache).getAllConnections();
FeatureInstance dstFi = ci.findFeatureInstance(toFeature);
List<Connection> conns = filterOutgoingConnections(parentConns, dstFi.getFeature(), ci.getSubcomponent());
if (conns.isEmpty()) {
if (!didModeTransitionConnection) {
if (ci instanceof SystemInstance) {
finalizeConnectionInstance(ci, connInfo, ci.findFeatureInstance(toFeature));
} else {
warning(toFi, "Could not continue connection from " + connInfo.src.getInstanceObjectPath() + " through " + toFi.getInstanceObjectPath() + ". No connection instance created.");
}
}
} else {
for (Connection nextConn : conns) {
// note: nextConn goes either up or across
final ConnectionInfo clone = connInfo.cloneInfo();
boolean opposite = false;
if (nextConn.isAllBidirectional()) {
/*
* The next connection is bidirectional, but we need to figure out if we are
* traveling from its src to dest or from its dest to src.
*
* Put another way, we traverse the next connection in the opposite direction
* only if the destination feature instance of the next connection is equal to
* the destination feature instance of the current connection (based on "toFeature" which
* already takes it's own opposite direction into account via "goOpposite" at
* the start of the method).
*/
final ConnectionEnd nextConnDest = nextConn.getAllDestination();
if (nextConnDest instanceof Feature) {
final Feature nextConnDstFeature = (Feature) nextConnDest;
FeatureInstance nextConnDstFi = nextCi.findFeatureInstance(nextConnDstFeature);
/*
* If we find the connection destination in the containing component instance, then
* the connection is a normal (not reversed) traversal of the connection. The
* value of `opposite` will stay `false`.
*/
if (nextConnDstFi == null) {
/*
* Didn't find the next destination in the containing component, so the question
* still is, is the destination in a sibling subcomponent or is it a reversed
* traversal from the containing component, or even a reversed traversal from
* a sibling subcomponent?
*/
// next goes across, maybe?
Context nextConnDstCtx = nextConn.getAllDestinationContext();
if (nextConnDstCtx instanceof Subcomponent) {
final ComponentInstance nextConnDstSubi = nextCi.findSubcomponentInstance((Subcomponent) nextConnDstCtx);
nextConnDstFi = nextConnDstSubi.findFeatureInstance(nextConnDstFeature);
}
if (nextConnDstFi != null) {
/*
* Opposite is true if the dest of the next connection the same feature instance as the
* dest of the current connection.
*/
opposite = ci.findFeatureInstance(toFeature) == nextConnDstFi;
}
}
}
} else {
/*
* not bidirectional, so the src of nextConn is a feature of 'ci', and the dest
* is a feature of either 'nextCi` or a sibling subcomponent. We are following
* the connection in its natural direction, so `opposite` is `false`.
*/
}
appendSegment(clone, nextConn, nextCi, opposite);
}
}
}
} else {
if (toCtx instanceof Subcomponent && toCi == null) {
if (!(toCtx instanceof SubprogramSubcomponent)) {
error(ci, "Instantiation error: no component instance for subcomponent " + toCtx.getName());
}
return;
}
toFi = toCi.findFeatureInstance(toFeature);
if (toFi == null) {
error(ci, "Could not find instance object for feature " + toEnd.getName() + " of subcomponent " + ((Subcomponent) toCtx).getName() + ". No connection instance created.");
return;
}
ComponentImplementation toImpl = InstanceUtil.getComponentImplementation(toCi, 0, classifierCache);
if (toImpl == null) {
connInfo.complete = true;
finalizeConnectionInstance(ci, connInfo, toFi);
} else {
// there is a toImpl
/*
* Issue 2032: Get the connections internal to the destination component that connect
* to the feature. Two cases here. (1) If the component is final (thread/device/processor),
* we only follow access features inside, (2) otherwise we follow all the internal connections
* except for the parameter connections. We keep track of whether any internal connections were
* ignored so we know if we should create a connection instance that stops at the component itself.
*/
final AtomicBoolean hasIgnoredConnection = new AtomicBoolean(false);
List<Connection> conns = AadlUtil.getIngoingConnections(toImpl, toFeature, c -> {
if (c instanceof AccessConnection) {
// never ignore access connections
return true;
} else if (c instanceof ParameterConnection) {
// always ignore parameter connections
hasIgnoredConnection.set(true);
return false;
} else {
// Ignore other connections only if the component is connection ending
if (finalComponent) {
hasIgnoredConnection.set(true);
return false;
} else {
return true;
}
}
});
if (conns.isEmpty()) {
// No internal connections, or they are all parameter connections, so we stop here
List<Subcomponent> subs = toImpl.getAllSubcomponents();
if (!subs.isEmpty()) {
if (!finalComponent) {
warning(ci, "No connection declaration from feature " + toEnd.getName() + " of component " + ((Subcomponent) toCtx).getName() + " to subcomponents. Connection instance ends at " + ((Subcomponent) toCtx).getName());
}
connInfo.complete = true;
finalizeConnectionInstance(ci, connInfo, toFi);
}
} else {
/*
* Issue 2032: If we get here then destination component has internal connections,
* not all of which are parameter connections. We definitely are going to proceed
* inside the component with the connection. However, if there are internal
* connections that were ignored, we also need to create a connection instance that
* ends at the component.
*
* NB. Not possible to have an ignored parameter connection from a feature and have a
* another not ignored connection from that feature because the only place a
* parameter connection can exist is in a subprogram or a thread, and it's
* not possible to have a regular port connections internal to
* either one of those (with the exception of abstract components, but those
* should probably be illegal anyway and we ignore those too).
*/
if (hasIgnoredConnection.get()) {
final ConnectionInfo clone = connInfo.cloneInfo();
clone.complete = true;
finalizeConnectionInstance(ci, clone, toFi);
}
// as End or as Cxt
for (Connection nextConn : conns) {
final ConnectionInfo clone = connInfo.cloneInfo();
EList<Feature> toflist = toFeature.getAllFeatureRefinements();
Context dstCtx = nextConn.getAllDestinationContext();
// dstCtx is null if we're going down and in opposite direction
final boolean opposite = toflist.contains(nextConn.getAllDestination()) && (dstCtx == null || toCtx == dstCtx) || toflist.contains(dstCtx);
appendSegment(clone, nextConn, toCi, opposite);
}
}
}
}
}
} finally {
if (pushedFeature != null) {
if (!upFeature.empty()) {
upFeature.pop();
} else {
warning(ci, "Popping from empty upindex");
}
}
if (poppedFeature != null) {
if (downFeature.empty()) {
upFeature.push(poppedFeature);
} else {
// remove from downIndex
warning(ci, "Trying to push back on while downIndex is not empty");
}
}
if (downedFeature != null) {
// remove from downIndex
FeatureInstance popfeature = downFeature.pop();
if (!Aadl2InstanceUtil.isSame(popfeature, downedFeature)) {
// should be the same
warning(ci, "Did not match popped downIndex");
}
}
}
}
use of org.osate.aadl2.ParameterConnection in project osate2 by osate.
the class SwitchDirectionOfConnectionPropertySection method refresh.
@Override
public void refresh() {
final List<Connection> selectedConnections = selectedBos.boStream(Connection.class).collect(Collectors.toList());
boolean isEnabledSwitchDirection = false;
final Iterator<Connection> it = selectedConnections.iterator();
Connection connection = it.next();
if (!(connection instanceof ParameterConnection)) {
isEnabledSwitchDirection = true;
}
Boolean isBidirectional = connection.isAllBidirectional();
while (it.hasNext()) {
connection = it.next();
// Check if connections selected are mixed bidirectional and unidirectional
if (connection.isAllBidirectional() != isBidirectional) {
// No selection on buttons
isBidirectional = null;
// Exit loop if obtained both initial control values
if (isEnabledSwitchDirection) {
break;
}
}
if (!isEnabledSwitchDirection && !(connection instanceof ParameterConnection)) {
isEnabledSwitchDirection = true;
}
}
// Set initial selections
bidirectionalBtn.setSelection(isBidirectional == Boolean.TRUE);
unidirectionalBtn.setSelection(isBidirectional == Boolean.FALSE);
switchDirectionBtn.setEnabled(isEnabledSwitchDirection);
}
Aggregations