示例#1
0
 /**
  * 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;
  }
示例#3
0
  /**
   * 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;
  }