package edu.brown.graphs;
import java.util.Set;
import org.json.JSONException;
import org.json.JSONObject;
import org.json.JSONStringer;
import org.voltdb.catalog.Database;
import edu.brown.utils.StringUtil;
import edu.uci.ics.jung.graph.util.EdgeType;
/**
*
* @author pavlo
*
*/
public class AbstractEdge extends AbstractGraphElement {
public enum Members {
VERTEX0,
VERTEX1,
TYPE,
}
protected final IGraph<AbstractVertex, AbstractEdge> graph;
/**
* Base constructor
* @param graph
* @param vertices
*/
@SuppressWarnings("unchecked")
public AbstractEdge(IGraph<? extends AbstractVertex, ? extends AbstractEdge> graph) {
super();
this.graph = (IGraph<AbstractVertex, AbstractEdge>)graph;
}
/**
* Copy constructor
* @param graph
* @param copy
*/
@SuppressWarnings("unchecked")
public AbstractEdge(IGraph<? extends AbstractVertex, ? extends AbstractEdge> graph, AbstractEdge copy) {
super(graph, copy);
this.graph = (IGraph<AbstractVertex, AbstractEdge>)graph;
//this.vertices = copy.vertices;
}
/**
*
* @return
*/
public IGraph<AbstractVertex, AbstractEdge> getGraph() {
return this.graph;
}
@SuppressWarnings("unchecked")
public <T> T getAttribute(String key) {
// System.out.println("EDGE-GET[" + this.graph + "]: " + key);
return (T)this.getAttribute(this.graph, key);
}
@SuppressWarnings("unchecked")
public <T, E extends Enum<?>> T getAttribute(E e) {
return ((T)this.getAttribute(this.graph, e));
}
public Set<String> getAttributes() {
return this.getAttributes(this.graph);
}
public void setAttribute(String key, Object value) {
this.setAttribute(this.graph, key, value);
}
public <E extends Enum<?>> void setAttribute(E e, Object value) {
this.setAttribute(e.name(), value);
}
public boolean hasAttribute(String key) {
return this.hasAttribute(this.graph, key);
}
@SuppressWarnings("unchecked")
public <V extends AbstractVertex, E extends AbstractEdge> String toStringPath(IGraph<V, E> graph) {
String delimiter = "";
V v0 = null;
V v1 = null;
switch (graph.getEdgeType((E)this)) {
case DIRECTED:
delimiter = "->";
v0 = graph.getSource((E)this);
v1 = graph.getDest((E)this);
break;
case UNDIRECTED:
delimiter = "--";
for (V v : graph.getIncidentVertices((E)this)) {
if (v0 == null) v0 = v;
else v1 = v;
} // FOR
} // SWITCH
return (v0 + delimiter + v1);
}
public String toString(boolean verbose) {
return (this.graph.toString(this, verbose));
}
@Override
public String toString() {
return (this.toString(this.getVerbose()));
}
@Override
public String debug() {
String ret = super.debug() + "\n";
ret += StringUtil.SPACER + " GRAPH: " + this.graph;
return (ret);
}
@Override
protected void toJSONStringImpl(JSONStringer stringer) throws JSONException {
Members elements[] = new Members[] { Members.VERTEX0, Members.VERTEX1 };
int idx = 0;
for (AbstractVertex v : this.graph.getIncidentVertices(this)) {
assert(v != null);
stringer.key(elements[idx++].name()).value(v.getElementId());
} // FOR
// Only store the first character of the edge type (U, D)
EdgeType edge_type = this.graph.getEdgeType(this);
stringer.key(Members.TYPE.name()).value(edge_type.name().subSequence(0, 1));
}
@Override
protected void fromJSONObjectImpl(JSONObject object, Database catalog_db) throws JSONException {
Long v0_elementId = object.getLong(Members.VERTEX0.name());
AbstractVertex v0 = this.graph.getVertex(v0_elementId);
assert(v0 != null) : "Invalid vertex element id '" + v0_elementId + "' (0)";
Long v1_elementId = object.getLong(Members.VERTEX1.name());
AbstractVertex v1 = this.graph.getVertex(v1_elementId);
assert(v1 != null) : "Invalid vertex element id '" + v1_elementId + "' (1)";
// Edge Type
String edge_type_key = object.getString(Members.TYPE.name());
EdgeType edge_type = null;
for (EdgeType e : EdgeType.values()) {
if (e.name().startsWith(edge_type_key)) {
edge_type = e;
break;
}
} // FOR
assert(edge_type != null) : "Invalid edge type key '" + edge_type_key + "'";
this.graph.addEdge(this, v0, v1, edge_type);
}
} // END CLASS