Search in sources :

Example 41 with ConnectionInstanceEnd

use of org.osate.aadl2.instance.ConnectionInstanceEnd in project osate2 by osate.

the class CreateConnectionsSwitch method balanceFeatureGroupEnds.

/**
 * Handle the case where one of the ends (or both) is a feature group.
 * Create multiple connection instances.
 *
 * @param parentci
 * @param connInfo
 * @param srcEnd
 * @param dstEnd
 */
private void balanceFeatureGroupEnds(final ComponentInstance parentci, final ConnectionInfo connInfo, ConnectionInstanceEnd srcEnd, ConnectionInstanceEnd dstEnd) {
    if (!upFeature.isEmpty()) {
        // we need to match from latest to the oldest in stack going down into the FG nesting hierarchy
        for (int count = upFeature.size() - 1; count >= 0; count--) {
            FeatureInstance upFi = upFeature.get(count);
            EList<FeatureInstance> flist = ((FeatureInstance) dstEnd).getFeatureInstances();
            if (connInfo.dstToMatch != null) {
                String name = connInfo.dstToMatch.getConnectionEnd().getName();
                dstEnd = (FeatureInstance) AadlUtil.findNamedElementInList(flist, name);
                connInfo.dstToMatch = connInfo.dstToMatch.getNext();
            } else {
                FeatureGroup upfg = (FeatureGroup) ((FeatureInstance) upFi.getOwner()).getFeature();
                FeatureGroup downfg = (FeatureGroup) ((FeatureInstance) dstEnd).getFeature();
                FeatureGroupType upfgt = upfg.getAllFeatureGroupType();
                FeatureGroupType downfgt = downfg.getAllFeatureGroupType();
                if (upfgt != null && downfgt != null && upfg.isInverseOf(downfg) && !upfgt.getAllFeatures().isEmpty() && !downfgt.getAllFeatures().isEmpty()) {
                    dstEnd = flist.get(Aadl2InstanceUtil.getFeatureIndex(upFi));
                } else {
                    String name = upFi.getName();
                    srcEnd = (FeatureInstance) AadlUtil.findNamedElementInList(flist, name);
                }
            }
        }
    } else if (!downFeature.isEmpty()) {
        // This is a down stack, i.e., the highest element got pushed first and is the oldest.
        for (int count = 0; count < downFeature.size(); count++) {
            FeatureInstance downFi = downFeature.get(count);
            EList<FeatureInstance> flist = ((FeatureInstance) srcEnd).getFeatureInstances();
            if (connInfo.srcToMatch != null) {
                String name = connInfo.srcToMatch.getConnectionEnd().getName();
                srcEnd = (FeatureInstance) AadlUtil.findNamedElementInList(flist, name);
                connInfo.srcToMatch = connInfo.srcToMatch.getNext();
            } else {
                FeatureGroup downfg = ((FeatureGroup) ((FeatureInstance) downFi.getOwner()).getFeature());
                FeatureGroupType downfgt = downfg.getFeatureGroupType();
                FeatureGroup upfg = ((FeatureGroup) ((FeatureInstance) srcEnd).getFeature());
                FeatureGroupType upfgt = upfg.getFeatureGroupType();
                if (upfgt != null && downfgt != null && upfg.isInverseOf(downfg) && !upfgt.getAllFeatures().isEmpty() && !downfgt.getAllFeatures().isEmpty()) {
                    srcEnd = flist.get(Aadl2InstanceUtil.getFeatureIndex(downFi));
                } else {
                    String name = downFi.getName();
                    srcEnd = (FeatureInstance) AadlUtil.findNamedElementInList(flist, name);
                }
            }
        }
        connInfo.src = srcEnd;
    }
    if (srcEnd instanceof ComponentInstance && dstEnd instanceof ComponentInstance) {
    // TODO-LW: error
    } else if (srcEnd instanceof ComponentInstance || dstEnd instanceof ComponentInstance) {
        addConnectionInstance(parentci.getSystemInstance(), connInfo, dstEnd);
    } else {
        expandFeatureGroupConnection(parentci, connInfo, srcEnd, dstEnd, connInfo.srcToMatch, connInfo.dstToMatch);
    }
}
Also used : FeatureGroup(org.osate.aadl2.FeatureGroup) EList(org.eclipse.emf.common.util.EList) FeatureInstance(org.osate.aadl2.instance.FeatureInstance) FeatureGroupType(org.osate.aadl2.FeatureGroupType) ComponentInstance(org.osate.aadl2.instance.ComponentInstance)

Example 42 with ConnectionInstanceEnd

use of org.osate.aadl2.instance.ConnectionInstanceEnd in project osate2 by osate.

the class CreateConnectionsSwitch method expandFeatureGroupConnection.

/**
 * Expand feature groups as much as possible
 *
 * @param parentci
 * @param connInfo
 * @param srcEnd
 * @param dstEnd
 */
private void expandFeatureGroupConnection(final ComponentInstance parentci, final ConnectionInfo connInfo, ConnectionInstanceEnd srcEnd, ConnectionInstanceEnd dstEnd, ConnectedElement srcToMatch, ConnectedElement dstToMatch) {
    ConnectionInstanceEnd oldSrc = connInfo.src;
    if (srcEnd instanceof FeatureInstance && dstEnd instanceof FeatureInstance) {
        FeatureInstance srcFi = (FeatureInstance) srcEnd;
        FeatureInstance dstFi = (FeatureInstance) dstEnd;
        if (srcToMatch != null) {
            for (FeatureInstance fi : srcFi.getFeatureInstances()) {
                if (srcToMatch.getConnectionEnd() == fi.getFeature()) {
                    expandFeatureGroupConnection(parentci, connInfo, fi, dstFi, srcToMatch.getNext(), dstToMatch);
                    break;
                }
            }
        } else if (dstToMatch != null) {
            for (FeatureInstance fi : dstFi.getFeatureInstances()) {
                if (dstToMatch.getConnectionEnd() == fi.getFeature()) {
                    expandFeatureGroupConnection(parentci, connInfo, srcFi, fi, srcToMatch, dstToMatch.getNext());
                    break;
                }
            }
        } else {
            /*
				 * One of three possible situations
				 * - both ends are feature groups without or with an empty type
				 * - one end is empty and the other is not
				 * - both ends are not empty, in this case they have the same internal structure
				 */
            if (isLeafFeature(srcFi) && isLeafFeature(dstFi)) {
                // both ends are empty
                if (connInfo.isAcross()) {
                    if (srcFi.getFlowDirection().outgoing() && dstFi.getFlowDirection().incoming()) {
                        connInfo.src = srcFi;
                        addConnectionInstance(parentci.getSystemInstance(), connInfo, dstFi);
                    }
                } else {
                    boolean upOnly = isUpOnly(connInfo, srcFi, dstFi);
                    if (upOnly && srcFi.getFlowDirection().outgoing() && dstFi.getFlowDirection().outgoing() || !upOnly && srcFi.getFlowDirection().incoming() && dstFi.getFlowDirection().incoming()) {
                        connInfo.src = srcFi;
                        addConnectionInstance(parentci.getSystemInstance(), connInfo, dstFi);
                    }
                }
            } else if (isLeafFeature(srcFi)) {
                // first find the feature instance as an element of the other end
                FeatureInstance dst = findDestinationFeatureInstance(connInfo, dstFi);
                // we need to deal with outgoing/incoming only and check the direction correctly
                if (dst != null && ((connInfo.isAcross() && dst.getFlowDirection().incoming()) || dst.getFlowDirection().outgoing())) {
                    expandFeatureGroupConnection(parentci, connInfo, srcFi, dst, srcToMatch, dstToMatch);
                } else if (srcFi.getCategory() == FeatureCategory.FEATURE_GROUP) {
                    // we may have a feature group with no FGT or an empty FGT
                    boolean upOnly = isUpOnly(connInfo, srcFi, dstFi);
                    for (FeatureInstance dstelem : dstFi.getFeatureInstances()) {
                        if (upOnly) {
                            if (dstelem.getFlowDirection().outgoing()) {
                                expandFeatureGroupConnection(parentci, connInfo, srcFi, dstelem, srcToMatch, dstToMatch);
                            }
                        } else if (dstelem.getFlowDirection().incoming()) {
                            expandFeatureGroupConnection(parentci, connInfo, srcFi, dstelem, srcToMatch, dstToMatch);
                        }
                    }
                } else {
                    // create the unexpanded connection instance
                    connInfo.src = srcFi;
                    addConnectionInstance(parentci.getSystemInstance(), connInfo, dstFi);
                }
            } else if (isLeafFeature(dstFi)) {
                FeatureInstance target = findSourceFeatureInstance(connInfo, srcFi);
                // we need to deal with outgoing/incoming only and check the direction correctly
                if (target != null && ((connInfo.isAcross() && target.getFlowDirection().outgoing()) || target.getFlowDirection().incoming())) {
                    expandFeatureGroupConnection(parentci, connInfo, target, dstFi, srcToMatch, dstToMatch);
                } else if (dstFi.getCategory() == FeatureCategory.FEATURE_GROUP || connInfo.srcToMatch != null) {
                    // we may have a feature group with no FGT or an empty FGT
                    boolean downOnly = !connInfo.isAcross() && !isUpOnly(connInfo, srcFi, dstFi);
                    for (FeatureInstance srcelem : srcFi.getFeatureInstances()) {
                        if (downOnly) {
                            if (srcelem.getFlowDirection().incoming()) {
                                expandFeatureGroupConnection(parentci, connInfo, srcelem, dstFi, srcToMatch, dstToMatch);
                            }
                        } else if (srcelem.getFlowDirection().outgoing()) {
                            expandFeatureGroupConnection(parentci, connInfo, srcelem, dstFi, srcToMatch, dstToMatch);
                        }
                    }
                } else {
                    // create the unexpanded connection instance
                    connInfo.src = srcFi;
                    addConnectionInstance(parentci.getSystemInstance(), connInfo, dstFi);
                }
            } else {
                boolean isSubset = subsetMatch(connInfo.connections);
                if (!isSubset) {
                    Iterator<FeatureInstance> srcIter = srcFi.getFeatureInstances().iterator();
                    Iterator<FeatureInstance> dstIter = dstFi.getFeatureInstances().iterator();
                    while (srcIter.hasNext() && dstIter.hasNext()) {
                        FeatureInstance src = srcIter.next();
                        FeatureInstance dst = dstIter.next();
                        expandFeatureGroupConnection(parentci, connInfo, src, dst, srcToMatch, dstToMatch);
                    }
                    Assert.isTrue(!srcIter.hasNext() && !dstIter.hasNext(), "Connected feature groups do not have the same number of features");
                } else {
                    // subset matching features by name
                    for (FeatureInstance dst : dstFi.getFeatureInstances()) {
                        if ((connInfo.isAcross() && dst.getFlowDirection().incoming()) || dst.getFlowDirection().outgoing()) {
                            FeatureInstance src = findFeatureInstance(srcFi, dst.getName());
                            if (src != null) {
                                expandFeatureGroupConnection(parentci, connInfo, src, dst, srcToMatch, dstToMatch);
                            }
                        }
                    }
                }
            }
        }
    }
    connInfo.src = oldSrc;
}
Also used : FeatureInstance(org.osate.aadl2.instance.FeatureInstance) ConnectionInstanceEnd(org.osate.aadl2.instance.ConnectionInstanceEnd) ListIterator(java.util.ListIterator) TreeIterator(org.eclipse.emf.common.util.TreeIterator) Iterator(java.util.Iterator)

Example 43 with ConnectionInstanceEnd

use of org.osate.aadl2.instance.ConnectionInstanceEnd in project osate2 by osate.

the class ConnectionInfo method addSegment.

/**
 * @param newSeg the connection to be appended
 * @param srcFi the feature instance at the source of the new segment
 * @param dstFi the feature instance at the destination of the new
 *            segment
 * @param ci the component containing the new segment
 * @param opposite if we traverse a bidirectional segment opposite to
 *            the declaration order
 * @return if the new segment is a valid continuation of the connection
 *         instance
 */
public boolean addSegment(final Connection newSeg, final ConnectionInstanceEnd srcFi, final ConnectionInstanceEnd dstFi, final ComponentInstance ci, boolean opposite, boolean[] keep) {
    boolean valid = true;
    final Context srcCtx = opposite ? newSeg.getAllDestinationContext() : newSeg.getAllSourceContext();
    final Context dstCtx = opposite ? newSeg.getAllSourceContext() : newSeg.getAllDestinationContext();
    final ConnectionEnd source = opposite ? newSeg.getAllDestination() : newSeg.getAllSource();
    final ConnectionEnd dest = opposite ? newSeg.getAllSource() : newSeg.getAllDestination();
    final boolean goingUp = !(dstCtx instanceof Subcomponent) && (source instanceof Subcomponent || srcCtx instanceof Subcomponent);
    final boolean goingDown = !(srcCtx instanceof Subcomponent) && (dest instanceof Subcomponent || dstCtx instanceof Subcomponent);
    // TODO can we do these checks on the instance information
    keep[0] = true;
    if (srcFi != null) {
        sources.add(srcFi);
        if (srcFi instanceof FeatureInstance) {
            DirectionType dir = ((FeatureInstance) srcFi).getFlowDirection();
            bidirectional &= (dir == DirectionType.IN_OUT);
            if (goingUp) {
                valid &= dir.outgoing();
            } else if (goingDown) {
                valid &= dir.incoming();
            } else {
                valid &= dir.outgoing();
            }
        }
    }
    bidirectional &= newSeg.isAllBidirectional();
    if (dstFi != null) {
        destinations.add(dstFi);
        if (dstFi instanceof FeatureInstance) {
            DirectionType dir = ((FeatureInstance) dstFi).getFlowDirection();
            bidirectional &= (dir == DirectionType.IN_OUT);
            if (goingUp) {
                valid &= dir.outgoing();
            } else if (goingDown) {
                valid &= dir.incoming();
            } else {
                valid &= dir.incoming();
            }
        }
    }
    /*
		 * Issue 582 -- This does not catch all the bad things that can happen. NOT testing for
		 * subcomponents being connected to requires (goingup) or provides (goingdon).
		 */
    // XXX: the argument below, "this.src", may not be correct, but I'm not really sure what is the correct thing
    final ConnectionInstanceEnd resolvedSrc = resolveFeatureInstance(this.src, srcFi);
    // XXX: the argument below, "this.src", may not be correct, but I'm not really sure what is the correct thing
    final ConnectionInstanceEnd resolvedDst = resolveFeatureInstance(this.src, dstFi);
    if (resolvedSrc instanceof FeatureInstance) {
        if (resolvedDst instanceof FeatureInstance) {
            final FeatureInstance resolvedSrcFI = (FeatureInstance) resolvedSrc;
            final FeatureInstance resolvedDstFI = (FeatureInstance) resolvedDst;
            if (resolvedSrcFI.getCategory() == FeatureCategory.DATA_ACCESS && resolvedDstFI.getCategory() == FeatureCategory.DATA_ACCESS) {
                if (goingUp || goingDown) {
                    valid &= resolvedSrcFI.getDirection() == resolvedDstFI.getDirection();
                } else {
                    valid &= resolvedSrcFI.getDirection().getInverseDirection() == resolvedDstFI.getDirection();
                }
            }
        }
    } else {
    // TODO ComponentInstance -- Should check connections between components and access features here
    }
    if (valid) {
        // handle reaching into feature groups in across connection
        if (newSeg.isAcross()) {
            // segment goes across
            int i = connections.size();
            Connection root = newSeg.getRootConnection();
            srcToMatch = opposite ? root.getDestination() : root.getSource();
            srcToMatch = srcToMatch.getNext();
            while (keep[0] && i > 0 && srcToMatch != null) {
                i -= 1;
                Connection c = connections.get(i);
                // skip connections that don't go into a feature group
                if (!connectsSameFeatureGroup(c)) {
                    ConnectionEnd e = opposites.get(i) ? c.getAllSource() : c.getAllDestination();
                    ConnectionEnd cce = srcToMatch.getConnectionEnd();
                    srcToMatch = srcToMatch.getNext();
                    keep[0] = cce == e;
                }
            }
            across = true;
            acrossConnection = newSeg;
            dstToMatch = opposite ? root.getSource() : root.getDestination();
            dstToMatch = dstToMatch.getNext();
            container = ci;
        } else if (across && dstToMatch != null) {
            if (!connectsSameFeatureGroup(newSeg)) {
                ConnectionEnd e = opposite ? newSeg.getAllDestination() : newSeg.getAllSource();
                ConnectionEnd cce = dstToMatch.getConnectionEnd();
                dstToMatch = dstToMatch.getNext();
                keep[0] = cce == e;
            }
        }
    }
    connections.add(newSeg);
    opposites.add(opposite);
    contexts.add(ci);
    return valid;
}
Also used : Context(org.osate.aadl2.Context) DirectionType(org.osate.aadl2.DirectionType) FeatureInstance(org.osate.aadl2.instance.FeatureInstance) ConnectionInstanceEnd(org.osate.aadl2.instance.ConnectionInstanceEnd) Subcomponent(org.osate.aadl2.Subcomponent) FeatureGroupConnection(org.osate.aadl2.FeatureGroupConnection) Connection(org.osate.aadl2.Connection) ConnectionEnd(org.osate.aadl2.ConnectionEnd)

Example 44 with ConnectionInstanceEnd

use of org.osate.aadl2.instance.ConnectionInstanceEnd in project osate2 by osate.

the class ConnectionInfo method createConnectionInstance.

public ConnectionInstance createConnectionInstance(final String name, final ConnectionInstanceEnd dst) {
    ConnectionInstance conni = InstanceFactory.eINSTANCE.createConnectionInstance();
    conni.setName(name);
    Iterator<Connection> connIter = connections.iterator();
    Iterator<ComponentInstance> ctxIter = contexts.iterator();
    // Iterator<ConnectionInstanceEnd> srcIter = sources.iterator();
    Iterator<ConnectionInstanceEnd> dstIter = destinations.iterator();
    Iterator<Boolean> oppIter = opposites.iterator();
    ConnectionInstanceEnd dosrc = src;
    ConnectionInstanceEnd dodst = null;
    while (connIter.hasNext() && dstIter.hasNext()) {
        ConnectionReference connRef = conni.createConnectionReference();
        connRef.setConnection(connIter.next());
        connRef.setContext(ctxIter.next());
        connRef.setSource(dosrc);
        dodst = resolveFeatureInstance(dosrc, dstIter.next());
        connRef.setDestination(dodst);
        dosrc = dodst;
        connRef.setReverse(oppIter.next());
    }
    conni.setSource(src);
    conni.setDestination(dst);
    conni.setComplete(across);
    kind = getKind(dst);
    conni.setKind(kind);
    return conni;
}
Also used : ConnectionInstance(org.osate.aadl2.instance.ConnectionInstance) ConnectionInstanceEnd(org.osate.aadl2.instance.ConnectionInstanceEnd) ConnectionReference(org.osate.aadl2.instance.ConnectionReference) FeatureGroupConnection(org.osate.aadl2.FeatureGroupConnection) Connection(org.osate.aadl2.Connection) ComponentInstance(org.osate.aadl2.instance.ComponentInstance)

Example 45 with ConnectionInstanceEnd

use of org.osate.aadl2.instance.ConnectionInstanceEnd in project osate2 by osate.

the class InstantiateModel method createNewConnection.

/**
 * create a copy of the connection instance with the specified indices for the source and the destination
 * @param conni
 * @param srcIndices
 * @param dstIndices
 */
private void createNewConnection(ConnectionInstance conni, List<Long> srcIndices, List<Long> dstIndices) {
    LinkedList<String> names = new LinkedList<String>();
    LinkedList<Integer> dims = new LinkedList<Integer>();
    LinkedList<Integer> sizes = new LinkedList<Integer>();
    ConnectionInstance newConn = EcoreUtil.copy(conni);
    conni.getContainingComponentInstance().getConnectionInstances().add(newConn);
    ConnectionReference topConnRef = Aadl2InstanceUtil.getTopConnectionReference(newConn);
    analyzePath(conni.getContainingComponentInstance(), conni.getSource(), names, dims, sizes);
    if (srcIndices.size() != sizes.size() && // filter out one side being an element without index (array of 1) (many to one mapping)
    !(sizes.size() == 0 && dstIndices.size() == 1)) {
        errManager.error(newConn, "Source indices " + srcIndices + " do not match source dimension " + sizes.size());
    }
    InstanceObject src = resolveConnectionInstancePath(newConn, topConnRef, names, dims, sizes, srcIndices, true);
    names.clear();
    dims.clear();
    sizes.clear();
    analyzePath(conni.getContainingComponentInstance(), conni.getDestination(), names, dims, sizes);
    if (dstIndices.size() != sizes.size() && // filter out one side being an element without index (array of 1) (many to one mapping)
    !(sizes.size() == 0 && dstIndices.size() == 1)) {
        errManager.error(newConn, "For " + newConn.getConnectionReferences().get(0).getFullName() + " : " + newConn.getFullName() + ", destination indices " + dstIndices + " do not match destination dimension " + sizes.size());
    }
    InstanceObject dst = resolveConnectionInstancePath(newConn, topConnRef, names, dims, sizes, dstIndices, false);
    if (src == null) {
        errManager.error(newConn, "Connection source not found");
    }
    if (dst == null) {
        errManager.error(newConn, "Connection destination not found");
    }
    String containerPath = conni.getContainingComponentInstance().getInstanceObjectPath();
    int len = containerPath.length() + 1;
    String srcPath = (src != null) ? src.getInstanceObjectPath() : "Source end not found";
    StringBuffer sb = new StringBuffer();
    int i = (srcPath.startsWith(containerPath)) ? len : 0;
    sb.append(srcPath.substring(i));
    sb.append(" --> ");
    String dstPath = (dst != null) ? dst.getInstanceObjectPath() : "Destination end not found";
    i = (dstPath.startsWith(containerPath)) ? len : 0;
    sb.append(dstPath.substring(i));
    ConnectionInstance duplicate = (ConnectionInstance) AadlUtil.findNamedElementInList(conni.getContainingComponentInstance().getConnectionInstances(), sb.toString());
    if (duplicate != null && duplicate != conni) {
        // conni will be removed later
        errManager.warning(newConn, "There is already another connection between the same endpoints");
    }
    newConn.setSource((ConnectionInstanceEnd) src);
    newConn.setDestination((ConnectionInstanceEnd) dst);
    newConn.setName(sb.toString());
}
Also used : ConnectionInstance(org.osate.aadl2.instance.ConnectionInstance) InstanceObject(org.osate.aadl2.instance.InstanceObject) ConnectionReference(org.osate.aadl2.instance.ConnectionReference) LinkedList(java.util.LinkedList)

Aggregations

ConnectionInstanceEnd (org.osate.aadl2.instance.ConnectionInstanceEnd)47 ComponentInstance (org.osate.aadl2.instance.ComponentInstance)35 FeatureInstance (org.osate.aadl2.instance.FeatureInstance)33 ConnectionInstance (org.osate.aadl2.instance.ConnectionInstance)23 ConnectionReference (org.osate.aadl2.instance.ConnectionReference)18 ArrayList (java.util.ArrayList)13 Connection (org.osate.aadl2.Connection)10 Feature (org.osate.aadl2.Feature)9 Subcomponent (org.osate.aadl2.Subcomponent)9 ConnectionEnd (org.osate.aadl2.ConnectionEnd)8 BasicEList (org.eclipse.emf.common.util.BasicEList)7 ENotificationImpl (org.eclipse.emf.ecore.impl.ENotificationImpl)7 Element (org.osate.aadl2.Element)7 InstanceObject (org.osate.aadl2.instance.InstanceObject)7 HashMap (java.util.HashMap)6 List (java.util.List)6 FeatureGroup (org.osate.aadl2.FeatureGroup)6 FeatureGroupConnection (org.osate.aadl2.FeatureGroupConnection)6 ModeTransitionInstance (org.osate.aadl2.instance.ModeTransitionInstance)6 Map (java.util.Map)5