added d3 example
This commit is contained in:
parent
38c511cdda
commit
ff2e2627ca
7 changed files with 323 additions and 0 deletions
14
src/main/java/yooze/ClassNotScannable.java
Normal file
14
src/main/java/yooze/ClassNotScannable.java
Normal 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);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
70
src/main/java/yooze/InclusionDecider.java
Normal file
70
src/main/java/yooze/InclusionDecider.java
Normal 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);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
130
src/main/java/yooze/application/YoozeServer.java
Normal file
130
src/main/java/yooze/application/YoozeServer.java
Normal 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);
|
||||||
|
}
|
||||||
|
}
|
||||||
29
src/main/java/yooze/scanner/JarScanner.java
Normal file
29
src/main/java/yooze/scanner/JarScanner.java
Normal 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
5
src/main/webapp/d3.v3.min.js
vendored
Normal file
File diff suppressed because one or more lines are too long
75
src/main/webapp/index.html
Normal file
75
src/main/webapp/index.html
Normal 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>
|
||||||
BIN
src/test/resources/trc-common-core-1.0.jar
Normal file
BIN
src/test/resources/trc-common-core-1.0.jar
Normal file
Binary file not shown.
Loading…
Add table
Reference in a new issue