net.sf.javagimmicks.graph.MapGraphBuilder Maven / Gradle / Ivy
package net.sf.javagimmicks.graph;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Map;
import java.util.Set;
import net.sf.javagimmicks.util.Supplier;
/**
* A builder for creating {@link MapGraph} instances using a fluent API.
*
* A {@link MapGraph} needs three things for internal operation:
*
* - The core {@link Map} of vertices to a {@link Set} of {@link Edge}s - can
* be provided via {@link #setEdgeMap(Map)}
* - A {@link Supplier} creating new {@link Set} instances for {@link Edge}s -
* can be provided via {@link #setEdgeSetFactory(Supplier)}
* - An {@link EdgeFactory} for creating new {@link Edge} instances - can be
* provided via {@link #setEdgeFactory(EdgeFactory)}
*
* If nothing else is provided by the client, {@link MapGraphBuilder} uses by
* default a {@link HashMap} for {@code 1.} and a {@link Supplier} creating
* {@link HashSet}s for {@code 2.} - for {@code 3.} the client must
* provide an instance.
*
* Additionally, it can be configured, if the generated {@link MapGraph} runs in
* directed or non-directed mode (see {@link MapGraph#isDirected()}) using
* {@link #setDirected(boolean)}.
*
* Attention: this class is not thread-safe
*
* @param
* the type of vertices that the built {@link Graph}s can carry
* @param
* the type of {@link Edge}s that the built {@link Graph}s can carry
*/
public class MapGraphBuilder>
{
protected boolean _directed = false;
protected Map> _edgeMap = new HashMap>();
protected Supplier extends Set> _edgeSetFactory = new HashSetFactory();
protected EdgeFactory _edgeFactory;
/**
* Creates a new {@link MapGraphBuilder} using the {@link #MapGraphBuilder()
* default constructor} and applies a {@link DefaultEdgeFactory} for
* {@link #setEdgeFactory(EdgeFactory)}.
*
* @param
* the type of vertices that the built {@link Graph}s can carry
* @return the new {@link MapGraphBuilder}
*/
public static MapGraphBuilder> withDefaultEdgeFactory()
{
return new MapGraphBuilder>()
.setEdgeFactory(new DefaultEdgeFactory());
}
/**
* Creates a new {@link MapGraphBuilder} using the {@link #MapGraphBuilder()
* default constructor} and applies a {@link DefaultValuedEdgeFactory} for
* {@link #setEdgeFactory(EdgeFactory)}.
*
* @param
* the type of vertices that the built {@link Graph}s can carry
* @param
* the type of values that the built {@link Graph}s can carry
* @return the new {@link MapGraphBuilder}
*/
public static MapGraphBuilder> withDefaultValuedEdgeFactory()
{
return new MapGraphBuilder>()
.setEdgeFactory(new DefaultValuedEdgeFactory());
}
/**
* Creates a new instance with a internal {@link HashMap}, a {@link HashSet}
* creating {@link Supplier} and for non-directed mode.
*/
public MapGraphBuilder()
{}
/**
* Builds the final {@link MapGraph} using the internal {@link Map},
* {@link Set} for {@link Edge}s and {@link EdgeFactory}.
*
* Attention: this method can be used multiple times on the same
* instance for creating many {@link MapGraph}s, but between calls, a new
* internal {@link Map} must be provided via {@link #setEdgeMap(Map)}.
*
* @return the resulting {@link MapGraph}
* @throws IllegalStateException
* if one of the necessary internal objects is (still)
* {@code null}
*/
public MapGraph build()
{
if (_edgeFactory == null)
{
throw new IllegalStateException("No EdgeFactory set!");
}
if (_edgeMap == null)
{
throw new IllegalStateException("No Edge-Map set!");
}
if (_edgeSetFactory == null)
{
throw new IllegalStateException("No Edge-Set-Factory set!");
}
final Map> edgeMap = _edgeMap;
_edgeMap = null;
return new MapGraph(edgeMap, _edgeSetFactory, _edgeFactory, _directed);
}
/**
* Returns if generated {@link MapGraph}s will run in directed or
* non-directed mode.
*
* @return if generated {@link MapGraph}s will run in directed or
* non-directed mode
* @see MapGraph#isDirected()
*/
public boolean isDirected()
{
return _directed;
}
/**
* Returns the {@link Map} that the generated {@link MapGraph}s will
* internally use.
*
* @return the {@link Map} that the generated {@link MapGraph}s will
* internally use
*/
public Map> getEdgeMap()
{
return _edgeMap;
}
/**
* Returns the {@link Supplier} for {@link Edge}-{@link Set}s that the
* generated {@link MapGraph}s will internally use.
*
* @return the {@link Supplier} for {@link Edge}-{@link Set}s that the
* generated {@link MapGraph}s will internally use
*/
public Supplier extends Set> getEdgeSetFactory()
{
return _edgeSetFactory;
}
/**
* Returns the {@link EdgeFactory} that the generated {@link MapGraph}s will
* internally use.
*
* @return the {@link EdgeFactory} that the generated {@link MapGraph}s will
* internally use
*/
public EdgeFactory getEdgeFactory()
{
return _edgeFactory;
}
/**
* Sets if generated {@link MapGraph}s will run in directed or non-directed
* mode.
*
* @param directed
* if generated {@link MapGraph}s will run in directed or
* non-directed mode
* @return the {@link MapGraphBuilder} itself
* @see MapGraph#isDirected()
*/
public MapGraphBuilder setDirected(final boolean directed)
{
_directed = directed;
return this;
}
/**
* Sets the {@link Map} that the next generated {@link MapGraph} will
* internally use.
*
* @param edgeMap
* the {@link Map} that the next generated {@link MapGraph} will
* internally use
* @return the {@link MapGraphBuilder} itself
*/
public MapGraphBuilder setEdgeMap(final Map> edgeMap)
{
_edgeMap = edgeMap;
return this;
}
/**
* Sets the {@link Supplier} for {@link Edge}-{@link Set}s that generated
* {@link MapGraph}s will internally use.
*
* @param edgeSetFactory
* the {@link Supplier} for {@link Edge}-{@link Set}s that
* generated {@link MapGraph}s will internally use
* @return the {@link MapGraphBuilder} itself
*/
public MapGraphBuilder setEdgeSetFactory(final Supplier extends Set> edgeSetFactory)
{
_edgeSetFactory = edgeSetFactory;
return this;
}
/**
* Sets the {@link EdgeFactory} that generated {@link MapGraph}s will
* internally use.
*
* @param edgeFactory
* the {@link EdgeFactory} that generated {@link MapGraph}s will
* internally use
* @return the {@link MapGraphBuilder} itself
*/
public MapGraphBuilder setEdgeFactory(final EdgeFactory edgeFactory)
{
_edgeFactory = edgeFactory;
return this;
}
private static class HashSetFactory implements Supplier>
{
@Override
public Set get()
{
return new HashSet();
}
}
}