/*
* CCVisu is a tool for visual graph clustering
* and general force-directed graph layout.
* This file is part of CCVisu.
*
* Copyright (C) 2005-2012 Dirk Beyer
*
* CCVisu 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 2.1 of the License, or (at your option) any later version.
*
* CCVisu 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 CCVisu; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*
* Please find the GNU Lesser General Public License in file
* license_lgpl.txt or http://www.gnu.org/licenses/lgpl.txt
*
* Dirk Beyer (firstname.lastname@uni-passau.de)
* University of Passau, Bavaria, Germany
*/
package org.sosy_lab.ccvisu.measuring.calldep;
import java.util.ArrayList;
import java.util.Collections;
import java.util.EventObject;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import org.sosy_lab.ccvisu.InformationCollector;
import org.sosy_lab.ccvisu.Options;
import org.sosy_lab.ccvisu.Options.OptionsEnum;
import org.sosy_lab.ccvisu.Options.Verbosity;
import org.sosy_lab.ccvisu.graph.GraphData;
import org.sosy_lab.ccvisu.graph.GraphEdge;
import org.sosy_lab.ccvisu.graph.GraphVertex;
import org.sosy_lab.ccvisu.graph.NameVisibility;
import org.sosy_lab.ccvisu.measuring.calldep.colors.ColorProvider;
import org.sosy_lab.ccvisu.measuring.calldep.colors.VertexColoring;
import org.sosy_lab.util.ProgressingBase;
import org.sosy_lab.util.interfaces.Progressing;
public class DependencyCalculator extends ProgressingBase implements Runnable, Progressing {
private GraphData graph;
private Options options;
public DependencyCalculator(GraphData graph, Options options) {
this.graph = graph;
this.options = options;
}
public void calculateAndSetDegree() {
if (graph.getEdges().isEmpty()) {
if (options.verbosity.isAtLeast(Verbosity.WARNING)) {
System.err.println("Warning: Cannot perform measurement analysis on "
+ "empty graph.");
}
return;
}
List<VertexContainer> vertexList = getListOfVertexContainers();
// normalize
Collections.sort(vertexList);
double max = vertexList.get(vertexList.size() - 1).getVertexMeasure();
double min = vertexList.get(0).getVertexMeasure();
double sum = 0;
VertexColoring coloring = ColorProvider.getInstance().getColoringObject(
options.getOption(OptionsEnum.dependencyColoring).getString(), min, max);
for (VertexContainer vertexContainer : vertexList) {
GraphVertex vertex = vertexContainer.getVertex();
vertex.setColor(coloring.getColor(vertexContainer.getVertexMeasure()));
vertex.setTooltip(vertexContainer.getMeasureName() + ": "
+ String.valueOf(vertexContainer.getVertexMeasure()));
sum += vertexContainer.getVertexMeasure();
// disable showing of labels from previous runs of the algorithm
vertex.unsetShowName(NameVisibility.Priority.DEPDEGREE);
}
// show labels
int numberOfShownLabels = options.getOption(OptionsEnum.dependencyShowLabels).getInt();
Collections.reverse(vertexList);
Iterator<VertexContainer> iterator = vertexList.iterator();
for (int i = 0; i < numberOfShownLabels && iterator.hasNext(); i++) {
iterator.next().getVertex().setShowName(NameVisibility.Priority.DEPDEGREE, true);
}
InformationCollector infos = options.infoCollector;
infos.addMessage("");
infos.addMessage(String.format("Overall dependency degree: %.2f", sum));
infos.addMessage(String.format("Minimum dependency: %.2f", min));
infos.addMessage(String.format("Maximum dependency: %.2f", max));
setProgress(0, 0, "Analysis finished.");
graph.notifyAboutLayoutChange(new EventObject(this));
}
public List<VertexContainer> getListOfVertexContainers() {
graph.getVertices();
List<GraphEdge> edges = graph.getEdges();
Map<GraphVertex, VertexContainer> vertices =
new HashMap<GraphVertex, VertexContainer>(graph.getVertices().size());
String algorithmName = options.getOption(OptionsEnum.dependencyAlgorithm).getString();
for (GraphVertex vertex : graph.getVertices()) {
if (algorithmName.equals(OutdegreeVertexContainer.ALGORITHM_NAME)) {
vertices.put(vertex, new OutdegreeVertexContainer(vertex));
} else if (algorithmName.equals(DistanceVertexContainer.ALGORITHM_NAME)) {
vertices.put(vertex, new DistanceVertexContainer(vertex));
} else { // default
vertices.put(vertex, new DistanceVertexContainer(vertex));
}
}
for (GraphEdge edge : edges) {
vertices.get(edge.getSource()).addEdge(edge);
}
return new ArrayList<VertexContainer>(vertices.values());
}
@Override
public void run() {
calculateAndSetDegree();
}
}