org.jgrapht.graph.guava.BaseNetworkAdapter Maven / Gradle / Ivy
/*
* (C) Copyright 2018-2018, by Dimitrios Michail and Contributors.
*
* JGraphT : a free Java graph-theory library
*
* This program and the accompanying materials are dual-licensed under
* either
*
* (a) the terms of the GNU Lesser General Public License version 2.1
* as published by the Free Software Foundation, or (at your option) any
* later version.
*
* or (per the licensee's choosing)
*
* (b) the terms of the Eclipse Public License v1.0 as published by
* the Eclipse Foundation.
*/
package org.jgrapht.graph.guava;
import com.google.common.graph.*;
import org.jgrapht.*;
import org.jgrapht.Graph;
import org.jgrapht.graph.AbstractGraph;
import org.jgrapht.graph.*;
import java.io.*;
import java.util.*;
import java.util.function.*;
/**
* A base abstract implementation for the graph adapter class using Guava's {@link Network}. This is
* a helper class in order to support both mutable and immutable networks.
*
* @author Dimitrios Michail
*
* @param the graph vertex type
* @param the graph edge type
* @param type of the underlying Guava's network
*/
public abstract class BaseNetworkAdapter>
extends
AbstractGraph
implements
Graph,
Cloneable,
Serializable
{
private static final long serialVersionUID = -6233085794632237761L;
protected static final String LOOPS_NOT_ALLOWED = "loops not allowed";
protected transient Set unmodifiableVertexSet = null;
protected transient Set unmodifiableEdgeSet = null;
protected Supplier vertexSupplier;
protected Supplier edgeSupplier;
protected transient N network;
/**
* Create a new network adapter.
*
* @param network the mutable network
*/
public BaseNetworkAdapter(N network)
{
this(network, null, null);
}
/**
* Create a new network adapter.
*
* @param network the mutable network
* @param vertexSupplier the vertex supplier
* @param edgeSupplier the edge supplier
*/
public BaseNetworkAdapter(N network, Supplier vertexSupplier, Supplier edgeSupplier)
{
this.vertexSupplier = vertexSupplier;
this.edgeSupplier = edgeSupplier;
this.network = Objects.requireNonNull(network);
}
@Override
public Supplier getVertexSupplier()
{
return vertexSupplier;
}
/**
* Set the vertex supplier that the graph uses whenever it needs to create new vertices.
*
*
* A graph uses the vertex supplier to create new vertex objects whenever a user calls method
* {@link Graph#addVertex()}. Users can also create the vertex in user code and then use method
* {@link Graph#addVertex(Object)} to add the vertex.
*
*
* In contrast with the {@link Supplier} interface, the vertex supplier has the additional
* requirement that a new and distinct result is returned every time it is invoked. More
* specifically for a new vertex to be added in a graph v
must not be equal
* to any other vertex in the graph. More formally, the graph must not contain any vertex
* v2
such that v2.equals(v)
.
*
* @param vertexSupplier the vertex supplier
*/
public void setVertexSupplier(Supplier vertexSupplier)
{
this.vertexSupplier = vertexSupplier;
}
@Override
public Supplier getEdgeSupplier()
{
return edgeSupplier;
}
/**
* Set the edge supplier that the graph uses whenever it needs to create new edges.
*
*
* A graph uses the edge supplier to create new edge objects whenever a user calls method
* {@link Graph#addEdge(Object, Object)}. Users can also create the edge in user code and then
* use method {@link Graph#addEdge(Object, Object, Object)} to add the edge.
*
*
* In contrast with the {@link Supplier} interface, the edge supplier has the additional
* requirement that a new and distinct result is returned every time it is invoked. More
* specifically for a new edge to be added in a graph e
must not be equal to
* any other edge in the graph (even if the graph allows edge-multiplicity). More formally, the
* graph must not contain any edge e2
such that e2.equals(e)
.
*
* @param edgeSupplier the edge supplier
*/
public void setEdgeSupplier(Supplier edgeSupplier)
{
this.edgeSupplier = edgeSupplier;
}
@Override
public E getEdge(V sourceVertex, V targetVertex)
{
return network
.edgesConnecting(sourceVertex, targetVertex).stream().findFirst().orElse(null);
}
@Override
public Set vertexSet()
{
if (unmodifiableVertexSet == null) {
unmodifiableVertexSet = Collections.unmodifiableSet(network.nodes());
}
return unmodifiableVertexSet;
}
@Override
public V getEdgeSource(E e)
{
return network.incidentNodes(e).nodeU();
}
@Override
public V getEdgeTarget(E e)
{
return network.incidentNodes(e).nodeV();
}
@Override
public GraphType getType()
{
return (network.isDirected() ? new DefaultGraphType.Builder().directed()
: new DefaultGraphType.Builder().undirected())
.weighted(false).allowMultipleEdges(network.allowsParallelEdges())
.allowSelfLoops(network.allowsSelfLoops()).build();
}
@Override
public boolean containsEdge(E e)
{
return network.edges().contains(e);
}
@Override
public boolean containsVertex(V v)
{
return network.nodes().contains(v);
}
@Override
public Set edgeSet()
{
if (unmodifiableEdgeSet == null) {
unmodifiableEdgeSet = Collections.unmodifiableSet(network.edges());
}
return unmodifiableEdgeSet;
}
@Override
public int degreeOf(V vertex)
{
return network.degree(vertex);
}
@Override
public Set edgesOf(V vertex)
{
return network.incidentEdges(vertex);
}
@Override
public int inDegreeOf(V vertex)
{
return network.inDegree(vertex);
}
@Override
public Set incomingEdgesOf(V vertex)
{
return network.inEdges(vertex);
}
@Override
public int outDegreeOf(V vertex)
{
return network.outDegree(vertex);
}
@Override
public Set outgoingEdgesOf(V vertex)
{
return network.outEdges(vertex);
}
@Override
public double getEdgeWeight(E e)
{
if (e == null) {
throw new NullPointerException();
} else if (!network.edges().contains(e)) {
throw new IllegalArgumentException("no such edge in graph: " + e.toString());
} else {
return Graph.DEFAULT_EDGE_WEIGHT;
}
}
@Override
public Set getAllEdges(V sourceVertex, V targetVertex)
{
return network.edgesConnecting(sourceVertex, targetVertex);
}
}