/* * SonarQube, open source software quality management tool. * Copyright (C) 2008-2014 SonarSource * mailto:contact AT sonarsource DOT com * * SonarQube 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 3 of the License, or (at your option) any later version. * * SonarQube 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 program; if not, write to the Free Software Foundation, * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ package org.sonar.graph; import java.util.ArrayList; import java.util.Collection; import java.util.HashMap; import java.util.HashSet; import java.util.List; import java.util.Map; import java.util.Set; public class DirectedGraph> implements DirectedGraphAccessor { private EdgeFactory edgeFactory; private Map> outgoingEdgesByVertex = new HashMap>(); private Map> incomingEdgesByVertex = new HashMap>(); private Set vertices = new HashSet(); public DirectedGraph() { } public DirectedGraph(EdgeFactory edgeFactory) { this.edgeFactory = edgeFactory; } public static DirectedGraph createStringDirectedGraph() { return new DirectedGraph(new StringEdgeFactory()); } public DirectedGraph addEdge(V from, V to) { checkEdgeFacory(); E edge = edgeFactory.createEdge(from, to); return addEdge(edge); } public DirectedGraph addEdge(V from, V to, int weight) { checkEdgeFacory(); E edge = edgeFactory.createEdge(from, to, weight); return addEdge(edge); } private void checkEdgeFacory() { if (edgeFactory == null) { throw new IllegalStateException( "EdgeFactory has not been defined. Please use the 'public E addEdge(V from, V to, E edge)' method."); } } public DirectedGraph addEdge(E edge) { addEdgeToMap(edge.getFrom(), edge.getTo(), edge, outgoingEdgesByVertex); addEdgeToMap(edge.getTo(), edge.getFrom(), edge, incomingEdgesByVertex); vertices.add(edge.getFrom()); vertices.add(edge.getTo()); return this; } private void addEdgeToMap(V vertexKey1, V vertexKey2, E edge, Map> edgesByVertex) { Map edges = edgesByVertex.get(vertexKey1); if (edges == null) { edges = new HashMap(); edgesByVertex.put(vertexKey1, edges); } if (edges.containsKey(vertexKey2)) { throw new IllegalStateException("The graph already contains the edge : " + edge); } edges.put(vertexKey2, edge); } public E getEdge(V from, V to) { Map outgoingEdgesFrom = outgoingEdgesByVertex.get(from); if (outgoingEdgesFrom == null) { return null; } else { return outgoingEdgesFrom.get(to); } } public boolean hasEdge(V from, V to) { Map outgoingEdges = outgoingEdgesByVertex.get(from); if (outgoingEdges == null) { return false; } return outgoingEdges.containsKey(to); } public void addVertex(V vertex) { vertices.add(vertex); } public void addVertices(Collection vertices) { for (V vertex : vertices) { addVertex(vertex); } } public Set getVertices() { return vertices; } public List getEdges(Collection vertices) { List result = new ArrayList(); for (V vertice : vertices) { Collection outgoingEdges = getOutgoingEdges(vertice); if (outgoingEdges != null) { result.addAll(outgoingEdges); } } return result; } public Collection getOutgoingEdges(V from) { Map outgoingEdges = outgoingEdgesByVertex.get(from); if (outgoingEdges == null) { return new HashSet(); } return outgoingEdges.values(); } public Collection getIncomingEdges(V to) { Map incomingEdges = incomingEdgesByVertex.get(to); if (incomingEdges == null) { return new HashSet(); } return incomingEdges.values(); } }