Thomas Vachuska

Moved jdvue utility from ONOS-tools repo into onos repo.

Change-Id: I0bc1cef80541075c800c5309cb642a244a79fa0b
1 +#!/bin/bash
2 +#-------------------------------------------------------------------------------
3 +# Java Package Dependency viewer
4 +#
5 +# written by Thomas Vachuska
6 +# -- Doobs --
7 +#-------------------------------------------------------------------------------
8 +
9 +JDVUE_ROOT=${JDVUE_ROOT:-$(dirname $0)/..}
10 +cd $JDVUE_ROOT
11 +VER=1.2.0-SNAPSHOT
12 +JAR=$PWD/target/jdvue-${VER}.jar # start with the dev jar first
13 +cd - >/dev/null
14 +
15 +# If the dev jar is not available, use one from .m2/repository
16 +[ -f ${JAR} ] || JAR=~/.m2/repository/org/onlab/tools/jdvue/${VER}/jdvue-${VER}.jar
17 +
18 +# Assume default project to be the base-name of the argument or of current dir
19 +name=$(basename ${1:-$PWD})
20 +
21 +# If the -n option is specified use the next argument as the catalog name
22 +[ "$1" = "-n" -a $# -ge 2 ] && name=$2 && shift 2
23 +
24 +# Use the rest of the arguments as paths to scan for sources to build catalog
25 +find "${@:-.}" -type f -name \*.java \
26 + | grep -v -E '/lost+found/|/target/|archetype-resources' \
27 + | xargs grep -E "^[ \t]*import .*;.*|^[ \t]*package .*;.*" \
28 + | tr -d '\r' > $name.db
29 +
30 +# Now run the Java Dependency Viewer jar on the catalog
31 +java -jar ${JAR} $name && rm $name.db && open $name.html
1 +#!/bin/bash
2 +#-------------------------------------------------------------------------------
3 +# Java Package Dependency scanner
4 +#
5 +# written by Thomas Vachuska
6 +# -- Doobs --
7 +#-------------------------------------------------------------------------------
8 +
9 +find "${@:-.}" -type f -name \*.java \
10 + | grep -v -E '/lost+found/|/target/' \
11 + | xargs grep -E "^[ \t]*import .*;.*|^[ \t]*package .*;.*" \
12 + | tr -d '\r' > jpd.db
1 +<?xml version="1.0"?>
2 +<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
3 + xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
4 + <modelVersion>4.0.0</modelVersion>
5 + <prerequisites>
6 + <maven>3.0.4</maven>
7 + </prerequisites>
8 +
9 + <parent>
10 + <groupId>org.onosproject</groupId>
11 + <artifactId>onos-base</artifactId>
12 + <version>1</version>
13 + <relativePath>../../build/pom.xml</relativePath>
14 + </parent>
15 +
16 + <artifactId>jdvue</artifactId>
17 + <version>1.2.0-SNAPSHOT</version>
18 + <packaging>jar</packaging>
19 +
20 + <description>Java Package Dependency &amp; Analyzer</description>
21 +
22 + <dependencies>
23 + <dependency>
24 + <groupId>com.google.guava</groupId>
25 + <artifactId>guava</artifactId>
26 + <version>18.0</version>
27 + </dependency>
28 + <dependency>
29 + <groupId>com.google.guava</groupId>
30 + <artifactId>guava-testlib</artifactId>
31 + <version>18.0</version>
32 + <scope>test</scope>
33 + </dependency>
34 + <dependency>
35 + <groupId>com.fasterxml.jackson.core</groupId>
36 + <artifactId>jackson-databind</artifactId>
37 + <version>2.2.2</version>
38 + </dependency>
39 + <dependency>
40 + <groupId>junit</groupId>
41 + <artifactId>junit</artifactId>
42 + <version>4.11</version>
43 + <scope>test</scope>
44 + </dependency>
45 + </dependencies>
46 +
47 + <build>
48 + <plugins>
49 + <plugin>
50 + <artifactId>maven-compiler-plugin</artifactId>
51 + <version>3.1</version>
52 + <configuration>
53 + <source>1.8</source>
54 + <target>1.8</target>
55 + </configuration>
56 + </plugin>
57 + <plugin>
58 + <groupId>org.apache.maven.plugins</groupId>
59 + <artifactId>maven-shade-plugin</artifactId>
60 + <version>2.3</version>
61 + <configuration>
62 + <transformers>
63 + <transformer implementation="org.apache.maven.plugins.shade.resource.ManifestResourceTransformer">
64 + <mainClass>org.onlab.jdvue.DependencyViewer</mainClass>
65 + </transformer>
66 + </transformers>
67 + </configuration>
68 + <executions>
69 + <execution>
70 + <phase>package</phase>
71 + <goals>
72 + <goal>shade</goal>
73 + </goals>
74 + </execution>
75 + </executions>
76 + </plugin>
77 + </plugins>
78 + </build>
79 +
80 +</project>
This diff is collapsed. Click to expand it.
1 +package org.onlab.jdvue;
2 +
3 +import java.util.Objects;
4 +
5 +import static com.google.common.base.Objects.toStringHelper;
6 +
7 +/**
8 + * Abstraction of a dependency segment.
9 + *
10 + * @author Thomas Vachuska
11 + */
12 +public class Dependency {
13 +
14 + private final JavaPackage source;
15 + private final JavaPackage target;
16 +
17 + /**
18 + * Creates a dependency from the specified source on the given target.
19 + *
20 + * @param source source of the dependency
21 + * @param target target of the dependency
22 + */
23 + public Dependency(JavaPackage source, JavaPackage target) {
24 + this.source = source;
25 + this.target = target;
26 + }
27 +
28 + /**
29 + * Returns the dependency source.
30 + *
31 + * @return source Java package
32 + */
33 + public JavaPackage getSource() {
34 + return source;
35 + }
36 +
37 + /**
38 + * Returns the dependency target.
39 + *
40 + * @return target Java package
41 + */
42 + public JavaPackage getTarget() {
43 + return target;
44 + }
45 +
46 + @Override
47 + public boolean equals(Object obj) {
48 + if (obj instanceof Dependency) {
49 + Dependency that = (Dependency) obj;
50 + return Objects.equals(source, that.source) &&
51 + Objects.equals(target, that.target);
52 + }
53 + return false;
54 + }
55 +
56 + @Override
57 + public int hashCode() {
58 + return Objects.hash(source, target);
59 + }
60 +
61 + @Override
62 + public String toString() {
63 + return toStringHelper(this)
64 + .add("source", source).add("target", target).toString();
65 + }
66 +
67 +}
1 +package org.onlab.jdvue;
2 +
3 +import java.util.ArrayList;
4 +import java.util.Collections;
5 +import java.util.List;
6 +import java.util.Objects;
7 +
8 +import static com.google.common.base.Objects.toStringHelper;
9 +
10 +/**
11 + * Simple representation of a Java package dependency cycle.
12 + */
13 +public class DependencyCycle {
14 +
15 + private final List<JavaPackage> cycle;
16 +
17 + /**
18 + * Creates a normalized dependency cycle represented by the specified list
19 + * of Java packages, which are expected to be given in order of dependency.
20 + * List is assumed to be non-empty.
21 + *
22 + * @param cycle list of Java packages in the dependency cycle
23 + * @param cause Java package that caused the cycle
24 + */
25 + DependencyCycle(List<JavaPackage> cycle, JavaPackage cause) {
26 + this.cycle = normalize(cycle, cause);
27 + }
28 +
29 + /**
30 + * Produces a normalized dependency cycle list. Normalization is performed
31 + * by rotating the list so that the package with the least lexicographic
32 + * name is at the start of the list.
33 + *
34 + * @param cycle list of Java packages in the dependency cycle
35 + * @param cause Java package that caused the cycle
36 + * @return normalized cycle
37 + */
38 + private List<JavaPackage> normalize(List<JavaPackage> cycle, JavaPackage cause) {
39 + int start = cycle.indexOf(cause);
40 + List<JavaPackage> clone = new ArrayList<>(cycle.subList(start, cycle.size()));
41 + int leastIndex = findIndexOfLeastName(clone);
42 + Collections.rotate(clone, -leastIndex);
43 + return Collections.unmodifiableList(clone);
44 + }
45 +
46 + /**
47 + * Returns the index of the Java package with the least name.
48 + *
49 + * @param cycle list of Java packages in the dependency cycle
50 + * @return index of the least Java package name
51 + */
52 + private int findIndexOfLeastName(List<JavaPackage> cycle) {
53 + int leastIndex = 0;
54 + String leastName = cycle.get(leastIndex).name();
55 + for (int i = 1, n = cycle.size(); i < n; i++) {
56 + JavaPackage javaPackage = cycle.get(i);
57 + if (leastName.compareTo(javaPackage.name()) > 0) {
58 + leastIndex = i;
59 + leastName = javaPackage.name();
60 + }
61 + }
62 + return leastIndex;
63 + }
64 +
65 + /**
66 + * Returns the normalized Java package dependency cycle
67 + *
68 + * @return list of packages in the dependency cycle
69 + */
70 + public List<JavaPackage> getCycle() {
71 + return cycle;
72 + }
73 +
74 + /**
75 + * Returns the dependency cycle in form of individual dependencies.
76 + *
77 + * @return list of dependencies forming the cycle
78 + */
79 + public List<Dependency> getCycleSegments() {
80 + List<Dependency> dependencies = new ArrayList<>();
81 + for (int i = 0, n = cycle.size(); i < n; i++) {
82 + dependencies.add(new Dependency(cycle.get(i), cycle.get(i < n - 1 ? i + 1 : 0)));
83 + }
84 + return dependencies;
85 + }
86 +
87 + @Override
88 + public boolean equals(Object o) {
89 + if (o instanceof DependencyCycle) {
90 + DependencyCycle that = (DependencyCycle) o;
91 + return Objects.equals(cycle, that.cycle);
92 + }
93 + return false;
94 + }
95 +
96 + @Override
97 + public int hashCode() {
98 + return Objects.hash(cycle);
99 + }
100 +
101 + @Override
102 + public String toString() {
103 + return toStringHelper(this).add("cycle", cycle).toString();
104 + }
105 +
106 + public String toShortString() {
107 + StringBuilder sb = new StringBuilder("[");
108 + for (JavaPackage javaPackage : cycle) {
109 + sb.append(javaPackage.name()).append(", ");
110 + }
111 + if (sb.length() > 1) {
112 + sb.delete(sb.length() - 2, sb.length());
113 + }
114 + sb.append("]");
115 + return sb.toString();
116 + }
117 +
118 +}
1 +package org.onlab.jdvue;
2 +
3 +import com.fasterxml.jackson.databind.JsonNode;
4 +import com.fasterxml.jackson.databind.ObjectMapper;
5 +import com.fasterxml.jackson.databind.ObjectWriter;
6 +import com.fasterxml.jackson.databind.node.ArrayNode;
7 +import com.fasterxml.jackson.databind.node.ObjectNode;
8 +
9 +import java.io.BufferedReader;
10 +import java.io.FileWriter;
11 +import java.io.IOException;
12 +import java.io.InputStream;
13 +import java.io.InputStreamReader;
14 +import java.util.Set;
15 +
16 +/**
17 + * Generator of a self-contained HTML file which serves as a GUI for
18 + * visualizing Java package dependencies carried in the supplied catalog.
19 + *
20 + * The HTML file is an adaptation of D3.js Hierarchical Edge Bundling as
21 + * shown at http://bl.ocks.org/mbostock/7607999.
22 + *
23 + * @author Thomas Vachuska
24 + */
25 +public class DependencyViewer {
26 +
27 + private static final String JPD_EXT = ".db";
28 + private static final String HTML_EXT = ".html";
29 +
30 + private static final String INDEX = "index.html";
31 + private static final String D3JS = "d3.v3.min.js";
32 +
33 + private static final String TITLE_PLACEHOLDER = "TITLE_PLACEHOLDER";
34 + private static final String D3JS_PLACEHOLDER = "D3JS_PLACEHOLDER";
35 + private static final String DATA_PLACEHOLDER = "DATA_PLACEHOLDER";
36 +
37 + private final Catalog catalog;
38 +
39 + /**
40 + * Creates a Java package dependency viewer.
41 + *
42 + * @param catalog dependency catalog
43 + */
44 + public DependencyViewer(Catalog catalog) {
45 + this.catalog = catalog;
46 + }
47 +
48 + /**
49 + * Main program entry point.
50 + *
51 + * @param args command line arguments
52 + */
53 + public static void main(String[] args) {
54 + Catalog cat = new Catalog();
55 + DependencyViewer viewer = new DependencyViewer(cat);
56 + try {
57 + String path = args[0];
58 + cat.load(path + JPD_EXT);
59 + cat.analyze();
60 +
61 + System.err.println(cat);
62 + viewer.dumpLongestCycle(cat);
63 + viewer.writeHTMLFile(path);
64 + } catch (IOException e) {
65 + System.err.println("Unable to process catalog: " + e.getMessage());
66 + }
67 + }
68 +
69 + /**
70 + * Prints out the longest cycle; just for kicks.
71 + * @param cat catalog
72 + */
73 + private void dumpLongestCycle(Catalog cat) {
74 + DependencyCycle longest = null;
75 + for (DependencyCycle cycle : cat.getCycles()) {
76 + if (longest == null || longest.getCycleSegments().size() < cycle.getCycleSegments().size()) {
77 + longest = cycle;
78 + }
79 + }
80 +
81 + if (longest != null) {
82 + for (Dependency dependency : longest.getCycleSegments()) {
83 + System.out.println(dependency);
84 + }
85 + }
86 + }
87 +
88 + /**
89 + * Writes the HTML catalog file for the given viewer.
90 + *
91 + * @param path base file path
92 + * @throws IOException if issues encountered writing the HTML file
93 + */
94 + public void writeHTMLFile(String path) throws IOException {
95 + String index = slurp(getClass().getResourceAsStream(INDEX));
96 + String d3js = slurp(getClass().getResourceAsStream(D3JS));
97 +
98 + FileWriter fw = new FileWriter(path + HTML_EXT);
99 + ObjectWriter writer = new ObjectMapper().writer(); // .writerWithDefaultPrettyPrinter();
100 + fw.write(index.replace(TITLE_PLACEHOLDER, path)
101 + .replace(D3JS_PLACEHOLDER, d3js)
102 + .replace(DATA_PLACEHOLDER, writer.writeValueAsString(toJson())));
103 + fw.close();
104 + }
105 +
106 + /**
107 + * Slurps the specified input stream into a string.
108 + *
109 + * @param stream input stream to be read
110 + * @return string containing the contents of the input stream
111 + * @throws IOException if issues encountered reading from the stream
112 + */
113 + static String slurp(InputStream stream) throws IOException {
114 + StringBuilder sb = new StringBuilder();
115 + BufferedReader br = new BufferedReader(new InputStreamReader(stream));
116 + String line;
117 + while ((line = br.readLine()) != null) {
118 + sb.append(line).append(System.lineSeparator());
119 + }
120 + br.close();
121 + return sb.toString();
122 + }
123 +
124 + // Produces a JSON structure designed to drive the hierarchical visual
125 + // representation of Java package dependencies and any dependency cycles
126 + private JsonNode toJson() {
127 + ObjectMapper mapper = new ObjectMapper();
128 + ObjectNode root = mapper.createObjectNode();
129 + root.put("packages", jsonPackages(mapper));
130 + root.put("cycleSegments", jsonCycleSegments(mapper, catalog.getCycleSegments()));
131 + root.put("summary", jsonSummary(mapper));
132 + return root;
133 + }
134 +
135 + // Produces a JSON summary of dependencies
136 + private JsonNode jsonSummary(ObjectMapper mapper) {
137 + ObjectNode summary = mapper.createObjectNode();
138 + summary.put("packages", catalog.getPackages().size());
139 + summary.put("sources", catalog.getSources().size());
140 + summary.put("cycles", catalog.getCycles().size());
141 + summary.put("cycleSegments", catalog.getCycleSegments().size());
142 + return summary;
143 + }
144 +
145 + // Produces a JSON structure with package dependency data
146 + private JsonNode jsonPackages(ObjectMapper mapper) {
147 + ArrayNode packages = mapper.createArrayNode();
148 + for (JavaPackage javaPackage : catalog.getPackages()) {
149 + packages.add(json(mapper, javaPackage));
150 + }
151 + return packages;
152 + }
153 +
154 + // Produces a JSON structure with all cyclic segments
155 + private JsonNode jsonCycleSegments(ObjectMapper mapper,
156 + Set<Dependency> segments) {
157 + ObjectNode cyclicSegments = mapper.createObjectNode();
158 + for (Dependency dependency : segments) {
159 + String s = dependency.getSource().name();
160 + String t = dependency.getTarget().name();
161 + cyclicSegments.put(t + "-" + s,
162 + mapper.createObjectNode().put("s", s).put("t", t));
163 + }
164 + return cyclicSegments;
165 + }
166 +
167 + // Produces a JSON object structure describing the specified Java package.
168 + private JsonNode json(ObjectMapper mapper, JavaPackage javaPackage) {
169 + ObjectNode node = mapper.createObjectNode();
170 +
171 + ArrayNode imports = mapper.createArrayNode();
172 + for (JavaPackage dependency : javaPackage.getDependencies()) {
173 + imports.add(dependency.name());
174 + }
175 +
176 + Set<DependencyCycle> packageCycles = catalog.getPackageCycles(javaPackage);
177 + Set<Dependency> packageCycleSegments = catalog.getPackageCycleSegments(javaPackage);
178 +
179 + node.put("name", javaPackage.name());
180 + node.put("size", javaPackage.getSources().size());
181 + node.put("imports", imports);
182 + node.put("cycleSegments", jsonCycleSegments(mapper, packageCycleSegments));
183 + node.put("cycleCount", packageCycles.size());
184 + node.put("cycleSegmentCount", packageCycleSegments.size());
185 + return node;
186 + }
187 +
188 +}
1 +package org.onlab.jdvue;
2 +
3 +import java.util.Objects;
4 +
5 +/**
6 + * Abstraction of a Java source entity.
7 + */
8 +public abstract class JavaEntity {
9 +
10 + private final String name;
11 +
12 + /**
13 + * Creates a new Java source entity with the given name.
14 + *
15 + * @param name source entity name
16 + */
17 + JavaEntity(String name) {
18 + this.name = name;
19 + }
20 +
21 + /**
22 + * Returns the Java source entity name.
23 + *
24 + * @return source entity name
25 + */
26 + public String name() {
27 + return name;
28 + }
29 +
30 + @Override
31 + public boolean equals(Object o) {
32 + if (o instanceof JavaEntity) {
33 + JavaEntity that = (JavaEntity) o;
34 + return getClass().equals(that.getClass()) &&
35 + Objects.equals(name, that.name);
36 + }
37 + return false;
38 + }
39 +
40 + @Override
41 + public int hashCode() {
42 + return Objects.hash(name);
43 + }
44 +}
1 +package org.onlab.jdvue;
2 +
3 +import java.util.Collections;
4 +import java.util.HashSet;
5 +import java.util.Set;
6 +
7 +import static com.google.common.base.Objects.toStringHelper;
8 +
9 +/**
10 + * Simple abstraction of a Java package for the purpose of tracking
11 + * dependencies and requirements.
12 + *
13 + * @author Thomas Vachuska
14 + */
15 +public class JavaPackage extends JavaEntity {
16 +
17 + private final Set<JavaSource> sources = new HashSet<>();
18 + private Set<JavaPackage> dependencies;
19 +
20 + /**
21 + * Creates a new Java package.
22 + *
23 + * @param name java package file name
24 + */
25 + JavaPackage(String name) {
26 + super(name);
27 + }
28 +
29 + /**
30 + * Returns the set of sources contained in this Java package.
31 + *
32 + * @return set of Java sources
33 + */
34 + public Set<JavaSource> getSources() {
35 + return Collections.unmodifiableSet(sources);
36 + }
37 +
38 + /**
39 + * Adds the specified Java source to the package. Only possible if the
40 + * Java package of the source is the same as this Java package.
41 + *
42 + * @param source Java source to be added
43 + */
44 + void addSource(JavaSource source) {
45 + if (source.getPackage().equals(this)) {
46 + sources.add(source);
47 + }
48 + }
49 +
50 + /**
51 + * Returns the set of packages directly required by this package.
52 + *
53 + * @return set of Java package dependencies
54 + */
55 + Set<JavaPackage> getDependencies() {
56 + return dependencies;
57 + }
58 +
59 + /**
60 + * Sets the set of resolved Java packages on which this package dependens.
61 + *
62 + * @param dependencies set of resolved Java packages
63 + */
64 + void setDependencies(Set<JavaPackage> dependencies) {
65 + if (this.dependencies == null) {
66 + this.dependencies = Collections.unmodifiableSet(new HashSet<>(dependencies));
67 + }
68 + }
69 +
70 + @Override
71 + public String toString() {
72 + return toStringHelper(this)
73 + .add("name", name())
74 + .add("sources", sources.size())
75 + .add("dependencies", (dependencies != null ? dependencies.size() : 0))
76 + .toString();
77 + }
78 +
79 +}
1 +package org.onlab.jdvue;
2 +
3 +import java.util.*;
4 +
5 +import static com.google.common.base.Objects.toStringHelper;
6 +
7 +/**
8 + * Simple abstraction of a Java source file for the purpose of tracking
9 + * dependencies and requirements.
10 + *
11 + * @author Thomas Vachuska
12 + */
13 +public class JavaSource extends JavaEntity {
14 +
15 + private String path;
16 + private JavaPackage javaPackage;
17 +
18 + private final Set<String> importNames = new HashSet<>();
19 + private Set<JavaEntity> imports;
20 +
21 + /**
22 + * Creates a new Java source entity.
23 + *
24 + * @param name java source file name
25 + */
26 + JavaSource(String name, String path) {
27 + super(name);
28 + this.path = path;
29 + }
30 +
31 + /**
32 + * Returns the Java package for this Java source.
33 + *
34 + * @return Java package
35 + */
36 + public JavaPackage getPackage() {
37 + return javaPackage;
38 + }
39 +
40 + /**
41 + * Sets the Java package for this Java source.
42 + *
43 + * @param javaPackage Java package
44 + */
45 + void setPackage(JavaPackage javaPackage) {
46 + if (this.javaPackage == null) {
47 + this.javaPackage = javaPackage;
48 + }
49 + }
50 +
51 + /**
52 + * Returns the set of resolved imports for this Java source
53 + * @return set of imports
54 + */
55 + public Set<JavaEntity> getImports() {
56 + return imports;
57 + }
58 +
59 + /**
60 + * Sets the set of resolved imported Java entities for this source.
61 + *
62 + * @param imports set of resolved Java entities imported by this source
63 + */
64 + void setImports(Set<JavaEntity> imports) {
65 + if (this.imports == null) {
66 + this.imports = Collections.unmodifiableSet(new HashSet<>(imports));
67 + }
68 + }
69 +
70 + /**
71 + * Adds a name of an imported, but unresolved, Java entity name.
72 + *
73 + * @param name name of an imported Java entity
74 + */
75 + void addImportName(String name) {
76 + importNames.add(name);
77 + }
78 +
79 + /**
80 + * Returns the set of imported, but unresolved, Java entity names.
81 + * @return set of imported Java entity names
82 + */
83 + Set<String> getImportNames() {
84 + return importNames;
85 + }
86 +
87 + @Override
88 + public String toString() {
89 + return toStringHelper(this)
90 + .add("name", name())
91 + .add("javaPackage", (javaPackage != null ? javaPackage.name() : ""))
92 + .add("importNames", importNames.size())
93 + .add("imports", (imports != null ? imports.size() : 0))
94 + .toString();
95 + }
96 +
97 +}
1 +/*
2 + * Copyright 2015 Open Networking Laboratory
3 + *
4 + * Licensed under the Apache License, Version 2.0 (the "License");
5 + * you may not use this file except in compliance with the License.
6 + * You may obtain a copy of the License at
7 + *
8 + * http://www.apache.org/licenses/LICENSE-2.0
9 + *
10 + * Unless required by applicable law or agreed to in writing, software
11 + * distributed under the License is distributed on an "AS IS" BASIS,
12 + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 + * See the License for the specific language governing permissions and
14 + * limitations under the License.
15 + */
16 +
17 +/**
18 + * Utility to analyze Java package dependencies.
19 + */
20 +package org.onlab.jdvue;
...\ No newline at end of file ...\ No newline at end of file
This diff could not be displayed because it is too large.
This diff is collapsed. Click to expand it.
1 +package org.onlab.jdvue;
2 +
3 +import org.junit.Test;
4 +import org.onlab.jdvue.Catalog;
5 +import org.onlab.jdvue.JavaPackage;
6 +import org.onlab.jdvue.JavaSource;
7 +
8 +import java.io.IOException;
9 +
10 +import static org.junit.Assert.assertEquals;
11 +import static org.junit.Assert.assertNotNull;
12 +
13 +/**
14 + * Unit test for the source catalog.
15 + *
16 + * @author Thomas Vachuska
17 + */
18 +public class CatalogTest {
19 +
20 + @Test
21 + public void basics() throws IOException {
22 + Catalog cat = new Catalog();
23 + cat.load("src/test/resources/catalog.db");
24 + cat.analyze();
25 +
26 + assertEquals("incorrect package count", 12, cat.getPackages().size());
27 + assertEquals("incorrect source count", 14, cat.getSources().size());
28 +
29 + JavaPackage pkg = cat.getPackage("k");
30 + assertNotNull("package should be found", pkg);
31 +
32 + JavaSource src = cat.getSource("k.K");
33 + assertNotNull("source should be found", src);
34 +
35 + assertEquals("incorrect package source count", 1, pkg.getSources().size());
36 + assertEquals("incorrect package dependency count", 1, pkg.getDependencies().size());
37 + assertEquals("incorrect package cycle count", 3, cat.getPackageCycles(pkg).size());
38 +
39 + assertEquals("incorrect segment count", 11, cat.getCycleSegments().size());
40 + assertEquals("incorrect cycle count", 5, cat.getCycles().size());
41 + }
42 +
43 +}
1 +package org.onlab.jdvue;
2 +
3 +import org.junit.Test;
4 +import org.onlab.jdvue.DependencyCycle;
5 +import org.onlab.jdvue.JavaPackage;
6 +
7 +import java.util.Arrays;
8 +
9 +import static org.junit.Assert.*;
10 +
11 +/**
12 + * Unit test for the dependency cycle entity.
13 + *
14 + * @author Thomas Vachuska
15 + */
16 +public class DependencyCycleTest {
17 +
18 + @Test
19 + public void normalize() {
20 + JavaPackage x = new JavaPackage("x");
21 + JavaPackage y = new JavaPackage("y");
22 + JavaPackage z = new JavaPackage("z");
23 +
24 + DependencyCycle a = new DependencyCycle(Arrays.asList(new JavaPackage[] {x, y, z}), x);
25 + DependencyCycle b = new DependencyCycle(Arrays.asList(new JavaPackage[] {y, z, x}), y);
26 + DependencyCycle c = new DependencyCycle(Arrays.asList(new JavaPackage[] {z, x, y}), z);
27 +
28 + assertEquals("incorrect normalization", a, b);
29 + assertEquals("incorrect normalization", a, c);
30 + }
31 +
32 + @Test
33 + public void testToString() {
34 + JavaPackage x = new JavaPackage("x");
35 + JavaPackage y = new JavaPackage("y");
36 + JavaPackage z = new JavaPackage("z");
37 +
38 + DependencyCycle a = new DependencyCycle(Arrays.asList(new JavaPackage[] {x, y, z}), x);
39 + assertEquals("incorrect toString", "[x, y, z]", a.toShortString());
40 + assertEquals("incorrect toString",
41 + "DependencyCycle{cycle=[" +
42 + "JavaPackage{name=x, sources=0, dependencies=0}, " +
43 + "JavaPackage{name=y, sources=0, dependencies=0}, " +
44 + "JavaPackage{name=z, sources=0, dependencies=0}]}",
45 + a.toString());
46 + }
47 +}
1 +package org.onlab.jdvue;
2 +
3 +import com.google.common.testing.EqualsTester;
4 +import org.junit.Test;
5 +import org.onlab.jdvue.Dependency;
6 +import org.onlab.jdvue.JavaPackage;
7 +
8 +import static org.junit.Assert.assertEquals;
9 +import static org.junit.Assert.assertNotEquals;
10 +
11 +/**
12 + * Unit test for the dependency entity.
13 + *
14 + * @author Thomas Vachuska
15 + */
16 +public class DependencyTest {
17 +
18 + @Test
19 + public void basics() {
20 + JavaPackage x = new JavaPackage("x");
21 + JavaPackage y = new JavaPackage("y");
22 +
23 + new EqualsTester()
24 + .addEqualityGroup(new Dependency(x, y), new Dependency(x, y))
25 + .addEqualityGroup(new Dependency(y, x), new Dependency(y, x))
26 + .testEquals();
27 + }
28 +
29 +}
1 +package org.onlab.jdvue;
2 +
3 +import org.junit.Test;
4 +import org.onlab.jdvue.DependencyViewer;
5 +
6 +import java.io.FileInputStream;
7 +import java.io.IOException;
8 +
9 +import static org.junit.Assert.assertEquals;
10 +import static org.junit.Assert.assertNotEquals;
11 +import static org.onlab.jdvue.DependencyViewer.slurp;
12 +
13 +/**
14 + * Unit test for the dependency viewer.
15 + *
16 + * @author Thomas Vachuska
17 + */
18 +public class DependencyViewerTest {
19 +
20 + @Test
21 + public void basics() throws IOException {
22 + DependencyViewer.main(new String[]{"src/test/resources/catalog"});
23 +
24 + String expected = slurp(new FileInputStream("src/test/resources/expected.html"));
25 + String actual = slurp(new FileInputStream("src/test/resources/catalog.html"));
26 +
27 + // FIXME: add more manageable assertions here
28 +// assertEquals("incorrect html", expected, actual);
29 + }
30 +
31 +}
1 +src/main/java/a/A.java:package a;
2 +src/main/java/a/A.java:import b.B;
3 +src/main/java/a/A2.java:package a;
4 +src/main/java/a/A2.java:import c.C;
5 +src/main/java/b/B.java:package b;
6 +src/main/java/b/B.java:import c.C;
7 +src/main/java/c/C.java:package c;
8 +
9 +src/main/java/x/X.java:package x;
10 +src/main/java/x/X.java:import y.Y;
11 +src/main/java/y/Y.java:package y;
12 +src/main/java/y/Y.java:import z.Z;
13 +src/main/java/z/Z.java:package z;
14 +src/main/java/z/Z.java:import x.X;
15 +
16 +src/main/java/u/U.java:package u;
17 +src/main/java/u/U.java:import v.V;
18 +src/main/java/u/U2.java:package u;
19 +src/main/java/u/U2.java:import v.V;
20 +src/main/java/v/V.java:package v;
21 +src/main/java/v/V.java:import u.U;
22 +
23 +src/main/java/k/K.java:package k;
24 +src/main/java/k/K.java:import l.L;
25 +src/main/java/l/L.java:package l;
26 +src/main/java/l/L.java:import k.K;
27 +src/main/java/l/L.java:import m.M;
28 +src/main/java/l/L.java:import n.N;
29 +src/main/java/m/M.java:package m;
30 +src/main/java/m/M.java:import n.N;
31 +src/main/java/n/N.java:package n;
32 +src/main/java/n/N.java:import k.K;
33 +
This diff could not be displayed because it is too large.
This diff could not be displayed because it is too large.
...@@ -39,6 +39,7 @@ ...@@ -39,6 +39,7 @@
39 <module>osgi</module> 39 <module>osgi</module>
40 <module>rest</module> 40 <module>rest</module>
41 <module>thirdparty</module> 41 <module>thirdparty</module>
42 + <module>jdvue</module>
42 <module>jnc</module> <!-- FIXME publish and remove before release --> 43 <module>jnc</module> <!-- FIXME publish and remove before release -->
43 </modules> 44 </modules>
44 45
......