package org.panlab.software.fstoolkit.workflowcomposer;
/*
* JBoss, Home of Professional Open Source Copyright 2006, Red Hat Middleware
* LLC, and individual contributors by the @authors tag. See the copyright.txt
* in the distribution for a full listing of individual contributors.
*
* This is free software; you can redistribute it and/or modify it under the
* terms of the GNU Lesser General Public License as published by the Free
* Software Foundation; either version 2.1 of the License, or (at your option)
* any later version.
*
* This software is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
* FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
* details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this software; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA, or see the FSF
* site: http://www.fsf.org.
*/
import java.util.ArrayList;
import java.util.List;
/**
* A named graph vertex with optional data.
*
* @author Scott.Stark@jboss.org
* @version $Revision$
* @param <T>
*/
class Vertex<T> {
private List<Edge<T>> incomingEdges;
private List<Edge<T>> outgoingEdges;
private String name;
private boolean mark;
private int markState;
private T data;
/**
* Calls this(null, null).
*/
public Vertex() {
this(null, null);
}
/**
* Create a vertex with the given name and no data
*
* @param n
*/
public Vertex(String n) {
this(n, null);
}
/**
* Create a Vertex with name n and given data
*
* @param n -
* name of vertex
* @param data -
* data associated with vertex
*/
public Vertex(String n, T data) {
incomingEdges = new ArrayList<Edge<T>>();
outgoingEdges = new ArrayList<Edge<T>>();
name = n;
mark = false;
this.data = data;
}
/**
* @return the possibly null name of the vertex
*/
public String getName() {
return name;
}
/**
* @return the possibly null data of the vertex
*/
public T getData() {
return this.data;
}
/**
* @param data
* The data to set.
*/
public void setData(T data) {
this.data = data;
}
/**
* Add an edge to the vertex. If edge.from is this vertex, its an outgoing
* edge. If edge.to is this vertex, its an incoming edge. If neither from or
* to is this vertex, the edge is not added.
*
* @param e -
* the edge to add
* @return true if the edge was added, false otherwise
*/
public boolean addEdge(Edge<T> e) {
if (e.getFrom() == this)
outgoingEdges.add(e);
else if (e.getTo() == this)
incomingEdges.add(e);
else
return false;
return true;
}
/**
* Add an outgoing edge ending at to.
*
* @param to -
* the destination vertex
* @param cost
* the edge cost
*/
public void addOutgoingEdge(Vertex<T> to, int cost) {
Edge<T> out = new Edge<T>(this, to, cost);
outgoingEdges.add(out);
}
/**
* Add an incoming edge starting at from
*
* @param from -
* the starting vertex
* @param cost
* the edge cost
*/
public void addIncomingEdge(Vertex<T> from, int cost) {
Edge<T> out = new Edge<T>(this, from, cost);
incomingEdges.add(out);
}
/**
* Check the vertex for either an incoming or outgoing edge mathcing e.
*
* @param e
* the edge to check
* @return true it has an edge
*/
public boolean hasEdge(Edge<T> e) {
if (e.getFrom() == this)
return incomingEdges.contains(e);
else if (e.getTo() == this)
return outgoingEdges.contains(e);
else
return false;
}
/**
* Remove an edge from this vertex
*
* @param e -
* the edge to remove
* @return true if the edge was removed, false if the edge was not connected
* to this vertex
*/
public boolean remove(Edge<T> e) {
if (e.getFrom() == this)
incomingEdges.remove(e);
else if (e.getTo() == this)
outgoingEdges.remove(e);
else
return false;
return true;
}
/**
*
* @return the count of incoming edges
*/
public int getIncomingEdgeCount() {
return incomingEdges.size();
}
/**
* Get the ith incoming edge
*
* @param i
* the index into incoming edges
* @return ith incoming edge
*/
public Edge<T> getIncomingEdge(int i) {
return incomingEdges.get(i);
}
/**
* Get the incoming edges
*
* @return incoming edge list
*/
public List<Edge<T>> getIncomingEdges() {
return this.incomingEdges;
}
/**
*
* @return the count of incoming edges
*/
public int getOutgoingEdgeCount() {
return outgoingEdges.size();
}
/**
* Get the ith outgoing edge
*
* @param i
* the index into outgoing edges
* @return ith outgoing edge
*/
public Edge<T> getOutgoingEdge(int i) {
return outgoingEdges.get(i);
}
/**
* Get the outgoing edges
*
* @return outgoing edge list
*/
public List<Edge<T>> getOutgoingEdges() {
return this.outgoingEdges;
}
/**
* Search the outgoing edges looking for an edge whose's edge.to == dest.
*
* @param dest
* the destination
* @return the outgoing edge going to dest if one exists, null otherwise.
*/
public Edge<T> findEdge(Vertex<T> dest) {
for (Edge<T> e : outgoingEdges) {
if (e.getTo() == dest)
return e;
}
return null;
}
/**
* Search the outgoing edges for a match to e.
*
* @param e -
* the edge to check
* @return e if its a member of the outgoing edges, null otherwise.
*/
public Edge<T> findEdge(Edge<T> e) {
if (outgoingEdges.contains(e))
return e;
else
return null;
}
/**
* What is the cost from this vertext to the dest vertex.
*
* @param dest -
* the destination vertex.
* @return Return Integer.MAX_VALUE if we have no edge to dest, 0 if dest is
* this vertex, the cost of the outgoing edge otherwise.
*/
public int cost(Vertex<T> dest) {
if (dest == this)
return 0;
Edge<T> e = findEdge(dest);
int cost = Integer.MAX_VALUE;
if (e != null)
cost = e.getCost();
return cost;
}
/**
* Is there an outgoing edge ending at dest.
*
* @param dest -
* the vertex to check
* @return true if there is an outgoing edge ending at vertex, false
* otherwise.
*/
public boolean hasEdge(Vertex<T> dest) {
return (findEdge(dest) != null);
}
/**
* Has this vertex been marked during a visit
*
* @return true is visit has been called
*/
public boolean visited() {
return mark;
}
/**
* Set the vertex mark flag.
*
*/
public void mark() {
mark = true;
}
/**
* Set the mark state to state.
*
* @param state
* the state
*/
public void setMarkState(int state) {
markState = state;
}
/**
* Get the mark state value.
*
* @return the mark state
*/
public int getMarkState() {
return markState;
}
/**
* Visit the vertex and set the mark flag to true.
*
*/
public void visit() {
mark();
}
/**
* Clear the visited mark flag.
*
*/
public void clearMark() {
mark = false;
}
/**
* @return a string form of the vertex with in and out edges.
*/
public String toString() {
StringBuffer tmp = new StringBuffer("Vertex(");
tmp.append(name);
tmp.append(", data=");
tmp.append(data);
tmp.append("), in:[");
for (int i = 0; i < incomingEdges.size(); i++) {
Edge<T> e = incomingEdges.get(i);
if (i > 0)
tmp.append(',');
tmp.append('{');
tmp.append(e.getFrom().name);
tmp.append(',');
tmp.append(e.getCost());
tmp.append('}');
}
tmp.append("], out:[");
for (int i = 0; i < outgoingEdges.size(); i++) {
Edge<T> e = outgoingEdges.get(i);
if (i > 0)
tmp.append(',');
tmp.append('{');
tmp.append(e.getTo().name);
tmp.append(',');
tmp.append(e.getCost());
tmp.append('}');
}
tmp.append(']');
return tmp.toString();
}
}