/** * Clone the object into the specified workspace. The new object is <i>not</i> added to the * directory of that workspace (you must do this yourself if you want it there). The result is a * new port with no connections and no container. * * @param workspace The workspace for the cloned object. * @exception CloneNotSupportedException If one or more of the attributes cannot be cloned. * @return A new ComponentPort. */ public Object clone(Workspace workspace) throws CloneNotSupportedException { ComponentPort newObject = (ComponentPort) super.clone(workspace); newObject._insideLinks = new CrossRefList(newObject); newObject._deepLinkedInPortsVersion = -1L; newObject._deepLinkedPortsVersion = -1L; newObject._isOpaqueVersion = -1L; return newObject; }
/** * 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; }
/** * Deeply list the ports linked to this relation. Look through all transparent ports and return * only opaque ports. This method is read-synchronized on the workspace. * * @return An unmodifiable list of ComponentPorts. */ public List deepLinkedPortList() { try { _workspace.getReadAccess(); if (_deepLinkedPortsVersion == _workspace.getVersion()) { // Cache is valid. Use it. return _deepLinkedPorts; } Iterator nearPorts = linkedPortList().iterator(); _deepLinkedPorts = new LinkedList(); while (nearPorts.hasNext()) { ComponentPort port = (ComponentPort) nearPorts.next(); if (port._isInsideLinkable(this.getContainer())) { // Port is above me in the hierarchy. if (port.isOpaque()) { // Port is opaque. Append it to list. _deepLinkedPorts.add(port); } else { // Port is transparent. See through it. _deepLinkedPorts.addAll(port.deepConnectedPortList()); } } else { // Port below me in the hierarchy. if (port.isOpaque()) { _deepLinkedPorts.add(port); } else { _deepLinkedPorts.addAll(port.deepInsidePortList()); } } } _deepLinkedPortsVersion = _workspace.getVersion(); return Collections.unmodifiableList(_deepLinkedPorts); } finally { _workspace.doneReading(); } }
/** * If this port is transparent, then deeply list the ports connected on the inside. Otherwise, * list just this port. All ports listed are opaque. Note that the returned list could conceivably * be empty, for example if this port is transparent but has no inside links. Also, a port may be * listed more than once if more than one inside connection to it has been established. 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 is * read-synchronized on the workspace. * * @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 _deepInsidePortList(LinkedList path) { if (_deepLinkedInPortsVersion == _workspace.getVersion()) { // Cache is valid. Use it. return _deepLinkedInPorts; } if (path == null) { path = new LinkedList(); } else { if (path.indexOf(this) >= 0) { throw new InvalidStateException(path, "Loop in topology!"); } } path.add(0, this); LinkedList result = new LinkedList(); // Port is transparent. Iterator relations = insideRelationList().iterator(); while (relations.hasNext()) { Relation relation = (Relation) relations.next(); // A null link might yield a null relation here. if (relation != null) { Iterator insidePorts = relation.linkedPortList(this).iterator(); while (insidePorts.hasNext()) { ComponentPort port = (ComponentPort) insidePorts.next(); // The inside port may not be actually inside, // in which case we want to look through it // from the inside (this supports transparent // entities). if (port._isInsideLinkable(relation.getContainer())) { // The inside port is not truly inside. // Check to see whether it is transparent. if (port.isOpaque()) { result.add(port); } else { result.addAll(port._deepConnectedPortList(path)); } } else { // We are coming at the port from the outside. if (port.isOpaque()) { // The inside port is truly inside. result.add(port); } else { result.addAll(port._deepInsidePortList(path)); } } } } } _deepLinkedInPorts = Collections.unmodifiableList(result); _deepLinkedInPortsVersion = _workspace.getVersion(); path.remove(0); return _deepLinkedInPorts; }