package org.codehaus.plexus.util.dag;

/*
 * Copyright The Codehaus Foundation.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

import java.io.Serializable;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Set;

DAG = Directed Acyclic Graph
Author:Michal Maczka
Version:$Id$ TODO this class should be renamed from DAG to Dag
/** * DAG = Directed Acyclic Graph * * @author <a href="michal.maczka@dimatics.com">Michal Maczka</a> * @version $Id$ * TODO this class should be renamed from DAG to Dag */
public class DAG implements Cloneable, Serializable { // ------------------------------------------------------------ // Fields // ------------------------------------------------------------ /** * Nodes will be kept in two data structures at the same time for faster processing */
Maps vertex's label to vertex
/** * Maps vertex's label to vertex */
private Map<String, Vertex> vertexMap = new HashMap<String, Vertex>();
Conatin list of all vertices
/** * Conatin list of all vertices */
private List<Vertex> vertexList = new ArrayList<Vertex>(); // ------------------------------------------------------------ // Constructors // ------------------------------------------------------------ /** * */ public DAG() { super(); } // ------------------------------------------------------------ // Accessors // ------------------------------------------------------------
Returns:
/** * @return */
public List<Vertex> getVertices() { return vertexList; }
Deprecated:instead use getVertices()
/** * @deprecated instead use {@link #getVertices()} */
@Deprecated public List<Vertex> getVerticies() { return getVertices(); } public Set<String> getLabels() { return vertexMap.keySet(); } // ------------------------------------------------------------ // Implementation // ------------------------------------------------------------
Adds vertex to DAG. If vertex of given label already exist in DAG no vertex is added
Params:
  • label – The label of the Vertex
Returns:New vertex if vertex of given label was not present in the DAG or existing vertex if vertex of given label was already added to DAG
/** * Adds vertex to DAG. If vertex of given label already exist in DAG no vertex is added * * @param label The label of the Vertex * @return New vertex if vertex of given label was not present in the DAG or existing vertex if vertex of given * label was already added to DAG */
public Vertex addVertex( final String label ) { Vertex retValue = null; // check if vertex is already in DAG if ( vertexMap.containsKey( label ) ) { retValue = vertexMap.get( label ); } else { retValue = new Vertex( label ); vertexMap.put( label, retValue ); vertexList.add( retValue ); } return retValue; } public void addEdge( final String from, final String to ) throws CycleDetectedException { final Vertex v1 = addVertex( from ); final Vertex v2 = addVertex( to ); addEdge( v1, v2 ); } public void addEdge( final Vertex from, final Vertex to ) throws CycleDetectedException { from.addEdgeTo( to ); to.addEdgeFrom( from ); final List<String> cycle = CycleDetector.introducesCycle( to ); if ( cycle != null ) { // remove edge which introduced cycle removeEdge( from, to ); final String msg = "Edge between '" + from + "' and '" + to + "' introduces to cycle in the graph"; throw new CycleDetectedException( msg, cycle ); } } public void removeEdge( final String from, final String to ) { final Vertex v1 = addVertex( from ); final Vertex v2 = addVertex( to ); removeEdge( v1, v2 ); } public void removeEdge( final Vertex from, final Vertex to ) { from.removeEdgeTo( to ); to.removeEdgeFrom( from ); } public Vertex getVertex( final String label ) { final Vertex retValue = (Vertex) vertexMap.get( label ); return retValue; } public boolean hasEdge( final String label1, final String label2 ) { final Vertex v1 = getVertex( label1 ); final Vertex v2 = getVertex( label2 ); final boolean retValue = v1.getChildren().contains( v2 ); return retValue; }
Params:
  • label –
Returns:
/** * @param label * @return */
public List<String> getChildLabels( final String label ) { final Vertex vertex = getVertex( label ); return vertex.getChildLabels(); }
Params:
  • label –
Returns:
/** * @param label * @return */
public List<String> getParentLabels( final String label ) { final Vertex vertex = getVertex( label ); return vertex.getParentLabels(); }
See Also:
  • clone.clone()
/** * @see java.lang.Object#clone() */
public Object clone() throws CloneNotSupportedException { // this is what's failing.. final Object retValue = super.clone(); return retValue; }
Indicates if there is at least one edge leading to or from vertex of given label
Returns:true if this vertex is connected with other vertex,false otherwise
/** * Indicates if there is at least one edge leading to or from vertex of given label * * @return <code>true</code> if this vertex is connected with other vertex,<code>false</code> otherwise */
public boolean isConnected( final String label ) { final Vertex vertex = getVertex( label ); final boolean retValue = vertex.isConnected(); return retValue; }
Return the list of labels of successor in order decided by topological sort
Params:
  • label – The label of the vertex whose predecessors are searched
Returns:The list of labels. Returned list contains also the label passed as parameter to this method. This label should always be the last item in the list.
/** * Return the list of labels of successor in order decided by topological sort * * @param label The label of the vertex whose predecessors are searched * @return The list of labels. Returned list contains also the label passed as parameter to this method. This label * should always be the last item in the list. */
public List<String> getSuccessorLabels( final String label ) { final Vertex vertex = getVertex( label ); final List<String> retValue; // optimization. if ( vertex.isLeaf() ) { retValue = new ArrayList<String>( 1 ); retValue.add( label ); } else { retValue = TopologicalSorter.sort( vertex ); } return retValue; } }