Skip to content

Instantly share code, notes, and snippets.

@banthar
Created March 19, 2015 20:33
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save banthar/a911b98b56b1e241fa76 to your computer and use it in GitHub Desktop.
Save banthar/a911b98b56b1e241fa76 to your computer and use it in GitHub Desktop.
package dependencies;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.PrintStream;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Iterator;
import java.util.Map;
import java.util.Map.Entry;
import java.util.Set;
import org.eclipse.core.runtime.Platform;
import org.eclipse.equinox.app.IApplication;
import org.eclipse.equinox.app.IApplicationContext;
import org.osgi.framework.Bundle;
import org.osgi.framework.wiring.BundleWire;
import org.osgi.framework.wiring.BundleWiring;
public class Application implements IApplication {
public Object start(IApplicationContext context) throws Exception {
Bundle bundle = Platform.getBundle("org.eclipse.osgi");
Bundle[] bundles = bundle.getBundleContext().getBundles();
Map<String,Set<String>> nodes = new HashMap<String,Set<String>>();
Map<String,Integer> sizes = new HashMap<String,Integer>();
for (Bundle b : bundles) {
BundleWiring wiring = b.adapt(BundleWiring.class);
Set<String> dependencies = new HashSet<>();
for (BundleWire r : wiring.getRequiredWires(null)) {
dependencies.add(r.getProvider().getSymbolicName());
}
dependencies.remove(b.getSymbolicName());
nodes.put(b.getSymbolicName(), dependencies);
sizes.put(b.getSymbolicName(), wiring.listResources("/", "*.class", BundleWiring.LISTRESOURCES_RECURSE).size());
}
optimize(nodes);
dump(nodes,sizes);
return IApplication.EXIT_OK;
}
private void travel(Map<String, Set<String>> nodes, Set<String> visited, String p) {
for(String next : nodes.get(p) ){
if(visited.add(next)) {
travel(nodes,visited,next);
}
}
}
private boolean dependsOn(Map<String, Set<String>> nodes, String from, String to) {
HashSet<String> visited = new HashSet<>();
travel(nodes,visited, from);
return visited.contains(to);
}
private void optimize(Map<String, Set<String>> nodes) {
for(String n : nodes.keySet() ){
Set<String> directions = nodes.get(n);
for(Iterator<String> iterator = directions.iterator();iterator.hasNext();) {
String k = iterator.next();
Set<String> visited = new HashSet<String>();
for(String p : directions) {
if(k!=p) {
travel(nodes, visited, p);
}
}
if(visited.contains(k)) {
iterator.remove();
}
}
}
}
private void dump(Map<String, Set<String>> nodes, Map<String, Integer> sizes) throws FileNotFoundException {
PrintStream out = new PrintStream(new File("/tmp/dependencies/dependencies.dot"));
out.println("digraph dependencies {");
out.println("node [style = filled, shape = circle, fixedsize=true] ");
for(String n : nodes.keySet()) {
Set<String> flags = new HashSet<>();
if(dependsOn(nodes,n,"org.eclipse.swt")) {
flags.add("color=red");
} else {
flags.add("color=green");
}
flags.add("width="+0.1*Math.sqrt(sizes.get(n)));
out.println("\""+n+"\" "+flags+";");
}
for(Entry<String, Set<String>> e : nodes.entrySet()) {
for(String n : e.getValue()) {
out.println("\t\""+e.getKey()+"\"->\""+n+"\";");
}
}
out.println("}");
out.close();
}
public void stop() {
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment