/** * Deeply list the opaque ports connected to this port on the outside. Begin by listing the ports * that are connected to this port. If any of those are transparent ports that we are connected to * from the inside, then list all the ports deeply connected on the outside to that transparent * port. If any are transparent ports that we are connected to from the outside, then list opaque * ports deeply inside that port. Note that a port may be listed more than once. The path argument * is the path from the port that originally calls this method to this port. If this port is * already on the list of ports on the path to this port in deeply traversing the topology, then * there is a loop in the topology, and an InvalidStateException is thrown. This method not * synchronized on the workspace, so the caller should. * * @param path The list of ports on the path to this port in deeply traversing the topology. * @return An unmodifiable list of ComponentPort objects. */ protected List _deepConnectedPortList(LinkedList path) { if (_deepLinkedPortsVersion == _workspace.getVersion()) { // Cache is valid. Use it. return _deepLinkedPorts; } if (path == null) { path = new LinkedList(); } else { if (path.indexOf(this) >= 0) { throw new InvalidStateException(path, "Loop in topology!"); } } path.add(0, this); Iterator nearRelations = linkedRelationList().iterator(); LinkedList result = new LinkedList(); while (nearRelations.hasNext()) { ComponentRelation relation = (ComponentRelation) nearRelations.next(); // A null link (supported since indexed links) might // yield a null relation here. EAL 7/19/00. if (relation != null) { Iterator connectedPorts = relation.linkedPortList(this).iterator(); while (connectedPorts.hasNext()) { ComponentPort port = (ComponentPort) connectedPorts.next(); // NOTE: If level-crossing transitions are not allowed, // then a simpler test than that of the following // would work. if (port._isInsideLinkable(relation.getContainer())) { // We are coming at the port from the inside. if (port.isOpaque()) { result.add(port); } else { // Port is transparent result.addAll(port._deepConnectedPortList(path)); } } else { // We are coming at the port from the outside. if (port.isOpaque()) { result.add(port); } else { // It is transparent. result.addAll(port._deepInsidePortList(path)); } } } } } _deepLinkedPorts = Collections.unmodifiableList(result); _deepLinkedPortsVersion = _workspace.getVersion(); path.remove(0); return _deepLinkedPorts; }