added d3 example

This commit is contained in:
Sander Hautvast 2014-09-30 12:54:25 +02:00
parent 38c511cdda
commit ff2e2627ca
7 changed files with 323 additions and 0 deletions

View file

@ -0,0 +1,14 @@
package yooze;
@SuppressWarnings("serial")
public class ClassNotScannable extends RuntimeException {
public ClassNotScannable(String message) {
super(message);
}
public ClassNotScannable(Throwable cause) {
super(cause);
}
}

View file

@ -0,0 +1,70 @@
package yooze;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
public class InclusionDecider {
private static Logger log = LoggerFactory.getLogger(InclusionDecider.class);
private Pattern[] packageIncludePatterns;
private Pattern[] packageExcludePatterns;
public boolean shouldSkip(String className) {
if (!isIncluded(className)) {
log.debug("skipping {}", className);
return true;
}
if (isExcluded(className)) {
log.debug("skipping {}", className);
return true;
}
return false;
}
public boolean isExcluded(String className) {
if (packageExcludePatterns != null) {
for (Pattern excludePattern : packageExcludePatterns) {
Matcher matcher = excludePattern.matcher(className);
if (matcher.find()) {
return true;
}
}
}
return false;
}
public boolean isIncluded(String className) {
if (packageIncludePatterns != null) {
for (Pattern includePattern : packageIncludePatterns) {
Matcher matcher = includePattern.matcher(className);
if (matcher.find()) {
return true;
}
}
}
return false;
}
public void setPackageIncludePatterns(String... packageIncludePatterns) {
if (packageIncludePatterns != null) {
this.packageIncludePatterns = new Pattern[packageIncludePatterns.length];
int i = 0;
for (String pattern : packageIncludePatterns) {
this.packageIncludePatterns[i++] = Pattern.compile(pattern);
}
}
}
public void setPackageExcludePatterns(String... packageExcludePatterns) {
if (packageExcludePatterns != null) {
this.packageExcludePatterns = new Pattern[packageExcludePatterns.length];
int i = 0;
for (String pattern : packageExcludePatterns) {
this.packageExcludePatterns[i++] = Pattern.compile(pattern);
}
}
}
}

View file

@ -0,0 +1,130 @@
package yooze.application;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.ConcurrentHashMap;
import javax.annotation.PostConstruct;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.EnableAutoConfiguration;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;
import yooze.ClassCache;
import yooze.ClassModelBuilder;
import yooze.GraphBuilder;
import yooze.InclusionDecider;
import yooze.domain.ClassModel;
import yooze.domain.Graph;
@Configuration
@EnableAutoConfiguration
@ComponentScan
@Controller
public class YoozeServer {
private Graph raw;
private ClassCache classCache;
@RequestMapping("/graph")
@ResponseBody
public NodesAndLinks nodesAndLinks() {
ConcurrentHashMap<ClassModel, Integer> classes = new ConcurrentHashMap<ClassModel, Integer>();
int i = 0;
List<Node> nodes = new ArrayList<Node>();
List<Link> links = new ArrayList<Link>();
for (ClassModel classModel : classCache.values()) {
classes.put(classModel, i++);
nodes.add(new Node(classModel.getName().substring(classModel.getName().lastIndexOf(".") + 1)));
}
for (ClassModel classModel : classCache.values()) {
for (ClassModel ref : classModel.getReferences()) {
links.add(new Link(classes.get(classModel), classes.get(ref)));
}
}
return new NodesAndLinks(nodes, links);
}
@RequestMapping("/raw")
@ResponseBody
public Graph raw() {
return raw;
}
static class NodesAndLinks {
private List<Node> nodes;
private List<Link> links;
public NodesAndLinks(List<Node> nodes, List<Link> links) {
super();
this.nodes = nodes;
this.links = links;
}
public List<Link> getLinks() {
return links;
}
public List<Node> getNodes() {
return nodes;
}
}
static class Node {
String name;
public Node(String name) {
super();
this.name = name;
}
public String getName() {
return name;
}
}
static class Link {
private int source, target;
public Link(int source, int target) {
super();
this.source = source;
this.target = target;
}
public int getSource() {
return source;
}
public int getTarget() {
return target;
}
}
@PostConstruct
public void startup() throws IOException {
InclusionDecider i = new InclusionDecider();
i.setPackageExcludePatterns("java\\.", ".*Regelkosten", "org\\.", "dao", "\\$");
i.setPackageIncludePatterns("Service$", "ServiceImpl$", "ServiceBean$", "Handelingen$");
GraphBuilder directoryBuilder = GraphBuilderFactory.getJarBuilder();
classCache = new ClassCache();
classCache.setInclusionDecider(i);
ClassModelBuilder classModelBuilder = new ClassModelBuilder();
classModelBuilder.setClassCache(classCache);
directoryBuilder.setClassModelBuilder(classModelBuilder);
classModelBuilder.setInclusionDecider(i);
raw = directoryBuilder.build("src/test/resources/trc-common-core-1.0.jar", null);
}
public static void main(String[] args) {
SpringApplication.run(YoozeServer.class, args);
}
}

View file

@ -0,0 +1,29 @@
package yooze.scanner;
import java.io.File;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import java.util.jar.JarFile;
import yooze.InspectableClasspath;
import yooze.Scanner;
/**
* reads classes as .class files from a directory
*/
public class JarScanner implements Scanner {
@Override
public List<InspectableClasspath> scanArchive(String archiveName) throws IOException {
return scanArchive(new File(archiveName));
}
@Override
public List<InspectableClasspath> scanArchive(File file) throws IOException {
List<InspectableClasspath> result = new ArrayList<InspectableClasspath>();
result.add(new JarClassPath(new JarFile(file)));
return result;
}
}

5
src/main/webapp/d3.v3.min.js vendored Normal file

File diff suppressed because one or more lines are too long

View file

@ -0,0 +1,75 @@
<!DOCTYPE html>
<meta charset="utf-8">
<style>
.node {
stroke: #000;
stroke-width: 1.5px;
}
.link {
stroke: #999;
stroke-opacity: .6;
}
</style>
<body>
<script src="d3.v3.min.js"></script>
<script>
var width = 1500,
height = 1000;
var color = d3.scale.category20();
var force = d3.layout.force()
.charge(-350)
.linkDistance(150)
.size([width, height]);
var svg = d3.select("body").append("svg")
.attr("width", width)
.attr("height", height);
d3.json("graph", function(error, graph) {
force
.nodes(graph.nodes)
.links(graph.links)
.start();
var link = svg.selectAll(".link")
.data(graph.links)
.enter().append("line")
.attr("class", "link")
.style("stroke-width", "2");
var node = svg.selectAll(".node")
.data(graph.nodes)
.enter().append("g");
var text= node.append("text").text(function(d){return d.name});
var c= node.append("circle")
.attr("class", "node")
.attr("r", 5)
.style("fill", function(d) { return color(1); })
.call(force.drag);
node.append("title")
.text(function(d) { return d.name; });
force.on("tick", function() {
link.attr("x1", function(d) { return d.source.x; })
.attr("y1", function(d) { return d.source.y; })
.attr("x2", function(d) { return d.target.x; })
.attr("y2", function(d) { return d.target.y; });
text.attr("x", function(d) { return d.x; })
.attr("y", function(d) { return d.y; })
c.attr("cx", function(d) { return d.x; })
.attr("cy", function(d) { return d.y; })
.attr("r", "5");
});
});
</script>

Binary file not shown.