edu.wustl.cab2b.server.path.pathgen.Path.java Source code

Java tutorial

Introduction

Here is the source code for edu.wustl.cab2b.server.path.pathgen.Path.java

Source

/*L
 * Copyright Georgetown University, Washington University.
 *
 * Distributed under the OSI-approved BSD 3-Clause License.
 * See http://ncip.github.com/cab2b/LICENSE.txt for details.
 */

package edu.wustl.cab2b.server.path.pathgen;

import java.util.ArrayList;
import java.util.Collections;
import java.util.HashSet;
import java.util.List;
import java.util.Set;

import org.apache.commons.lang.builder.HashCodeBuilder;

/**
 * An immutable representation of a path as a collection of the following:
 * <ul>
 * <li>Source/From {@link edu.wustl.cab2b.server.path.pathgen.Node}
 * <li> Destination/To {@link edu.wustl.cab2b.server.path.pathgen.Node}
 * <li> A {@link java.util.List} of intermediate nodes needed to traverse from
 * <code>fromNode</code> to <code>toNode</code>.
 * </ul>
 * <p>
 * A path is a <i>self-edge</i> if and only if
 * <code>fromNode.equals(toNode)</code>. A node can occur twice in a path if
 * and only if the path is a self-edge; in other words, if a path is not a
 * self-edge, a node can appear in the path at atmost one of the following
 * locations:
 * <ul>
 * <li><code>fromNode</code>
 * <li><code>toNode</code>
 * <li>one of the <code>intermediateNodes</code>
 * </ul>
 * This class itself does not provide validation checks for this, since the
 * validation checks may hamper performance.
 * @author srinath_k
 */
public class Path {
    private SourceDestinationPair sdp;

    private List<Node> intermediateNodes;

    private int hashCode;

    Path(Node fromNode, Node toNode) {
        this(fromNode, toNode, null);
    }

    Path(Node fromNode, Node toNode, List<Node> intermediateNodes) {
        this.sdp = new SourceDestinationPair(fromNode, toNode);
        if (intermediateNodes == null) {
            this.intermediateNodes = Collections.unmodifiableList(new ArrayList<Node>(0));
        } else {
            this.intermediateNodes = Collections.unmodifiableList(intermediateNodes);
        }
    }

    /**
     * checks whether this path contains node or not
     * @param node
     * @return
     */
    public boolean containsNode(Node node) {
        return fromNode().equals(node) || toNode().equals(node) || getIntermediateNodes().contains(node);
    }

    /**
     * checks whether cycle present in current path or not.
     * @return
     */
    public boolean isCyclePresent() {
        if (getIntermediateNodes().isEmpty()) {
            return false;
        }
        Set<Node> nodesSet = new HashSet<Node>(getIntermediateNodes());
        nodesSet.add(fromNode());
        nodesSet.add(toNode());
        return nodesSet.size() < getIntermediateNodes().size() + 2;
    }

    /**
     * checks whether this edge is self edge or not.
     * @return
     */
    public boolean isSelfEdge() {
        return getIntermediateNodes().isEmpty() && fromNode().equals(toNode());
    }

    /**
     * @param origVal
     *            the node to be replaced.
     * @param replacement
     *            the new node which will replace origVal.
     * @return a newly constructed path which has the <code>replacement</code>
     *         node in place of the <code>origVal</code> node.
     */
    Path replace(Node origVal, Node replacement) {
        if (isSelfEdge() && fromNode().equals(origVal)) {
            return new Path(replacement, replacement);
        }
        if (fromNode().equals(origVal)) {
            return new Path(replacement, toNode(), getIntermediateNodes());
        }
        if (toNode().equals(origVal)) {
            return new Path(fromNode(), replacement, getIntermediateNodes());
        }
        List<Node> intermediateNodes = new ArrayList<Node>(getIntermediateNodes().size());

        for (Node origNode : getIntermediateNodes()) {
            if (origNode.equals(origVal)) {
                intermediateNodes.add(replacement);
            } else {
                intermediateNodes.add(origNode);
            }
        }
        return new Path(fromNode(), toNode(), intermediateNodes);
    }

    /**
     * Returns intermediate nodes
     * @return
     */
    public List<Node> getIntermediateNodes() {
        return intermediateNodes;
    }

    /**
     * Returns source node
     * @return
     */
    public Node fromNode() {
        return sdp.getSrcNode();
    }

    /**
     * Returns destination node
     * @return
     */
    public Node toNode() {
        return sdp.getDestNode();
    }

    /**
     * Retrunrs no. of nodes
     * @return
     */
    public int numNodes() {
        return intermediateNodes.size() + 2;
    }

    /**
     * Returns whether this object is equal to obj or not
     * @param obj
     * @return
     */
    public boolean equals(Object obj) {
        if (this == obj) {
            return true;
        }
        if (!(obj instanceof Path)) {
            return false;
        }
        Path otherPath = (Path) obj;
        return otherPath.fromNode().equals(fromNode()) && otherPath.toNode().equals(toNode())
                && otherPath.getIntermediateNodes().equals(getIntermediateNodes());
    }

    /**
     * Returns hashCode
     * @return
     */
    public int hashCode() {
        if (hashCode == 0) {
            hashCode = new HashCodeBuilder().append(fromNode()).append(toNode()).append(getIntermediateNodes())
                    .toHashCode();
        }
        return hashCode;
    }

    /**
     * String form of object
     * @return
     */
    public String toString() {
        String delim = "#";
        String s = fromNode().toString();
        for (Node intermediateNode : getIntermediateNodes()) {
            s += delim + intermediateNode;
        }
        s += delim + toNode();
        return s;
    }
}