/.settings/
/.project
/.classpath
-target/
+/target/
+/.idea/
--- /dev/null
+<?xml version="1.0" encoding="UTF-8"?>
+<module org.jetbrains.idea.maven.project.MavenProjectsManager.isMavenModule="true" type="JAVA_MODULE" version="4">
+ <component name="NewModuleRootManager" LANGUAGE_LEVEL="JDK_1_6" inherit-compiler-output="false">
+ <output url="file://$MODULE_DIR$/target/classes" />
+ <output-test url="file://$MODULE_DIR$/target/test-classes" />
+ <content url="file://$MODULE_DIR$">
+ <sourceFolder url="file://$MODULE_DIR$/src/main/java" isTestSource="false" />
+ <sourceFolder url="file://$MODULE_DIR$/src/test/java" isTestSource="true" />
+ <excludeFolder url="file://$MODULE_DIR$/target" />
+ </content>
+ <orderEntry type="inheritedJdk" />
+ <orderEntry type="sourceFolder" forTests="false" />
+ <orderEntry type="library" name="Maven: eu.svjatoslav:svjatoslavcommons:1.5-SNAPSHOT" level="project" />
+ </component>
+</module>
\ No newline at end of file
-<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
- <modelVersion>4.0.0</modelVersion>
- <groupId>eu.svjatoslav</groupId>
- <artifactId>javainspect</artifactId>
- <version>1.5-SNAPSHOT</version>
- <packaging>jar</packaging>
- <name>Java inspect</name>
- <description>Utility to visualize Java code</description>
+<project xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://maven.apache.org/POM/4.0.0"
+ xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+ <modelVersion>4.0.0</modelVersion>
+ <groupId>eu.svjatoslav</groupId>
+ <artifactId>javainspect</artifactId>
+ <version>1.5-SNAPSHOT</version>
+ <packaging>jar</packaging>
+ <name>Java inspect</name>
+ <description>Utility to visualize Java code</description>
- <organization>
- <name>svjatoslav.eu</name>
- <url>http://svjatoslav.eu</url>
- </organization>
+ <organization>
+ <name>svjatoslav.eu</name>
+ <url>http://svjatoslav.eu</url>
+ </organization>
- <properties>
- <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
- <project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
- </properties>
+ <properties>
+ <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
+ <project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
+ </properties>
- <reporting>
- <plugins>
- <plugin>
- <!-- Attempt to discover bugs by doing static code analysis -->
- <groupId>org.codehaus.mojo</groupId>
- <artifactId>findbugs-maven-plugin</artifactId>
- <version>2.5.3</version>
- </plugin>
- </plugins>
- </reporting>
- <build>
- <plugins>
- <plugin>
- <groupId>org.apache.maven.plugins</groupId>
- <artifactId>maven-compiler-plugin</artifactId>
- <version>2.3.2</version>
- <configuration>
- <source>1.6</source>
- <target>1.6</target>
- <encoding>UTF-8</encoding>
- </configuration>
- </plugin>
+ <build>
+ <plugins>
+ <plugin>
+ <groupId>org.apache.maven.plugins</groupId>
+ <artifactId>maven-compiler-plugin</artifactId>
+ <version>2.3.2</version>
+ <configuration>
+ <source>1.6</source>
+ <target>1.6</target>
+ <encoding>UTF-8</encoding>
+ </configuration>
+ </plugin>
- <plugin>
- <groupId>org.apache.maven.plugins</groupId>
- <artifactId>maven-source-plugin</artifactId>
- <version>2.2.1</version>
- <executions>
- <execution>
- <id>attach-sources</id>
- <goals>
- <goal>jar</goal>
- </goals>
- </execution>
- </executions>
- </plugin>
+ <plugin>
+ <groupId>org.apache.maven.plugins</groupId>
+ <artifactId>maven-source-plugin</artifactId>
+ <version>2.2.1</version>
+ <executions>
+ <execution>
+ <id>attach-sources</id>
+ <goals>
+ <goal>jar</goal>
+ </goals>
+ </execution>
+ </executions>
+ </plugin>
- <plugin>
- <groupId>org.apache.maven.plugins</groupId>
- <artifactId>maven-javadoc-plugin</artifactId>
- <version>2.9</version>
- <executions>
- <execution>
- <id>attach-javadocs</id>
- <goals>
- <goal>jar</goal>
- </goals>
- </execution>
- </executions>
- </plugin>
-
- </plugins>
+ <plugin>
+ <groupId>org.apache.maven.plugins</groupId>
+ <artifactId>maven-javadoc-plugin</artifactId>
+ <version>2.9</version>
+ <executions>
+ <execution>
+ <id>attach-javadocs</id>
+ <goals>
+ <goal>jar</goal>
+ </goals>
+ </execution>
+ </executions>
+ </plugin>
- <extensions>
- <extension>
- <groupId>org.apache.maven.wagon</groupId>
- <artifactId>wagon-ssh-external</artifactId>
- <version>2.6</version>
- </extension>
- </extensions>
- </build>
+ </plugins>
- <dependencies>
- <dependency>
- <groupId>eu.svjatoslav</groupId>
- <artifactId>svjatoslavcommons</artifactId>
- <version>1.5-SNAPSHOT</version>
- </dependency>
- </dependencies>
+ <extensions>
+ <extension>
+ <groupId>org.apache.maven.wagon</groupId>
+ <artifactId>wagon-ssh-external</artifactId>
+ <version>2.6</version>
+ </extension>
+ </extensions>
+ </build>
- <distributionManagement>
- <snapshotRepository>
- <id>svjatoslav.eu</id>
- <name>svjatoslav.eu</name>
- <url>scpexe://svjatoslav.eu/var/www/svjatoslav.eu/maven</url>
- </snapshotRepository>
- <repository>
- <id>svjatoslav.eu</id>
- <name>svjatoslav.eu</name>
- <url>scpexe://svjatoslav.eu/var/www/svjatoslav.eu/maven</url>
- </repository>
- </distributionManagement>
+ <dependencies>
+ <dependency>
+ <groupId>eu.svjatoslav</groupId>
+ <artifactId>svjatoslavcommons</artifactId>
+ <version>1.5-SNAPSHOT</version>
+ </dependency>
+ </dependencies>
- <repositories>
- <repository>
- <id>svjatoslav.eu</id>
- <name>Svjatoslav repository</name>
- <url>http://www2.svjatoslav.eu/maven/</url>
- </repository>
- </repositories>
+ <distributionManagement>
+ <snapshotRepository>
+ <id>svjatoslav.eu</id>
+ <name>svjatoslav.eu</name>
+ <url>scpexe://svjatoslav.eu/var/www/svjatoslav.eu/maven</url>
+ </snapshotRepository>
+ <repository>
+ <id>svjatoslav.eu</id>
+ <name>svjatoslav.eu</name>
+ <url>scpexe://svjatoslav.eu/var/www/svjatoslav.eu/maven</url>
+ </repository>
+ </distributionManagement>
+ <repositories>
+ <repository>
+ <id>svjatoslav.eu</id>
+ <name>Svjatoslav repository</name>
+ <url>http://www2.svjatoslav.eu/maven/</url>
+ </repository>
+ </repositories>
- <scm>
- <connection>scm:git:ssh://git@svjatoslav.eu/home/git/repositories/javainspect.git</connection>
- <developerConnection>scm:git:ssh://git@svjatoslav.eu/home/git/repositories/javainspect.git</developerConnection>
- </scm>
+
+ <scm>
+ <connection>scm:git:ssh://git@svjatoslav.eu/home/git/repositories/javainspect.git</connection>
+ <developerConnection>scm:git:ssh://git@svjatoslav.eu/home/git/repositories/javainspect.git</developerConnection>
+ </scm>
</project>
\ No newline at end of file
public class Annotation {
- private String name;
+ private String name;
- public Annotation(final Tokenizer tokenizer) throws InvalidSyntaxException {
+ public Annotation(final Tokenizer tokenizer) throws InvalidSyntaxException {
- name = tokenizer.getNextToken().token;
+ name = tokenizer.getNextToken().token;
- if (!tokenizer.probeNextToken("("))
- return;
+ if (!tokenizer.probeNextToken("("))
+ return;
- int depth = 1;
+ int depth = 1;
- while (true) {
- final TokenizerMatch token = tokenizer.getNextToken();
+ while (true) {
+ final TokenizerMatch token = tokenizer.getNextToken();
- if (token == null)
- return;
+ if (token == null)
+ return;
- if ("(".equals(token.token))
- depth++;
- if (")".equals(token.token))
- depth--;
+ if ("(".equals(token.token))
+ depth++;
+ if (")".equals(token.token))
+ depth--;
- if (depth == 0)
- return;
- }
+ if (depth == 0)
+ return;
+ }
- }
+ }
}
package eu.svjatoslav.inspector.java.methods;
-import java.util.ArrayList;
-import java.util.List;
-
import eu.svjatoslav.commons.string.tokenizer.InvalidSyntaxException;
import eu.svjatoslav.commons.string.tokenizer.Tokenizer;
+import java.util.ArrayList;
+import java.util.List;
+
public class ClassReference {
- public String name;
+ public String name;
- List<ClassReference> typeParameters = new ArrayList<ClassReference>();
+ List<ClassReference> typeParameters = new ArrayList<ClassReference>();
- public ClassReference(final Tokenizer tokenizer)
- throws InvalidSyntaxException {
- name = tokenizer.getNextToken().token;
+ public ClassReference(final Tokenizer tokenizer)
+ throws InvalidSyntaxException {
+ name = tokenizer.getNextToken().token;
- if (!tokenizer.probeNextToken("<"))
- return;
+ if (!tokenizer.probeNextToken("<"))
+ return;
- while (true) {
- final ClassReference parameterType = new ClassReference(tokenizer);
- typeParameters.add(parameterType);
+ while (true) {
+ final ClassReference parameterType = new ClassReference(tokenizer);
+ typeParameters.add(parameterType);
- if (!tokenizer.probeNextToken(","))
- break;
- }
+ if (!tokenizer.probeNextToken(","))
+ break;
+ }
- tokenizer.expectNextToken(">");
- }
+ tokenizer.expectNextToken(">");
+ }
- @Override
- public String toString() {
- final EnumerationBuffer result = new EnumerationBuffer();
+ @Override
+ public String toString() {
+ final EnumerationBuffer result = new EnumerationBuffer();
- result.append(name);
+ result.append(name);
- if (typeParameters.size() > 0) {
- result.append("<");
- for (final ClassReference classReference : typeParameters)
- result.appendEnumeration(classReference.toString());
- result.append(">");
- }
+ if (typeParameters.size() > 0) {
+ result.append("<");
+ for (final ClassReference classReference : typeParameters)
+ result.appendEnumeration(classReference.toString());
+ result.append(">");
+ }
- return result.toString();
- }
+ return result.toString();
+ }
}
package eu.svjatoslav.inspector.java.methods;
-import java.util.ArrayList;
-import java.util.List;
-
import eu.svjatoslav.commons.string.tokenizer.InvalidSyntaxException;
import eu.svjatoslav.commons.string.tokenizer.Tokenizer;
import eu.svjatoslav.commons.string.tokenizer.TokenizerMatch;
+import java.util.ArrayList;
+import java.util.List;
+
public class Clazz {
- private final String packageName;
- private final String className;
- private final boolean isInterface;
+ private final String packageName;
+ private final String className;
+ private final boolean isInterface;
- public ClassReference superClass;
- public List<ClassReference> implementedInterfaces = new ArrayList<ClassReference>();
+ public ClassReference superClass;
+ public List<ClassReference> implementedInterfaces = new ArrayList<ClassReference>();
- public Clazz(final String packageName, final String className,
- final Tokenizer tokenizer, final boolean isInterface)
- throws InvalidSyntaxException {
+ public Clazz(final String packageName, final String className,
+ final Tokenizer tokenizer, final boolean isInterface)
+ throws InvalidSyntaxException {
- this.packageName = packageName;
- this.className = className;
- this.isInterface = isInterface;
+ this.packageName = packageName;
+ this.className = className;
+ this.isInterface = isInterface;
- while (true) {
- final TokenizerMatch match = tokenizer.getNextToken();
+ while (true) {
+ final TokenizerMatch match = tokenizer.getNextToken();
- if ("extends".equals(match.token)) {
- superClass = new ClassReference(tokenizer);
- continue;
- }
+ if ("extends".equals(match.token)) {
+ superClass = new ClassReference(tokenizer);
+ continue;
+ }
- if ("implements".equals(match.token)) {
- while (true) {
- implementedInterfaces.add(new ClassReference(tokenizer));
+ if ("implements".equals(match.token)) {
+ while (true) {
+ implementedInterfaces.add(new ClassReference(tokenizer));
- if (tokenizer.probeNextToken(","))
- continue;
+ if (tokenizer.probeNextToken(","))
+ continue;
- break;
- }
- continue;
- }
+ break;
+ }
+ continue;
+ }
- if ("{".equals(match.token)) {
- parseClassBody(tokenizer);
- break;
- }
+ if ("{".equals(match.token)) {
+ parseClassBody(tokenizer);
+ break;
+ }
- }
- }
+ }
+ }
- public String getFullName() {
- return packageName + "." + className;
- }
+ public String getFullName() {
+ return packageName + "." + className;
+ }
- public void parseClassBody(final Tokenizer tokenizer) {
- tokenizer.skipUntilDataEnd();
- }
+ public void parseClassBody(final Tokenizer tokenizer) {
+ tokenizer.skipUntilDataEnd();
+ }
- @Override
- public String toString() {
- final EnumerationBuffer result = new EnumerationBuffer();
+ @Override
+ public String toString() {
+ final EnumerationBuffer result = new EnumerationBuffer();
- result.append(packageName + " -> " + className + " ");
+ result.append(packageName + " -> " + className + " ");
- if (isInterface)
- result.append("(interface)");
- else
- result.append("(class)");
- result.append("\n");
+ if (isInterface)
+ result.append("(interface)");
+ else
+ result.append("(class)");
+ result.append("\n");
- if (superClass != null)
- result.append(" super: " + superClass.toString() + "\n");
+ if (superClass != null)
+ result.append(" super: " + superClass.toString() + "\n");
- if (implementedInterfaces.size() > 0) {
- result.append(" implements: ");
- for (final ClassReference classReference : implementedInterfaces)
- result.appendEnumeration(classReference.toString());
- result.append("\n");
- }
+ if (implementedInterfaces.size() > 0) {
+ result.append(" implements: ");
+ for (final ClassReference classReference : implementedInterfaces)
+ result.appendEnumeration(classReference.toString());
+ result.append("\n");
+ }
- return result.toString();
- }
+ return result.toString();
+ }
}
public class EnumerationBuffer {
- private final String enumerationDelimiter;
+ private final String enumerationDelimiter;
- private final StringBuffer buffer = new StringBuffer();
+ private final StringBuffer buffer = new StringBuffer();
- public int enumeratedEntitiesCount = 0;
+ public int enumeratedEntitiesCount = 0;
- public EnumerationBuffer() {
- this(", ");
- }
+ public EnumerationBuffer() {
+ this(", ");
+ }
- public EnumerationBuffer(final String enumerationDelimiter) {
- this.enumerationDelimiter = enumerationDelimiter;
- }
+ public EnumerationBuffer(final String enumerationDelimiter) {
+ this.enumerationDelimiter = enumerationDelimiter;
+ }
- public void append(final String value) {
- buffer.append(value);
- }
+ public void append(final String value) {
+ buffer.append(value);
+ }
- public void appendEnumeration(final String value) {
- if (enumeratedEntitiesCount > 0)
- buffer.append(enumerationDelimiter);
+ public void appendEnumeration(final String value) {
+ if (enumeratedEntitiesCount > 0)
+ buffer.append(enumerationDelimiter);
- buffer.append(value);
- enumeratedEntitiesCount++;
- }
+ buffer.append(value);
+ enumeratedEntitiesCount++;
+ }
- public void resetEnumeration() {
- enumeratedEntitiesCount = 0;
- }
+ public void resetEnumeration() {
+ enumeratedEntitiesCount = 0;
+ }
- @Override
- public String toString() {
- return buffer.toString();
- }
+ @Override
+ public String toString() {
+ return buffer.toString();
+ }
}
public class Import {
- String path;
- boolean isStatic = false;
+ String path;
+ boolean isStatic = false;
}
package eu.svjatoslav.inspector.java.methods;
-import java.io.BufferedReader;
-import java.io.File;
-import java.io.FileNotFoundException;
-import java.io.FileReader;
-import java.io.IOException;
-import java.util.ArrayList;
-import java.util.List;
-
import eu.svjatoslav.commons.string.tokenizer.InvalidSyntaxException;
import eu.svjatoslav.commons.string.tokenizer.Tokenizer;
import eu.svjatoslav.commons.string.tokenizer.TokenizerMatch;
-public class JavaFile {
-
- private final List<Import> imports = new ArrayList<Import>();
-
- private String packageName;
-
- private final File file;
-
- StringBuffer contents = new StringBuffer();
-
- public List<Clazz> classes = new ArrayList<Clazz>();
-
- public JavaFile(final File file) throws IOException, InvalidSyntaxException {
- this.file = file;
- parse();
- }
-
- public void parse() throws IOException, InvalidSyntaxException {
- System.out.println("java file: " + file);
-
- readFile();
+import java.io.*;
+import java.util.ArrayList;
+import java.util.List;
- final Tokenizer tokenizer = new Tokenizer(contents.toString());
+public class JavaFile {
- // empty space
- tokenizer.addTerminator(" ", true);
- tokenizer.addTerminator("\t", true);
- tokenizer.addTerminator("\n", true);
+ public static final String UTF_8 = "UTF-8";
+ private final List<Import> imports = new ArrayList<Import>();
+ private final File file;
+ public List<Clazz> classes = new ArrayList<Clazz>();
+ StringBuffer contents = new StringBuffer();
+ private String packageName;
+
+ public JavaFile(final File file) throws IOException, InvalidSyntaxException {
+ this.file = file;
+ parse();
+ }
+
+ public void parse() throws IOException, InvalidSyntaxException {
+ System.out.println("java file: " + file);
+
+ readFile();
- tokenizer.addTerminator(";", false);
- tokenizer.addTerminator("{", false);
- tokenizer.addTerminator("}", false);
- tokenizer.addTerminator("(", false);
- tokenizer.addTerminator(")", false);
- tokenizer.addTerminator("[", false);
- tokenizer.addTerminator("]", false);
- tokenizer.addTerminator("<", false);
- tokenizer.addTerminator(">", false);
- tokenizer.addTerminator(",", false);
- tokenizer.addTerminator("@", false);
+ final Tokenizer tokenizer = new Tokenizer(contents.toString());
+
+ // empty space
+ tokenizer.addTerminator(" ", true);
+ tokenizer.addTerminator("\t", true);
+ tokenizer.addTerminator("\n", true);
+
+ tokenizer.addTerminator(";", false);
+ tokenizer.addTerminator("{", false);
+ tokenizer.addTerminator("}", false);
+ tokenizer.addTerminator("(", false);
+ tokenizer.addTerminator(")", false);
+ tokenizer.addTerminator("[", false);
+ tokenizer.addTerminator("]", false);
+ tokenizer.addTerminator("<", false);
+ tokenizer.addTerminator(">", false);
+ tokenizer.addTerminator(",", false);
+ tokenizer.addTerminator("@", false);
- // comments
- tokenizer.addTerminator("//", "\n", true);
- tokenizer.addTerminator("/*", "*/", true);
+ // comments
+ tokenizer.addTerminator("//", "\n", true);
+ tokenizer.addTerminator("/*", "*/", true);
- final Modifiers modifiers = new Modifiers();
+ final Modifiers modifiers = new Modifiers();
- while (true) {
- final TokenizerMatch match = tokenizer.getNextToken();
- if (match == null)
- break;
+ while (true) {
+ final TokenizerMatch match = tokenizer.getNextToken();
+ if (match == null)
+ break;
- if (match.token.equals("package")) {
- parsePackage(tokenizer);
- continue;
- }
+ if (match.token.equals("package")) {
+ parsePackage(tokenizer);
+ continue;
+ }
- if (match.token.equals("import")) {
- parseImport(tokenizer);
- continue;
- }
+ if (match.token.equals("import")) {
+ parseImport(tokenizer);
+ continue;
+ }
- final boolean wasModifier = modifiers.parseModifier(match.token);
- if (wasModifier)
- continue;
+ final boolean wasModifier = modifiers.parseModifier(match.token);
+ if (wasModifier)
+ continue;
- if ("class".equals(match.token)) {
- parseClass(tokenizer);
- continue;
- }
+ if ("class".equals(match.token)) {
+ parseClass(tokenizer);
+ continue;
+ }
- if ("interface".equals(match.token)) {
- parseInterface(tokenizer);
- continue;
- }
+ if ("interface".equals(match.token)) {
+ parseInterface(tokenizer);
+ continue;
+ }
- if ("@".equals(match.token)) {
- final Annotation annotation = new Annotation(tokenizer);
- continue;
- }
+ if ("@".equals(match.token)) {
+ new Annotation(tokenizer);
+ continue;
+ }
- System.out.println(" " + modifiers.toString() + " "
- + match.token);
- modifiers.reset();
- skipUntilSemicolon(tokenizer);
- }
+ System.out.println(" " + modifiers.toString() + " "
+ + match.token);
+ modifiers.reset();
+ skipUntilSemicolon(tokenizer);
+ }
- }
+ }
- private void parseClass(final Tokenizer tokenizer)
- throws InvalidSyntaxException {
+ private void parseClass(final Tokenizer tokenizer)
+ throws InvalidSyntaxException {
- final TokenizerMatch match = tokenizer.getNextToken();
- final Clazz clazz = new Clazz(packageName, match.token, tokenizer,
- false);
- // System.out.println(clazz.toString());
- classes.add(clazz);
+ final TokenizerMatch match = tokenizer.getNextToken();
+ final Clazz clazz = new Clazz(packageName, match.token, tokenizer,
+ false);
+ // System.out.println(clazz.toString());
+ classes.add(clazz);
- }
+ }
- private void parseImport(final Tokenizer tokenizer)
- throws InvalidSyntaxException {
+ private void parseImport(final Tokenizer tokenizer)
+ throws InvalidSyntaxException {
- final Import imp = new Import();
+ final Import imp = new Import();
- final TokenizerMatch match = tokenizer.getNextToken();
+ final TokenizerMatch match = tokenizer.getNextToken();
- if (match.token.equals("static")) {
- imp.isStatic = true;
- imp.path = tokenizer.getNextToken().token;
- } else
- imp.path = match.token;
+ if (match.token.equals("static")) {
+ imp.isStatic = true;
+ imp.path = tokenizer.getNextToken().token;
+ } else
+ imp.path = match.token;
- imports.add(imp);
+ imports.add(imp);
- tokenizer.expectNextToken(";");
- }
+ tokenizer.expectNextToken(";");
+ }
- private void parseInterface(final Tokenizer tokenizer)
- throws InvalidSyntaxException {
+ private void parseInterface(final Tokenizer tokenizer)
+ throws InvalidSyntaxException {
- final TokenizerMatch match = tokenizer.getNextToken();
- final Clazz clazz = new Clazz(packageName, match.token, tokenizer, true);
- // System.out.println(clazz.toString());
- classes.add(clazz);
- }
+ final TokenizerMatch match = tokenizer.getNextToken();
+ final Clazz clazz = new Clazz(packageName, match.token, tokenizer, true);
+ // System.out.println(clazz.toString());
+ classes.add(clazz);
+ }
- private void parsePackage(final Tokenizer tokenizer)
- throws InvalidSyntaxException {
+ private void parsePackage(final Tokenizer tokenizer)
+ throws InvalidSyntaxException {
- final TokenizerMatch match = tokenizer.getNextToken();
+ final TokenizerMatch match = tokenizer.getNextToken();
- packageName = match.token;
+ packageName = match.token;
- tokenizer.expectNextToken(";");
- }
+ tokenizer.expectNextToken(";");
+ }
- private void readFile() throws FileNotFoundException, IOException {
- final FileReader fileReader = new FileReader(file);
+ private void readFile() throws IOException {
+ InputStreamReader inputStream = new InputStreamReader(new FileInputStream(file), UTF_8);
- final BufferedReader bufferedReader = new BufferedReader(fileReader);
+ final BufferedReader bufferedReader = new BufferedReader(inputStream);
- while (true) {
- final String line = bufferedReader.readLine();
+ while (true) {
+ final String line = bufferedReader.readLine();
- if (line == null)
- break;
+ if (line == null)
+ break;
- contents.append(line);
- contents.append("\n");
- }
+ contents.append(line);
+ contents.append("\n");
+ }
- bufferedReader.close();
- fileReader.close();
- }
+ bufferedReader.close();
+ inputStream.close();
+ }
- public void skipUntilSemicolon(final Tokenizer tokenizer) {
- while (true) {
- final TokenizerMatch token = tokenizer.getNextToken();
+ public void skipUntilSemicolon(final Tokenizer tokenizer) {
+ while (true) {
+ final TokenizerMatch token = tokenizer.getNextToken();
- if (token == null)
- return;
+ if (token == null)
+ return;
- if (token.token.equals(";"))
- return;
- }
- }
+ if (token.token.equals(";"))
+ return;
+ }
+ }
}
public class Modifiers {
- public enum Access {
- PUBLIC("public"), PROTECTED("protected"), DEFAULT(""), PRIVATE(
- "private");
-
- public final String name;
-
- Access(final String name) {
- this.name = name;
- };
- }
-
- Access access = Access.DEFAULT;
-
- boolean isStatic = false;;
-
- boolean isFinal = false;
-
- boolean isAbstract = false;
-
- public boolean parseModifier(final String string) {
- for (final Access access : Access.values())
- if (access.name.equals(string)) {
- this.access = access;
- return true;
- }
-
- if ("static".equals(string)) {
- isStatic = true;
- return true;
- }
-
- if ("final".equals(string)) {
- isFinal = true;
- return true;
- }
-
- if ("abstract".equals(string)) {
- isAbstract = true;
- return true;
- }
-
- return false;
- }
-
- public void reset() {
- isStatic = false;
- isFinal = false;
- access = Access.DEFAULT;
- }
-
- @Override
- public String toString() {
- final StringBuffer result = new StringBuffer();
-
- result.append(access.name);
-
- if (isStatic) {
- if (result.length() > 0)
- result.append(" ");
- result.append("static");
- }
-
- if (isFinal) {
- if (result.length() > 0)
- result.append(" ");
- result.append("final");
- }
-
- return result.toString();
- }
+ Access access = Access.DEFAULT;
+ boolean isStatic = false;
+ boolean isFinal = false;
+ boolean isAbstract = false;
+
+ public boolean parseModifier(final String string) {
+ for (final Access access : Access.values())
+ if (access.name.equals(string)) {
+ this.access = access;
+ return true;
+ }
+
+ if ("static".equals(string)) {
+ isStatic = true;
+ return true;
+ }
+
+ if ("final".equals(string)) {
+ isFinal = true;
+ return true;
+ }
+
+ if ("abstract".equals(string)) {
+ isAbstract = true;
+ return true;
+ }
+
+ return false;
+ }
+
+ public void reset() {
+ isStatic = false;
+ isFinal = false;
+ access = Access.DEFAULT;
+ }
+
+ @Override
+ public String toString() {
+ final StringBuffer result = new StringBuffer();
+
+ result.append(access.name);
+
+ if (isStatic) {
+ if (result.length() > 0)
+ result.append(" ");
+ result.append("static");
+ }
+
+ if (isFinal) {
+ if (result.length() > 0)
+ result.append(" ");
+ result.append("final");
+ }
+
+ return result.toString();
+ }
+
+ public enum Access {
+ PUBLIC("public"), PROTECTED("protected"), DEFAULT(""), PRIVATE(
+ "private");
+
+ public final String name;
+
+ Access(final String name) {
+ this.name = name;
+ }
+ }
}
public class Package {
- Map<String, Clazz> classes = new HashMap<String, Clazz>();
+ Map<String, Clazz> classes = new HashMap<String, Clazz>();
}
public class Project {
- Map<String, Package> packages = new HashMap<String, Package>();
+ Map<String, Package> packages = new HashMap<String, Package>();
}
package eu.svjatoslav.inspector.java.methods;
+import eu.svjatoslav.commons.file.FilePathParser;
+import eu.svjatoslav.commons.string.tokenizer.InvalidSyntaxException;
+
import java.io.File;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
-import eu.svjatoslav.commons.file.FilePathParser;
-import eu.svjatoslav.commons.string.tokenizer.InvalidSyntaxException;
-
public class ProjectScanner {
- private final File scanPath;
+ private final File scanPath;
+ public List<JavaFile> javaFiles = new ArrayList<JavaFile>();
+ Map<File, Project> projects = new HashMap<File, Project>();
- Map<File, Project> projects = new HashMap<File, Project>();
- public List<JavaFile> javaFiles = new ArrayList<JavaFile>();
+ public ProjectScanner(final File projectPath) {
+ scanPath = projectPath;
+ parse();
+ }
- public ProjectScanner(final File projectPath) {
- scanPath = projectPath;
- parse();
- }
+ public List<Clazz> getAllClasses() {
+ final List<Clazz> result = new ArrayList<Clazz>();
- public List<Clazz> getAllClasses() {
- final List<Clazz> result = new ArrayList<Clazz>();
+ for (final JavaFile file : javaFiles)
+ for (final Clazz clazz : file.classes)
+ result.add(clazz);
- for (final JavaFile file : javaFiles)
- for (final Clazz clazz : file.classes)
- result.add(clazz);
+ return result;
+ }
- return result;
- }
+ public void parse() {
- public void parse() {
+ if (!scanPath.exists())
+ System.out.println("Path not found: " + scanPath);
- if (!scanPath.exists())
- System.out.println("Path not found: " + scanPath);
+ if (!scanPath.canRead())
+ System.out.println("Cannot read path: " + scanPath);
- if (!scanPath.canRead())
- System.out.println("Cannot read path: " + scanPath);
+ if (scanPath.isDirectory())
+ parseDirectory(scanPath);
- if (scanPath.isDirectory())
- parseDirectory(scanPath);
+ if (scanPath.isFile())
+ parseFile(scanPath);
+ }
- if (scanPath.isFile())
- parseFile(scanPath);
- }
+ public void parseDirectory(final File file) {
- public void parseDirectory(final File file) {
+ File[] filesList = file.listFiles();
+ if (filesList == null) throw new RuntimeException("Cannot scan directory: " + file);
- for (final File subFile : file.listFiles()) {
+ for (final File subFile : filesList) {
- if (subFile.isFile())
- parseFile(subFile);
+ if (subFile.isFile())
+ parseFile(subFile);
- if (subFile.isDirectory())
- parseDirectory(subFile);
- }
- }
+ if (subFile.isDirectory())
+ parseDirectory(subFile);
+ }
+ }
- public void parseFile(final File file) {
- final String fileExtension = FilePathParser.getFileExtension(file);
- if ("java".equalsIgnoreCase(fileExtension))
- try {
- final JavaFile javaFile = new JavaFile(file);
- javaFiles.add(javaFile);
- } catch (final IOException e) {
- System.out.println("Error parsing file: " + file.toString()
- + ": " + e.toString());
- } catch (final InvalidSyntaxException e) {
- System.out.println("Syntax error occured while parsing file: "
- + file.toString() + ": " + e.toString());
- }
- }
+ public void parseFile(final File file) {
+ final String fileExtension = FilePathParser.getFileExtension(file);
+ if ("java".equalsIgnoreCase(fileExtension))
+ try {
+ final JavaFile javaFile = new JavaFile(file);
+ javaFiles.add(javaFile);
+ } catch (final IOException e) {
+ System.out.println("Error parsing file: " + file.toString()
+ + ": " + e.toString());
+ } catch (final InvalidSyntaxException e) {
+ System.out.println("Syntax error occured while parsing file: "
+ + file.toString() + ": " + e.toString());
+ }
+ }
}
* This package contains quickly hacked together Java language parser.
* Goal is to start visualizing method call references and other things
* which are not easily readable at runtime via reflection.
- *
+ * <p>
* Work in progress...
- *
+ * <p>
* Currently in is useful just for detecting class names and packages.
- *
*/
import java.lang.reflect.Field;
import java.lang.reflect.Method;
-import java.util.ArrayList;
-import java.util.List;
-import java.util.Map;
-import java.util.SortedSet;
-import java.util.TreeMap;
-import java.util.TreeSet;
+import java.util.*;
/**
* Describes single class instance
*/
-public class ClassDescriptor implements GraphElement {
+public class ClassDescriptor implements GraphElement, Comparable<ClassDescriptor> {
+
+ private static final int MAX_REFERECNES_COUNT = 10;
+ private final Map<String, FieldDescriptor> nameToFieldMap = new TreeMap<String, FieldDescriptor>();
+ private final SortedSet<MethodDescriptor> methods = new TreeSet<MethodDescriptor>();
+ private final ClassGraph classGraph;
+ boolean isEnum;
+ boolean isInterface;
+ boolean isArray;
+ List<ClassDescriptor> interfaces = new ArrayList<ClassDescriptor>();
+ ClassDescriptor superClass;
+ private String fullyQualifiedName;
+ /**
+ * Incoming arrows will have this color.
+ */
+ private String distinctiveReferenceColor;
+ private String interfaceColor;
+ private String superClassColor;
+ private boolean isShown = true;
+ /**
+ * Amount of field and method references pointing to this class.
+ */
+ private int referencesCount = 0;
+
+ // for interface, counts amount of found implementations
+ private int implementationsCount = 0;
+
+ // counts amount of times this class is extended
+ private int extensionsCount = 0;
+
+ private ClassDescriptor arrayComponent;
+
+ public ClassDescriptor(final ClassGraph classGraph) {
+ this.classGraph = classGraph;
+ }
+
+ protected void analyzeClass(final Class<? extends Object> clazz) {
+
+ fullyQualifiedName = clazz.getName();
+
+ isArray = clazz.isArray();
+
+ if (isArray) {
+ final Class<?> componentType = clazz.getComponentType();
+ arrayComponent = getClassGraph().getOrCreateClassDescriptor(
+ componentType);
+ }
+
+ // System.out.println("class: " + fullyQualifiedName);
+
+ isEnum = clazz.isEnum();
+
+ isInterface = clazz.isInterface();
+
+ if (!isVisible())
+ return;
+
+ indexFields(clazz.getDeclaredFields());
+ indexFields(clazz.getFields());
+
+ indexMethods(clazz);
+
+ for (final Class interfaceClass : clazz.getInterfaces()) {
+ final ClassDescriptor interfaceClassDescriptor = getClassGraph()
+ .getOrCreateClassDescriptor(interfaceClass);
+ interfaceClassDescriptor.registerImplementation();
+ interfaces.add(interfaceClassDescriptor);
+ }
+
+ superClass = getClassGraph().getOrCreateClassDescriptor(
+ clazz.getSuperclass());
+ if (superClass != null)
+ superClass.registerExtension();
+
+ }
+
+ protected boolean areReferencesShown() {
+ return referencesCount <= MAX_REFERECNES_COUNT;
+ }
+
+ private void enlistFieldReferences(final StringBuffer result) {
+ if (nameToFieldMap.isEmpty())
+ return;
+
+ result.append("\n");
+ result.append(" // field references to other classes\n");
+ for (final Map.Entry<String, FieldDescriptor> entry : nameToFieldMap
+ .entrySet())
+ result.append(entry.getValue().getDot());
+ }
+
+ private void enlistFields(final StringBuffer result) {
+ if (nameToFieldMap.isEmpty())
+ return;
+
+ result.append("\n");
+ result.append(" // fields:\n");
+
+ // enlist fields
+ for (final Map.Entry<String, FieldDescriptor> entry : nameToFieldMap
+ .entrySet())
+ result.append(entry.getValue().getEmbeddedDot());
+ }
+
+ private void enlistImplementedInterfaces(final StringBuffer result) {
+ if (interfaces.isEmpty())
+ return;
- private static final int MAX_REFERECNES_COUNT = 10;
+ result.append("\n");
+ result.append(" // interfaces implemented by class: "
+ + fullyQualifiedName + "\n");
- private String fullyQualifiedName;
+ for (final ClassDescriptor interfaceDescriptor : interfaces) {
+ if (!interfaceDescriptor.isVisible())
+ continue;
- private final Map<String, FieldDescriptor> nameToFieldMap = new TreeMap<String, FieldDescriptor>();
+ if (!interfaceDescriptor.areReferencesShown())
+ continue;
- private final SortedSet<MethodDescriptor> methods = new TreeSet<MethodDescriptor>();
+ result.append(" " + interfaceDescriptor.getGraphId() + " -> "
+ + getGraphId() + "[style=\"dotted\", color=\""
+ + interfaceDescriptor.getInterfaceColor()
+ + "\", penwidth=10, dir=\"forward\"];\n");
+ }
+ }
- /**
- * Incoming arrows will have this color.
- */
- private String distinctiveReferenceColor;
+ private void enlistMethodReferences(final StringBuffer result) {
+ if (methods.isEmpty())
+ return;
- private String interfaceColor;
+ result.append("\n");
+ result.append(" // method references to other classes\n");
+ for (final MethodDescriptor methodDescriptor : methods)
+ result.append(methodDescriptor.getDot());
+ }
- private String superClassColor;
+ private void enlistMethods(final StringBuffer result) {
+ if (methods.isEmpty())
+ return;
+
+ result.append("\n");
+ result.append(" // methods:\n");
+
+ // enlist methods
+ for (final MethodDescriptor methodDescriptor : methods)
+ result.append(methodDescriptor.getEmbeddedDot());
+ }
+
+ private void enlistSuperClass(final StringBuffer result) {
+ if (superClass == null)
+ return;
+
+ if (!superClass.isVisible())
+ return;
+
+ if (!superClass.areReferencesShown())
+ return;
+
+ result.append("\n");
+ result.append(" // super class for: " + fullyQualifiedName + "\n");
+
+ result.append(" " + superClass.getGraphId() + " -> " + getGraphId()
+ + "[ color=\"" + superClass.getSuperClassColor()
+ + "\", penwidth=10, dir=\"forward\"];\n");
+ }
- boolean isEnum;
+ private void generateDotHeader(final StringBuffer result) {
+ result.append("\n");
+ result.append("// Class: " + fullyQualifiedName + "\n");
- boolean isInterface;
+ result.append(" " + getGraphId() + "[label=<<TABLE "
+ + getBackgroundColor() + " BORDER=\"" + getBorderWidth()
+ + "\" CELLBORDER=\"1\" CELLSPACING=\"0\">\n");
- boolean isArray;
+ result.append("\n");
+ result.append(" // class descriptor header\n");
+ result.append(" <TR><TD colspan=\"2\" PORT=\"f0\">"
+ + "<FONT POINT-SIZE=\"8.0\" >" + getPackageName()
+ + "</FONT><br/>");
- private boolean isShown = true;
+ final String parentClassesName = getParentClassesName();
+ if (parentClassesName.length() > 0)
+ result.append("<FONT POINT-SIZE=\"12.0\"><B>" + parentClassesName
+ + "</B></FONT><br/>\n");
- private final ClassGraph classGraph;
+ result.append("<FONT POINT-SIZE=\"25.0\"><B>" + getClassName(false)
+ + "</B></FONT>" + "</TD></TR>\n");
+ }
- List<ClassDescriptor> interfaces = new ArrayList<ClassDescriptor>();
+ private String getBackgroundColor() {
+ String bgColor = "";
- ClassDescriptor superClass;
+ if (isEnum)
+ bgColor = "bgcolor=\"navajowhite2\"";
- /**
- * Amount of field and method references pointing to this class.
- */
- private int referencesCount = 0;
+ if (isInterface)
+ bgColor = "bgcolor=\"darkslategray1\"";
- // for interface, counts amount of found implementations
- private int implementationsCount = 0;
+ return bgColor;
+ }
- // counts amount of times this class is extended
- private int extensionsCount = 0;
+ private String getBorderWidth() {
- private ClassDescriptor arrayComponent;
+ if (!areReferencesShown())
+ return "4";
+ return "1";
+ }
- public ClassDescriptor(final ClassGraph classGraph) {
- this.classGraph = classGraph;
- }
+ protected ClassGraph getClassGraph() {
+ return classGraph;
+ }
- protected void analyzeClass(final Class<? extends Object> clazz) {
+ protected String getClassName(final boolean differentiateArray) {
+ // this is needed for nested classes
+ final String actualClassName = fullyQualifiedName.replace('$', '.');
- fullyQualifiedName = clazz.getName();
+ String result;
+ if (isArray) {
+ // for arrays use array component instead of array class name
+ result = arrayComponent.fullyQualifiedName;
+ if (result.contains(".")) {
+ final int i = result.lastIndexOf('.');
+ result = result.substring(i + 1);
+ }
+ } else {
+ final int i = actualClassName.lastIndexOf('.');
+ result = actualClassName.substring(i + 1);
+ }
- isArray = clazz.isArray();
+ if (differentiateArray)
+ if (isArray)
+ result += " []";
- if (isArray) {
- final Class<?> componentType = clazz.getComponentType();
- arrayComponent = getClassGraph().getOrCreateClassDescriptor(
- componentType);
- }
+ // this is needed for nested classes
+ // result = result.replace('$', '.');
+ return result;
+ }
- // System.out.println("class: " + fullyQualifiedName);
+ protected String getColor() {
+ if (distinctiveReferenceColor == null)
+ distinctiveReferenceColor = Utils.getNextDarkColor();
- isEnum = clazz.isEnum();
+ return distinctiveReferenceColor;
+ }
- isInterface = clazz.isInterface();
+ @Override
+ public String getDot() {
+ if (!isVisible())
+ return "";
- if (!isVisible())
- return;
+ if (isArray)
+ return "";
- indexFields(clazz.getDeclaredFields());
- indexFields(clazz.getFields());
+ final StringBuffer result = new StringBuffer();
- indexMethods(clazz);
+ generateDotHeader(result);
- for (final Class interfaceClass : clazz.getInterfaces()) {
- final ClassDescriptor interfaceClassDescriptor = getClassGraph()
- .getOrCreateClassDescriptor(interfaceClass);
- interfaceClassDescriptor.registerImplementation();
- interfaces.add(interfaceClassDescriptor);
- }
+ enlistFields(result);
- superClass = getClassGraph().getOrCreateClassDescriptor(
- clazz.getSuperclass());
- if (superClass != null)
- superClass.registerExtension();
+ enlistMethods(result);
- };
+ result.append(" </TABLE>>, shape=\"none\"];\n");
- protected boolean areReferencesShown() {
- return referencesCount <= MAX_REFERECNES_COUNT;
- }
+ enlistFieldReferences(result);
- private void enlistFieldReferences(final StringBuffer result) {
- if (nameToFieldMap.isEmpty())
- return;
+ enlistMethodReferences(result);
- result.append("\n");
- result.append(" // field references to other classes\n");
- for (final Map.Entry<String, FieldDescriptor> entry : nameToFieldMap
- .entrySet())
- result.append(entry.getValue().getDot());
- }
+ enlistImplementedInterfaces(result);
- private void enlistFields(final StringBuffer result) {
- if (nameToFieldMap.isEmpty())
- return;
+ enlistSuperClass(result);
- result.append("\n");
- result.append(" // fields:\n");
+ return result.toString();
+ }
- // enlist fields
- for (final Map.Entry<String, FieldDescriptor> entry : nameToFieldMap
- .entrySet())
- result.append(entry.getValue().getEmbeddedDot());
- }
+ @Override
+ public String getEmbeddedDot() {
+ return null;
+ }
- private void enlistImplementedInterfaces(final StringBuffer result) {
- if (interfaces.isEmpty())
- return;
+ /**
+ * Returns field with given name (case is ignored). Or <code>null</code> if
+ * field is not found.
+ *
+ * @param fieldToSearch field name (case is ignored)
+ * @return field matching given name
+ */
+ protected FieldDescriptor getFieldIgnoreCase(final String fieldToSearch) {
- result.append("\n");
- result.append(" // interfaces implemented by class: "
- + fullyQualifiedName + "\n");
+ for (final String fieldName : nameToFieldMap.keySet())
+ if (fieldToSearch.equalsIgnoreCase(fieldName))
+ return nameToFieldMap.get(fieldName);
- for (final ClassDescriptor interfaceDescriptor : interfaces) {
- if (!interfaceDescriptor.isVisible())
- continue;
+ return null;
+ }
- if (!interfaceDescriptor.areReferencesShown())
- continue;
+ protected String getFullyQualifiedName() {
+ return fullyQualifiedName;
+ }
- result.append(" " + interfaceDescriptor.getGraphId() + " -> "
- + getGraphId() + "[style=\"dotted\", color=\""
- + interfaceDescriptor.getInterfaceColor()
- + "\", penwidth=10, dir=\"forward\"];\n");
- }
- }
+ @Override
+ public String getGraphId() {
+ final String result = "class_"
+ + fullyQualifiedName.replace('.', '_').replace(";", "")
+ .replace("[L", "").replace('$', '_');
+ return result;
+ }
- private void enlistMethodReferences(final StringBuffer result) {
- if (methods.isEmpty())
- return;
+ private String getInterfaceColor() {
+ if (interfaceColor == null)
+ interfaceColor = Utils.getNextDarkColor();
- result.append("\n");
- result.append(" // method references to other classes\n");
- for (final MethodDescriptor methodDescriptor : methods)
- result.append(methodDescriptor.getDot());
- }
+ return interfaceColor;
+ }
- private void enlistMethods(final StringBuffer result) {
- if (methods.isEmpty())
- return;
-
- result.append("\n");
- result.append(" // methods:\n");
-
- // enlist methods
- for (final MethodDescriptor methodDescriptor : methods)
- result.append(methodDescriptor.getEmbeddedDot());
- }
-
- private void enlistSuperClass(final StringBuffer result) {
- if (superClass == null)
- return;
-
- if (!superClass.isVisible())
- return;
-
- if (!superClass.areReferencesShown())
- return;
-
- result.append("\n");
- result.append(" // super class for: " + fullyQualifiedName + "\n");
-
- result.append(" " + superClass.getGraphId() + " -> " + getGraphId()
- + "[ color=\"" + superClass.getSuperClassColor()
- + "\", penwidth=10, dir=\"forward\"];\n");
- }
+ private FieldDescriptor getOrCreateFieldDescriptor(final Field field) {
- private void generateDotHeader(final StringBuffer result) {
- result.append("\n");
- result.append("// Class: " + fullyQualifiedName + "\n");
+ final String fieldName = field.getName();
- result.append(" " + getGraphId() + "[label=<<TABLE "
- + getBackgroundColor() + " BORDER=\"" + getBorderWidth()
- + "\" CELLBORDER=\"1\" CELLSPACING=\"0\">\n");
+ if (nameToFieldMap.containsKey(fieldName))
+ return nameToFieldMap.get(fieldName);
- result.append("\n");
- result.append(" // class descriptor header\n");
- result.append(" <TR><TD colspan=\"2\" PORT=\"f0\">"
- + "<FONT POINT-SIZE=\"8.0\" >" + getPackageName()
- + "</FONT><br/>");
+ final FieldDescriptor newFieldDescriptor = new FieldDescriptor(this);
+ nameToFieldMap.put(fieldName, newFieldDescriptor);
- final String parentClassesName = getParentClassesName();
- if (parentClassesName.length() > 0)
- result.append("<FONT POINT-SIZE=\"12.0\"><B>" + parentClassesName
- + "</B></FONT><br/>\n");
+ newFieldDescriptor.analyzeField(field);
- result.append("<FONT POINT-SIZE=\"25.0\"><B>" + getClassName(false)
- + "</B></FONT>" + "</TD></TR>\n");
- }
+ return newFieldDescriptor;
+ }
- private String getBackgroundColor() {
- String bgColor = "";
+ private int getOutgoingReferencesCount() {
+ int result = 0;
- if (isEnum)
- bgColor = "bgcolor=\"navajowhite2\"";
+ // count method references
+ for (final MethodDescriptor methodDescriptor : methods)
+ result += methodDescriptor.getOutsideVisibleReferencesCount();
- if (isInterface)
- bgColor = "bgcolor=\"darkslategray1\"";
+ // count field references
+ for (final FieldDescriptor fieldDescriptor : nameToFieldMap.values())
+ result += fieldDescriptor.getOutsideVisibleReferencesCount();
- return bgColor;
- }
+ // count implemented interfaces
+ for (final ClassDescriptor classDescriptor : interfaces)
+ if (classDescriptor.isVisible())
+ result++;
- private String getBorderWidth() {
+ // count superclass
+ if (superClass != null)
+ if (superClass.isVisible())
+ result++;
- if (!areReferencesShown())
- return "4";
- return "1";
- }
+ return result;
+ }
- protected ClassGraph getClassGraph() {
- return classGraph;
- }
+ private String getPackageName() {
- protected String getClassName(final boolean differentiateArray) {
- // this is needed for nested classes
- final String actualClassName = fullyQualifiedName.replace('$', '.');
+ final int i = fullyQualifiedName.lastIndexOf('.');
- String result;
- if (isArray) {
- // for arrays use array component instead of array class name
- result = arrayComponent.fullyQualifiedName;
- if (result.contains(".")) {
- final int i = result.lastIndexOf('.');
- result = result.substring(i + 1);
- }
- } else {
- final int i = actualClassName.lastIndexOf('.');
- result = actualClassName.substring(i + 1);
- }
+ if (i == -1)
+ return "";
- if (differentiateArray)
- if (isArray)
- result += " []";
+ return fullyQualifiedName.substring(0, i).replace("[L", "");
+ }
- // this is needed for nested classes
- // result = result.replace('$', '.');
- return result;
- }
+ private String getParentClassesName() {
+ int i = fullyQualifiedName.lastIndexOf('.');
+ final String fullClassName = fullyQualifiedName.substring(i + 1);
- protected String getColor() {
- if (distinctiveReferenceColor == null)
- distinctiveReferenceColor = Utils.getNextDarkColor();
+ i = fullClassName.lastIndexOf('$');
+ if (i == -1)
+ return "";
+ final String parentClassesName = fullClassName.substring(0, i);
+ return parentClassesName.replace('$', '.');
+ }
- return distinctiveReferenceColor;
- }
+ private String getSuperClassColor() {
+ if (superClassColor == null)
+ superClassColor = Utils.getNextLightColor();
- @Override
- public String getDot() {
- if (!isVisible())
- return "";
+ return superClassColor;
+ }
- if (isArray)
- return "";
+ /**
+ * Checks if class has field with given name (case is ignored). Returns
+ * <code>true</code> if such field is found.
+ *
+ * @param fieldToSearch field to search for (case is ignored)
+ * @return <code>true</code> if field is found.
+ */
+ protected boolean hasFieldIgnoreCase(final String fieldToSearch) {
- final StringBuffer result = new StringBuffer();
+ for (final String fieldName : nameToFieldMap.keySet())
+ if (fieldToSearch.equalsIgnoreCase(fieldName))
+ return true;
- generateDotHeader(result);
+ return false;
+ }
- enlistFields(result);
+ private void hide() {
+ isShown = false;
+ }
- enlistMethods(result);
+ protected void hideClassIfNoReferences() {
+ if (!isVisible())
+ return;
- result.append(" </TABLE>>, shape=\"none\"];\n");
+ final int totalReferencesCount = getOutgoingReferencesCount()
+ + referencesCount + extensionsCount + implementationsCount;
- enlistFieldReferences(result);
+ if (totalReferencesCount == 0) {
+ hide();
+ return;
+ }
- enlistMethodReferences(result);
+ return;
+ }
- enlistImplementedInterfaces(result);
+ private void indexFields(final Field[] fields) {
+ for (final Field field : fields)
+ getOrCreateFieldDescriptor(field);
+ }
- enlistSuperClass(result);
+ private void indexMethods(final Class<? extends Object> clazz) {
+ for (final Method method : clazz.getMethods()) {
+ final MethodDescriptor methodDescriptor = new MethodDescriptor(
+ this, method.getName());
- return result.toString();
- }
+ methods.add(methodDescriptor);
- @Override
- public String getEmbeddedDot() {
- return null;
- }
+ methodDescriptor.analyze(method);
+ }
- /**
- * Returns field with given name (case is ignored). Or <code>null</code> if
- * field is not found.
- *
- * @param fieldToSearch
- * field name (case is ignored)
- * @return field matching given name
- */
- protected FieldDescriptor getFieldIgnoreCase(final String fieldToSearch) {
+ }
- for (final String fieldName : nameToFieldMap.keySet())
- if (fieldToSearch.equalsIgnoreCase(fieldName))
- return nameToFieldMap.get(fieldName);
+ @Override
+ public boolean isVisible() {
- return null;
- }
+ if (Utils.isSystemDataType(fullyQualifiedName))
+ return false;
- protected String getFullyQualifiedName() {
- return fullyQualifiedName;
- }
+ if (Utils.isSystemPackage(fullyQualifiedName))
+ return false;
- @Override
- public String getGraphId() {
- final String result = "class_"
- + fullyQualifiedName.replace('.', '_').replace(";", "")
- .replace("[L", "").replace('$', '_');
- return result;
- }
+ if (!getClassGraph().isClassShown(fullyQualifiedName))
+ return false;
- private String getInterfaceColor() {
- if (interfaceColor == null)
- interfaceColor = Utils.getNextDarkColor();
+ if (isArray)
+ if (arrayComponent != null)
+ if (Utils.isSystemDataType(arrayComponent.fullyQualifiedName))
+ // Do not show references to primitive data types in arrays.
+ // That is: there is no point to show reference to byte when
+ // we have class with byte array field.
+ return false;
- return interfaceColor;
- }
+ return isShown;
+ }
- private FieldDescriptor getOrCreateFieldDescriptor(final Field field) {
+ /**
+ * Register event when another class is extending this one.
+ */
+ protected void registerExtension() {
+ extensionsCount++;
+ }
- final String fieldName = field.getName();
+ protected void registerImplementation() {
+ implementationsCount++;
+ }
- if (nameToFieldMap.containsKey(fieldName))
- return nameToFieldMap.get(fieldName);
+ protected void registerReference() {
+ referencesCount++;
+ }
- final FieldDescriptor newFieldDescriptor = new FieldDescriptor(this);
- nameToFieldMap.put(fieldName, newFieldDescriptor);
+ @Override
+ public boolean equals(Object o) {
+ if (this == o) return true;
+ if (!(o instanceof ClassDescriptor)) return false;
- newFieldDescriptor.analyzeField(field);
+ ClassDescriptor that = (ClassDescriptor) o;
- return newFieldDescriptor;
- }
+ return getFullyQualifiedName().equals(that.getFullyQualifiedName());
- private int getOutgoingReferencesCount() {
- int result = 0;
+ }
- // count method references
- for (final MethodDescriptor methodDescriptor : methods)
- result += methodDescriptor.getOutsideVisibleReferencesCount();
-
- // count field references
- for (final FieldDescriptor fieldDescriptor : nameToFieldMap.values())
- result += fieldDescriptor.getOutsideVisibleReferencesCount();
-
- // count implemented interfaces
- for (final ClassDescriptor classDescriptor : interfaces)
- if (classDescriptor.isVisible())
- result++;
-
- // count superclass
- if (superClass != null)
- if (superClass.isVisible())
- result++;
-
- return result;
- }
-
- private String getPackageName() {
-
- final int i = fullyQualifiedName.lastIndexOf('.');
-
- if (i == -1)
- return "";
-
- return fullyQualifiedName.substring(0, i).replace("[L", "");
- }
-
- private String getParentClassesName() {
- int i = fullyQualifiedName.lastIndexOf('.');
- final String fullClassName = fullyQualifiedName.substring(i + 1);
-
- i = fullClassName.lastIndexOf('$');
- if (i == -1)
- return "";
- final String parentClassesName = fullClassName.substring(0, i);
- return parentClassesName.replace('$', '.');
- }
-
- private String getSuperClassColor() {
- if (superClassColor == null)
- superClassColor = Utils.getNextLightColor();
-
- return superClassColor;
- }
-
- /**
- * Checks if class has field with given name (case is ignored). Returns
- * <code>true</code> if such field is found.
- *
- * @param fieldToSearch
- * field to search for (case is ignored)
- *
- * @return <code>true</code> if field is found.
- */
- protected boolean hasFieldIgnoreCase(final String fieldToSearch) {
-
- for (final String fieldName : nameToFieldMap.keySet())
- if (fieldToSearch.equalsIgnoreCase(fieldName))
- return true;
-
- return false;
- }
-
- private void hide() {
- isShown = false;
- }
-
- protected void hideClassIfNoReferences() {
- if (!isVisible())
- return;
-
- final int totalReferencesCount = getOutgoingReferencesCount()
- + referencesCount + extensionsCount + implementationsCount;
-
- if (totalReferencesCount == 0) {
- hide();
- return;
- }
-
- return;
- }
-
- private void indexFields(final Field[] fields) {
- for (final Field field : fields)
- getOrCreateFieldDescriptor(field);
- }
-
- private void indexMethods(final Class<? extends Object> clazz) {
- for (final Method method : clazz.getMethods()) {
- final MethodDescriptor methodDescriptor = new MethodDescriptor(
- this, method.getName());
-
- methods.add(methodDescriptor);
-
- methodDescriptor.analyze(method);
- }
-
- }
-
- @Override
- public boolean isVisible() {
-
- if (Utils.isSystemDataType(fullyQualifiedName))
- return false;
-
- if (Utils.isSystemPackage(fullyQualifiedName))
- return false;
-
- if (!getClassGraph().isClassShown(fullyQualifiedName))
- return false;
-
- if (isArray)
- if (arrayComponent != null)
- if (Utils.isSystemDataType(arrayComponent.fullyQualifiedName))
- // Do not show references to primitive data types in arrays.
- // That is: there is no point to show reference to byte when
- // we have class with byte array field.
- return false;
-
- return isShown;
- }
-
- /**
- * Register event when another class is extending this one.
- */
- protected void registerExtension() {
- extensionsCount++;
- }
-
- protected void registerImplementation() {
- implementationsCount++;
- }
-
- protected void registerReference() {
- referencesCount++;
- }
+ @Override
+ public int hashCode() {
+ return getFullyQualifiedName().hashCode();
+ }
+ @Override
+ public int compareTo(ClassDescriptor o) {
+ return fullyQualifiedName.compareTo(o.fullyQualifiedName);
+ }
}
package eu.svjatoslav.inspector.java.structure;
+import eu.svjatoslav.commons.file.CommonPathResolver;
+import eu.svjatoslav.commons.string.WildCardMatcher;
+import eu.svjatoslav.inspector.java.methods.Clazz;
+import eu.svjatoslav.inspector.java.methods.ProjectScanner;
+
import java.io.File;
import java.io.IOException;
import java.io.PrintWriter;
import java.util.List;
import java.util.Map;
-import eu.svjatoslav.commons.file.CommonPathResolver;
-import eu.svjatoslav.commons.string.WildCardMatcher;
-import eu.svjatoslav.inspector.java.methods.Clazz;
-import eu.svjatoslav.inspector.java.methods.ProjectScanner;
+import static eu.svjatoslav.inspector.java.methods.JavaFile.UTF_8;
public class ClassGraph {
- /**
- * Maps class fully qualified names to class descriptors.
- */
- private final Map<String, ClassDescriptor> fullyQualifiedNameToClassMap = new HashMap<String, ClassDescriptor>();
-
- private final List<String> blacklistClassPatterns = new ArrayList<String>();
-
- private final List<String> whitelistClassPatterns = new ArrayList<String>();
-
- private String targetDirectory = CommonPathResolver.getDesktopDirectory()
- .getAbsolutePath() + "/";
-
- private boolean keepDotFile;
-
- public ClassGraph() {
- }
-
- /**
- * @param objects
- * objects that shall be added to graph
- *
- * @return this {@link ClassGraph}
- */
- public ClassGraph add(final Object... objects) {
-
- if (objects != null)
- for (final Object object : objects)
- addObject(object);
-
- return this;
- }
-
- private void addObject(final Object object) {
- if (object instanceof Class)
- getOrCreateClassDescriptor((Class) object);
- else
- getOrCreateClassDescriptor(object.getClass());
- }
-
- /**
- * @param path
- * path to recursively scan for java source code could be
- * relative to current project or absolute
- */
- public void addProject(final String path) {
- final ProjectScanner projectScanner = new ProjectScanner(new File(path));
- for (final Clazz clazz : projectScanner.getAllClasses())
- try {
- System.out.println("Class full name: " + clazz.getFullName());
- final Class c = this.getClass().forName(clazz.getFullName());
- addObject(c);
- } catch (final Exception exception) {
- System.out.println("cannot add class: "
- + exception.getMessage());
- }
- }
-
- public void blacklistClassPattern(final String pattern) {
- blacklistClassPatterns.add(pattern);
- }
-
- /**
- * @param resultFileName
- * file name for the generated graph. File extension will be
- * added automatically. Existing file with the same name will be
- * overwritten.
- *
- */
-
- public void generateGraph(final String resultFileName) {
-
- final String dotFilePath = targetDirectory + resultFileName + ".dot";
- final String imageFilePath = targetDirectory + resultFileName + ".png";
-
- System.out.println("Dot file path:" + dotFilePath);
-
- try {
- // write DOT file to disk
- final PrintWriter out = new PrintWriter(dotFilePath);
- out.write(getDot());
- out.close();
-
- // execute GraphViz to visualize graph
- try {
- Runtime.getRuntime()
- .exec(new String[] { "dot", "-Tpng", dotFilePath, "-o",
- imageFilePath }).waitFor();
- } catch (final InterruptedException e) {
- } finally {
- }
-
- if (!keepDotFile)
- // delete dot file
- new File(dotFilePath).delete();
- } catch (final IOException e) {
- System.err.println(e);
- }
-
- }
-
- private String getDot() {
- final StringBuffer result = new StringBuffer();
-
- result.append("digraph Java {\n");
- result.append("graph [rankdir=LR, overlap = false, concentrate=true];\n");
-
- for (final Map.Entry<String, ClassDescriptor> entry : fullyQualifiedNameToClassMap
- .entrySet())
- result.append(entry.getValue().getDot());
-
- result.append("}\n");
-
- final String resultStr = result.toString();
- return resultStr;
- }
-
- /**
- * @param clazz
- * class that shall be added to graph
- *
- * @return {@link ClassDescriptor} corresponding to given {@link Class}
- */
- protected ClassDescriptor getOrCreateClassDescriptor(final Class clazz) {
-
- if (clazz == null)
- return null;
-
- final String classFullyQualifiedName = clazz.getName();
-
- // reuse existing instance if possible
- if (fullyQualifiedNameToClassMap.containsKey(classFullyQualifiedName))
- return fullyQualifiedNameToClassMap.get(classFullyQualifiedName);
-
- // create new class descriptor
- final ClassDescriptor newClassDescriptor = new ClassDescriptor(this);
- fullyQualifiedNameToClassMap.put(classFullyQualifiedName,
- newClassDescriptor);
-
- newClassDescriptor.analyzeClass(clazz);
-
- return newClassDescriptor;
- }
-
- /**
- * Hide orphaned class that have no references
- *
- * @return this {@link ClassGraph}
- */
- public ClassGraph hideOrphanedClasses() {
-
- for (final ClassDescriptor classDescriptor : fullyQualifiedNameToClassMap
- .values())
- classDescriptor.hideClassIfNoReferences();
+ /**
+ * Maps class fully qualified names to class descriptors.
+ */
+ private final Map<String, ClassDescriptor> fullyQualifiedNameToClassMap = new HashMap<String, ClassDescriptor>();
+
+ private final List<String> blacklistClassPatterns = new ArrayList<String>();
+
+ private final List<String> whitelistClassPatterns = new ArrayList<String>();
+
+ private String targetDirectory = CommonPathResolver.getDesktopDirectory()
+ .getAbsolutePath() + "/";
+
+ private boolean keepDotFile;
+
+ public ClassGraph() {
+ }
+
+ /**
+ * @param objects objects that shall be added to graph
+ * @return this {@link ClassGraph}
+ */
+ public ClassGraph add(final Object... objects) {
+
+ if (objects != null)
+ for (final Object object : objects)
+ addObject(object);
+
+ return this;
+ }
+
+ private void addObject(final Object object) {
+ if (object instanceof Class)
+ getOrCreateClassDescriptor((Class) object);
+ else
+ getOrCreateClassDescriptor(object.getClass());
+ }
+
+ /**
+ * @param path path to recursively scan for java source code could be
+ * relative to current project or absolute
+ */
+ public void addProject(final String path) {
+ final ProjectScanner projectScanner = new ProjectScanner(new File(path));
+ for (final Clazz clazz : projectScanner.getAllClasses())
+ try {
+ System.out.println("Class full name: " + clazz.getFullName());
+ final Class c = this.getClass().forName(clazz.getFullName());
+ addObject(c);
+ } catch (final Exception exception) {
+ System.out.println("cannot add class: "
+ + exception.getMessage());
+ }
+ }
+
+ public void blacklistClassPattern(final String pattern) {
+ blacklistClassPatterns.add(pattern);
+ }
+
+ /**
+ * @param resultFileName file name for the generated graph. File extension will be
+ * added automatically. Existing file with the same name will be
+ * overwritten.
+ */
+
+ public void generateGraph(final String resultFileName) {
+
+ final String dotFilePath = targetDirectory + resultFileName + ".dot";
+ final String imageFilePath = targetDirectory + resultFileName + ".png";
+
+ System.out.println("Dot file path:" + dotFilePath);
+
+ try {
+ // write DOT file to disk
+ final PrintWriter out = new PrintWriter(dotFilePath, UTF_8);
+ out.write(getDot());
+ out.close();
+
+ // execute GraphViz to visualize graph
+ try {
+ Runtime.getRuntime()
+ .exec(new String[]{"dot", "-Tpng", dotFilePath, "-o",
+ imageFilePath}).waitFor();
+ } catch (final InterruptedException ignored) {
+ }
+
+ if (!keepDotFile)
+ // delete dot file
+ if (!new File(dotFilePath).delete()) throw new RuntimeException("Cannot delete file: " + dotFilePath);
+ } catch (final IOException e) {
+ System.err.println(e);
+ }
+
+ }
+
+ private String getDot() {
+ final StringBuffer result = new StringBuffer();
+
+ result.append("digraph Java {\n");
+ result.append("graph [rankdir=LR, overlap = false, concentrate=true];\n");
+
+ for (final Map.Entry<String, ClassDescriptor> entry : fullyQualifiedNameToClassMap
+ .entrySet())
+ result.append(entry.getValue().getDot());
+
+ result.append("}\n");
+
+ final String resultStr = result.toString();
+ return resultStr;
+ }
+
+ /**
+ * @param clazz class that shall be added to graph
+ * @return {@link ClassDescriptor} corresponding to given {@link Class}
+ */
+ protected ClassDescriptor getOrCreateClassDescriptor(final Class clazz) {
+
+ if (clazz == null)
+ return null;
+
+ final String classFullyQualifiedName = clazz.getName();
+
+ // reuse existing instance if possible
+ if (fullyQualifiedNameToClassMap.containsKey(classFullyQualifiedName))
+ return fullyQualifiedNameToClassMap.get(classFullyQualifiedName);
+
+ // create new class descriptor
+ final ClassDescriptor newClassDescriptor = new ClassDescriptor(this);
+ fullyQualifiedNameToClassMap.put(classFullyQualifiedName,
+ newClassDescriptor);
+
+ newClassDescriptor.analyzeClass(clazz);
+
+ return newClassDescriptor;
+ }
+
+ /**
+ * Hide orphaned class that have no references
+ *
+ * @return this {@link ClassGraph}
+ */
+ public ClassGraph hideOrphanedClasses() {
+
+ for (final ClassDescriptor classDescriptor : fullyQualifiedNameToClassMap
+ .values())
+ classDescriptor.hideClassIfNoReferences();
- return this;
- }
+ return this;
+ }
- protected boolean isClassShown(final String className) {
- for (final String pattern : blacklistClassPatterns)
- if (WildCardMatcher.match(className, pattern))
- return false;
+ protected boolean isClassShown(final String className) {
+ for (final String pattern : blacklistClassPatterns)
+ if (WildCardMatcher.match(className, pattern))
+ return false;
- if (!whitelistClassPatterns.isEmpty()) {
- for (final String pattern : whitelistClassPatterns)
- if (WildCardMatcher.match(className, pattern))
- return true;
- return false;
- }
+ if (!whitelistClassPatterns.isEmpty()) {
+ for (final String pattern : whitelistClassPatterns)
+ if (WildCardMatcher.match(className, pattern))
+ return true;
+ return false;
+ }
- return true;
- }
+ return true;
+ }
- public ClassGraph setKeepDotFile(final boolean keepDotFile) {
- this.keepDotFile = keepDotFile;
+ public ClassGraph setKeepDotFile(final boolean keepDotFile) {
+ this.keepDotFile = keepDotFile;
- return this;
- }
+ return this;
+ }
- public ClassGraph setTargetDirectory(String directoryPath) {
- if (!directoryPath.endsWith("/"))
- directoryPath += "/";
+ public ClassGraph setTargetDirectory(String directoryPath) {
+ if (!directoryPath.endsWith("/"))
+ directoryPath += "/";
- targetDirectory = directoryPath;
+ targetDirectory = directoryPath;
- return this;
- }
+ return this;
+ }
- public ClassGraph whitelistClassPattern(final String pattern) {
- whitelistClassPatterns.add(pattern);
+ public ClassGraph whitelistClassPattern(final String pattern) {
+ whitelistClassPatterns.add(pattern);
- return this;
- }
+ return this;
+ }
}
public class FieldDescriptor implements GraphElement {
- private String name;
- private ClassDescriptor type;
- private final ClassDescriptor parentClass;
- private final List<ClassDescriptor> typeArguments = new ArrayList<ClassDescriptor>();
- private boolean isInherited;
-
- public FieldDescriptor(final ClassDescriptor parent) {
- parentClass = parent;
- }
-
- public void analyzeField(final Field field) {
-
- if (!field.getDeclaringClass().getName()
- .equals(parentClass.getFullyQualifiedName()))
- isInherited = true;
-
- name = field.getName();
- type = parentClass.getClassGraph().getOrCreateClassDescriptor(
- field.getType());
- type.registerReference();
-
- final Type genericType = field.getGenericType();
- if (genericType instanceof ParameterizedType) {
- final ParameterizedType pt = (ParameterizedType) genericType;
- for (final Type t : pt.getActualTypeArguments())
- if (t instanceof Class) {
- final Class cl = (Class) t;
- final ClassDescriptor genericTypeDescriptor = parentClass
- .getClassGraph().getOrCreateClassDescriptor(cl);
- genericTypeDescriptor.registerReference();
- typeArguments.add(genericTypeDescriptor);
- }
-
- }
- }
-
- @Override
- public String getDot() {
-
- if (!isVisible())
- return "";
-
- final StringBuffer result = new StringBuffer();
-
- // describe associated types
- for (final ClassDescriptor classDescriptor : typeArguments)
- if (classDescriptor.isVisible())
- if (classDescriptor.areReferencesShown())
- result.append(" " + getGraphId() + " -> "
- + classDescriptor.getGraphId() + "[label=\"" + name
- + "\", color=\"" + classDescriptor.getColor()
- + "\", style=\"bold\"];\n");
-
- if (!type.isVisible())
- return result.toString();
-
- // main type
- boolean showLink = type.areReferencesShown();
-
- if (type == parentClass)
- showLink = false;
-
- if (parentClass.isEnum)
- showLink = false;
-
- if (showLink)
- result.append(" " + getGraphId() + " -> " + type.getGraphId()
- + "[label=\"" + name + "\"," + " color=\""
- + type.getColor() + "\", style=\"bold\"];\n");
-
- return result.toString();
- }
-
- @Override
- public String getEmbeddedDot() {
-
- if (!isVisible())
- return "";
-
- final StringBuffer result = new StringBuffer();
-
- result.append(" // " + name + "\n");
- if (parentClass.isEnum && (type == parentClass)) {
- result.append(" <TR><TD colspan=\"2\" PORT=\"" + name);
- result.append("\" ALIGN=\"left\"><FONT POINT-SIZE=\"11.0\">");
- result.append(name + "</FONT></TD></TR>\n");
- } else {
- result.append(" <TR><td ALIGN=\"right\">");
- result.append("<FONT POINT-SIZE=\"8.0\">");
- result.append(type.getClassName(true) + "</FONT>");
- result.append("</td><TD PORT=\"" + name);
- result.append("\" ALIGN=\"left\"><FONT POINT-SIZE=\"11.0\">");
- result.append(name + "</FONT></TD></TR>\n");
- }
- return result.toString();
- }
-
- @Override
- public String getGraphId() {
- return parentClass.getGraphId() + ":" + name;
- }
-
- protected int getOutsideVisibleReferencesCount() {
-
- if (!isVisible())
- return 0;
-
- if (type != null)
- if (type.isVisible())
- return 1;
-
- return 0;
- }
-
- protected ClassDescriptor getType() {
- return type;
- }
-
- @Override
- public boolean isVisible() {
- if (isInherited)
- return false;
-
- if (name.contains("$"))
- return false;
-
- if (name.equals("serialVersionUID"))
- return false;
+ private final ClassDescriptor parentClass;
+ private final List<ClassDescriptor> typeArguments = new ArrayList<ClassDescriptor>();
+ private String name;
+ private ClassDescriptor type;
+ private boolean isInherited;
+
+ public FieldDescriptor(final ClassDescriptor parent) {
+ parentClass = parent;
+ }
+
+ public void analyzeField(final Field field) {
+
+ if (!field.getDeclaringClass().getName()
+ .equals(parentClass.getFullyQualifiedName()))
+ isInherited = true;
+
+ name = field.getName();
+ type = parentClass.getClassGraph().getOrCreateClassDescriptor(
+ field.getType());
+ type.registerReference();
+
+ final Type genericType = field.getGenericType();
+ if (genericType instanceof ParameterizedType) {
+ final ParameterizedType pt = (ParameterizedType) genericType;
+ for (final Type t : pt.getActualTypeArguments())
+ if (t instanceof Class) {
+ final Class cl = (Class) t;
+ final ClassDescriptor genericTypeDescriptor = parentClass
+ .getClassGraph().getOrCreateClassDescriptor(cl);
+ genericTypeDescriptor.registerReference();
+ typeArguments.add(genericTypeDescriptor);
+ }
+
+ }
+ }
+
+ @Override
+ public String getDot() {
+
+ if (!isVisible())
+ return "";
+
+ final StringBuffer result = new StringBuffer();
+
+ // describe associated types
+ for (final ClassDescriptor classDescriptor : typeArguments)
+ if (classDescriptor.isVisible())
+ if (classDescriptor.areReferencesShown())
+ result.append(" " + getGraphId() + " -> "
+ + classDescriptor.getGraphId() + "[label=\"" + name
+ + "\", color=\"" + classDescriptor.getColor()
+ + "\", style=\"bold\"];\n");
+
+ if (!type.isVisible())
+ return result.toString();
+
+ // main type
+ boolean showLink = type.areReferencesShown();
+
+ if (type == parentClass)
+ showLink = false;
+
+ if (parentClass.isEnum)
+ showLink = false;
+
+ if (showLink)
+ result.append(" " + getGraphId() + " -> " + type.getGraphId()
+ + "[label=\"" + name + "\"," + " color=\""
+ + type.getColor() + "\", style=\"bold\"];\n");
+
+ return result.toString();
+ }
+
+ @Override
+ public String getEmbeddedDot() {
+
+ if (!isVisible())
+ return "";
+
+ final StringBuffer result = new StringBuffer();
+
+ result.append(" // " + name + "\n");
+ if (parentClass.isEnum && (type == parentClass)) {
+ result.append(" <TR><TD colspan=\"2\" PORT=\"" + name);
+ result.append("\" ALIGN=\"left\"><FONT POINT-SIZE=\"11.0\">");
+ result.append(name + "</FONT></TD></TR>\n");
+ } else {
+ result.append(" <TR><td ALIGN=\"right\">");
+ result.append("<FONT POINT-SIZE=\"8.0\">");
+ result.append(type.getClassName(true) + "</FONT>");
+ result.append("</td><TD PORT=\"" + name);
+ result.append("\" ALIGN=\"left\"><FONT POINT-SIZE=\"11.0\">");
+ result.append(name + "</FONT></TD></TR>\n");
+ }
+ return result.toString();
+ }
+
+ @Override
+ public String getGraphId() {
+ return parentClass.getGraphId() + ":" + name;
+ }
+
+ protected int getOutsideVisibleReferencesCount() {
+
+ if (!isVisible())
+ return 0;
+
+ if (type != null)
+ if (type.isVisible())
+ return 1;
+
+ return 0;
+ }
+
+ protected ClassDescriptor getType() {
+ return type;
+ }
+
+ @Override
+ public boolean isVisible() {
+ if (isInherited)
+ return false;
+
+ if (name.contains("$"))
+ return false;
+
+ return !name.equals("serialVersionUID");
- return true;
- }
+ }
}
\ No newline at end of file
public interface GraphElement {
- public String getDot();
+ String getDot();
- public String getEmbeddedDot();
+ String getEmbeddedDot();
- public String getGraphId();
+ String getGraphId();
- public boolean isVisible();
+ boolean isVisible();
}
* This class corresponds to single method within a java class.
*/
public class MethodDescriptor implements GraphElement,
- Comparable<MethodDescriptor> {
-
- private final String methodName;
- private ClassDescriptor returnType;
- private final ClassDescriptor parentClass;
- private final List<ClassDescriptor> argumentTypes = new ArrayList<ClassDescriptor>();
- private boolean isInherited;
-
- public MethodDescriptor(final ClassDescriptor parent,
- final String methodName) {
- parentClass = parent;
- this.methodName = methodName;
- }
-
- public void analyze(final Method method) {
-
- if (!method.getDeclaringClass().getName()
- .equals(parentClass.getFullyQualifiedName()))
- isInherited = true;
-
- returnType = parentClass.getClassGraph().getOrCreateClassDescriptor(
- method.getReturnType());
- returnType.registerReference();
-
- final Type genericType = method.getGenericReturnType();
- if (genericType instanceof ParameterizedType) {
- final ParameterizedType pt = (ParameterizedType) genericType;
- for (final Type t : pt.getActualTypeArguments())
- if (t instanceof Class) {
- final Class cl = (Class) t;
- final ClassDescriptor classDescriptor = parentClass
- .getClassGraph().getOrCreateClassDescriptor(cl);
- classDescriptor.registerReference();
- argumentTypes.add(classDescriptor);
- }
-
- }
- }
-
- @Override
- public int compareTo(final MethodDescriptor o) {
-
- final int nameComparisonResult = methodName.compareTo(o.methodName);
- if (nameComparisonResult != 0)
- return nameComparisonResult;
-
- return toString().compareTo(o.toString());
- }
-
- @Override
- public String getDot() {
-
- if (!isVisible())
- return "";
-
- final StringBuffer result = new StringBuffer();
-
- // describe associated types
- for (final ClassDescriptor classDescriptor : argumentTypes)
- if (classDescriptor.isVisible())
- if (classDescriptor.areReferencesShown())
- result.append(" " + getGraphId() + " -> "
- + classDescriptor.getGraphId() + "[label=\""
- + methodName + "\", color=\""
- + classDescriptor.getColor()
- + "\", style=\"dotted, bold\"];\n");
-
- if (!returnType.isVisible())
- return result.toString();
-
- // main type
- if (returnType.areReferencesShown())
- result.append(" " + getGraphId() + " -> "
- + returnType.getGraphId() + "[label=\"" + methodName
- + "\"," + " color=\"" + returnType.getColor()
- + "\", style=\"dotted, bold\"];\n");
-
- return result.toString();
- }
-
- @Override
- public String getEmbeddedDot() {
- if (!isVisible())
- return "";
-
- final StringBuffer result = new StringBuffer();
-
- result.append(" // " + methodName + "\n");
-
- result.append(" <TR><td ALIGN=\"right\">"
- + "<FONT POINT-SIZE=\"8.0\">" + returnType.getClassName(true)
- + "</FONT>" + "</td><TD PORT=\"" + getMethodLabel()
- + "\" ALIGN=\"left\"><FONT COLOR =\"red\" POINT-SIZE=\"11.0\">"
- + getMethodLabel() + "</FONT></TD></TR>\n");
-
- return result.toString();
- }
-
- @Override
- public String getGraphId() {
- return parentClass.getGraphId() + ":" + methodName;
- }
-
- private String getMethodLabel() {
- return methodName;
- }
+ Comparable<MethodDescriptor> {
+
+ private final String methodName;
+ private final ClassDescriptor parentClass;
+ private final List<ClassDescriptor> argumentTypes = new ArrayList<ClassDescriptor>();
+ private ClassDescriptor returnType;
+ private boolean isInherited;
+
+ public MethodDescriptor(final ClassDescriptor parent,
+ final String methodName) {
+ parentClass = parent;
+ this.methodName = methodName;
+ }
+
+ public void analyze(final Method method) {
+
+ if (!method.getDeclaringClass().getName()
+ .equals(parentClass.getFullyQualifiedName()))
+ isInherited = true;
+
+ returnType = parentClass.getClassGraph().getOrCreateClassDescriptor(
+ method.getReturnType());
+ returnType.registerReference();
+
+ final Type genericType = method.getGenericReturnType();
+ if (genericType instanceof ParameterizedType) {
+ final ParameterizedType pt = (ParameterizedType) genericType;
+ for (final Type t : pt.getActualTypeArguments())
+ if (t instanceof Class) {
+ final Class cl = (Class) t;
+ final ClassDescriptor classDescriptor = parentClass
+ .getClassGraph().getOrCreateClassDescriptor(cl);
+ classDescriptor.registerReference();
+ argumentTypes.add(classDescriptor);
+ }
+
+ }
+ }
- protected int getOutsideVisibleReferencesCount() {
- int result = 0;
-
- if (returnType.isVisible())
- result++;
+ @Override
+ public boolean equals(Object o) {
+ if (this == o) return true;
+ if (!(o instanceof MethodDescriptor)) return false;
+
+ MethodDescriptor that = (MethodDescriptor) o;
+
+ if (methodName != null ? !methodName.equals(that.methodName) : that.methodName != null) return false;
+ if (parentClass != null ? !parentClass.equals(that.parentClass) : that.parentClass != null) return false;
+ return argumentTypes != null ? argumentTypes.equals(that.argumentTypes) : that.argumentTypes == null;
+
+ }
+
+
+ @Override
+ public int hashCode() {
+ int result = methodName != null ? methodName.hashCode() : 0;
+ result = 31 * result + (parentClass != null ? parentClass.hashCode() : 0);
+ result = 31 * result + (argumentTypes != null ? argumentTypes.hashCode() : 0);
+ return result;
+ }
+
+ @Override
+ public String getDot() {
+
+ if (!isVisible())
+ return "";
+
+ final StringBuffer result = new StringBuffer();
+
+ // describe associated types
+ for (final ClassDescriptor classDescriptor : argumentTypes)
+ if (classDescriptor.isVisible())
+ if (classDescriptor.areReferencesShown())
+ result.append(" " + getGraphId() + " -> "
+ + classDescriptor.getGraphId() + "[label=\""
+ + methodName + "\", color=\""
+ + classDescriptor.getColor()
+ + "\", style=\"dotted, bold\"];\n");
+
+ if (!returnType.isVisible())
+ return result.toString();
+
+ // main type
+ if (returnType.areReferencesShown())
+ result.append(" " + getGraphId() + " -> "
+ + returnType.getGraphId() + "[label=\"" + methodName
+ + "\"," + " color=\"" + returnType.getColor()
+ + "\", style=\"dotted, bold\"];\n");
+
+ return result.toString();
+ }
+
+ @Override
+ public String getEmbeddedDot() {
+ if (!isVisible())
+ return "";
+
+ final StringBuffer result = new StringBuffer();
+
+ result.append(" // " + methodName + "\n");
+
+ result.append(" <TR><td ALIGN=\"right\">"
+ + "<FONT POINT-SIZE=\"8.0\">" + returnType.getClassName(true)
+ + "</FONT>" + "</td><TD PORT=\"" + getMethodLabel()
+ + "\" ALIGN=\"left\"><FONT COLOR =\"red\" POINT-SIZE=\"11.0\">"
+ + getMethodLabel() + "</FONT></TD></TR>\n");
+
+ return result.toString();
+ }
+
+ @Override
+ public String getGraphId() {
+ return parentClass.getGraphId() + ":" + methodName;
+ }
+
+ private String getMethodLabel() {
+ return methodName;
+ }
+
+ protected int getOutsideVisibleReferencesCount() {
+ int result = 0;
+
+ if (returnType.isVisible())
+ result++;
+
+ for (final ClassDescriptor classDescriptor : argumentTypes)
+ if (classDescriptor.isVisible())
+ result++;
- for (final ClassDescriptor classDescriptor : argumentTypes)
- if (classDescriptor.isVisible())
- result++;
-
- return result;
- }
+ return result;
+ }
- @Override
- public boolean isVisible() {
+ @Override
+ public boolean isVisible() {
- // hide inherited methods
- if (isInherited)
- return false;
+ // hide inherited methods
+ if (isInherited)
+ return false;
- // hide common object methods
- if (Utils.isCommonObjectMethod(methodName))
- return false;
+ // hide common object methods
+ if (Utils.isCommonObjectMethod(methodName))
+ return false;
- // hide common Enumeration methods
- if (parentClass.isEnum && Utils.isEnumMethod(methodName))
- return false;
+ // hide common Enumeration methods
+ if (parentClass.isEnum && Utils.isEnumMethod(methodName))
+ return false;
- // hide get/set methods for the field of the same name
- if (methodName.startsWith("get") || methodName.startsWith("set"))
- if (parentClass.hasFieldIgnoreCase(methodName.substring(3)))
- return false;
+ // hide get/set methods for the field of the same name
+ if (methodName.startsWith("get") || methodName.startsWith("set"))
+ if (parentClass.hasFieldIgnoreCase(methodName.substring(3)))
+ return false;
- // hide is methods for the boolean field of the same name
- if (methodName.startsWith("is")) {
- final FieldDescriptor field = parentClass
- .getFieldIgnoreCase(methodName.substring(2));
- if (field != null)
- if ("boolean".equals(field.getType().getFullyQualifiedName()))
- return false;
- }
+ // hide is methods for the boolean field of the same name
+ if (methodName.startsWith("is")) {
+ final FieldDescriptor field = parentClass
+ .getFieldIgnoreCase(methodName.substring(2));
+ if (field != null)
+ if ("boolean".equals(field.getType().getFullyQualifiedName()))
+ return false;
+ }
- return true;
+ return true;
- }
+ }
+ @Override
+ public int compareTo(MethodDescriptor that) {
+ if (this == that) return 0;
+
+ int comparisonResult = methodName.compareTo(that.methodName);
+ if (comparisonResult != 0) return comparisonResult;
+
+ return parentClass.compareTo(that.parentClass);
+ }
}
public class Utils {
- /**
- * retrieves colors from predefined palette
- *
- * @return next available dark color name
- */
- protected static String getNextDarkColor() {
- lastChosenDarkColor++;
- if (lastChosenDarkColor >= darkColors.size())
- lastChosenDarkColor = 0;
-
- return darkColors.get(lastChosenDarkColor);
- }
-
- /**
- * retrieves colors from predefined palette
- *
- * @return next available light color name
- */
- protected static String getNextLightColor() {
- lastChosenLightColor++;
- if (lastChosenLightColor >= lightColors.size())
- lastChosenLightColor = 0;
-
- return lightColors.get(lastChosenLightColor);
- }
-
- private static void initCommonObjectMethods() {
- commonObjectMethods.add("wait");
- commonObjectMethods.add("equals");
- commonObjectMethods.add("toString");
- commonObjectMethods.add("hashCode");
- commonObjectMethods.add("notify");
- commonObjectMethods.add("notifyAll");
- commonObjectMethods.add("getClass");
- }
-
- protected static void initDarkColors() {
- darkColors.add("antiquewhite4");
- darkColors.add("blueviolet");
- darkColors.add("brown4");
- darkColors.add("chartreuse4");
- darkColors.add("cyan4");
- darkColors.add("deeppink1");
- darkColors.add("deepskyblue3");
- darkColors.add("firebrick1");
- darkColors.add("goldenrod3");
- darkColors.add("gray0");
- }
-
- private static void initEnumMethods() {
- enumMethods.add("values");
- enumMethods.add("valueOf");
- enumMethods.add("name");
- enumMethods.add("compareTo");
- enumMethods.add("valueOf");
- enumMethods.add("getDeclaringClass");
- enumMethods.add("ordinal");
- }
-
- private static void initLightColors() {
- lightColors.add("olivedrab2");
- lightColors.add("peachpuff2");
- lightColors.add("seagreen1");
- lightColors.add("violet");
- lightColors.add("aqua");
- lightColors.add("orange");
- }
-
- private static void initSystemDataTypes() {
- systemDataTypes.add("void");
- systemDataTypes.add("int");
- systemDataTypes.add("long");
- systemDataTypes.add("float");
- systemDataTypes.add("double");
- systemDataTypes.add("boolean");
- systemDataTypes.add("char");
- systemDataTypes.add("short");
- systemDataTypes.add("byte");
- }
-
- private static void initSystemPackages() {
- systemPackages.add("java.");
- systemPackages.add("javax.");
- systemPackages.add("sun.");
- }
-
- protected static boolean isCommonObjectMethod(final String name) {
- return commonObjectMethods.contains(name);
- }
-
- protected static boolean isEnumMethod(final String name) {
- return enumMethods.contains(name);
- }
-
- protected static boolean isSystemDataType(final String name) {
- return systemDataTypes.contains(name);
- }
-
- protected static boolean isSystemPackage(final String name) {
-
- for (final String packagePrefix : systemPackages)
- if (name.startsWith(packagePrefix))
- return true;
-
- return false;
- }
-
- private static final List<String> systemDataTypes = new ArrayList<String>();
-
- private static final List<String> commonObjectMethods = new ArrayList<String>();
-
- private static final List<String> systemPackages = new ArrayList<String>();
-
- private static final List<String> darkColors = new ArrayList<String>();
-
- private static final List<String> lightColors = new ArrayList<String>();
-
- private static final List<String> enumMethods = new ArrayList<String>();
-
- private static int lastChosenDarkColor = -1;
-
- private static int lastChosenLightColor = -1;
-
- static {
- initEnumMethods();
- initSystemDataTypes();
- initDarkColors();
- initLightColors();
- initCommonObjectMethods();
- initSystemPackages();
- }
+ private static final List<String> systemDataTypes = new ArrayList<String>();
+ private static final List<String> commonObjectMethods = new ArrayList<String>();
+ private static final List<String> systemPackages = new ArrayList<String>();
+ private static final List<String> darkColors = new ArrayList<String>();
+ private static final List<String> lightColors = new ArrayList<String>();
+ private static final List<String> enumMethods = new ArrayList<String>();
+ private static int lastChosenDarkColor = -1;
+ private static int lastChosenLightColor = -1;
+
+ static {
+ initEnumMethods();
+ initSystemDataTypes();
+ initDarkColors();
+ initLightColors();
+ initCommonObjectMethods();
+ initSystemPackages();
+ }
+
+ /**
+ * retrieves colors from predefined palette
+ *
+ * @return next available dark color name
+ */
+ protected static String getNextDarkColor() {
+ lastChosenDarkColor++;
+ if (lastChosenDarkColor >= darkColors.size())
+ lastChosenDarkColor = 0;
+
+ return darkColors.get(lastChosenDarkColor);
+ }
+
+ /**
+ * retrieves colors from predefined palette
+ *
+ * @return next available light color name
+ */
+ protected static String getNextLightColor() {
+ lastChosenLightColor++;
+ if (lastChosenLightColor >= lightColors.size())
+ lastChosenLightColor = 0;
+
+ return lightColors.get(lastChosenLightColor);
+ }
+
+ private static void initCommonObjectMethods() {
+ commonObjectMethods.add("wait");
+ commonObjectMethods.add("equals");
+ commonObjectMethods.add("toString");
+ commonObjectMethods.add("hashCode");
+ commonObjectMethods.add("notify");
+ commonObjectMethods.add("notifyAll");
+ commonObjectMethods.add("getClass");
+ }
+
+ protected static void initDarkColors() {
+ darkColors.add("antiquewhite4");
+ darkColors.add("blueviolet");
+ darkColors.add("brown4");
+ darkColors.add("chartreuse4");
+ darkColors.add("cyan4");
+ darkColors.add("deeppink1");
+ darkColors.add("deepskyblue3");
+ darkColors.add("firebrick1");
+ darkColors.add("goldenrod3");
+ darkColors.add("gray0");
+ }
+
+ private static void initEnumMethods() {
+ enumMethods.add("values");
+ enumMethods.add("valueOf");
+ enumMethods.add("name");
+ enumMethods.add("compareTo");
+ enumMethods.add("valueOf");
+ enumMethods.add("getDeclaringClass");
+ enumMethods.add("ordinal");
+ }
+
+ private static void initLightColors() {
+ lightColors.add("olivedrab2");
+ lightColors.add("peachpuff2");
+ lightColors.add("seagreen1");
+ lightColors.add("violet");
+ lightColors.add("aqua");
+ lightColors.add("orange");
+ }
+
+ private static void initSystemDataTypes() {
+ systemDataTypes.add("void");
+ systemDataTypes.add("int");
+ systemDataTypes.add("long");
+ systemDataTypes.add("float");
+ systemDataTypes.add("double");
+ systemDataTypes.add("boolean");
+ systemDataTypes.add("char");
+ systemDataTypes.add("short");
+ systemDataTypes.add("byte");
+ }
+
+ private static void initSystemPackages() {
+ systemPackages.add("java.");
+ systemPackages.add("javax.");
+ systemPackages.add("sun.");
+ }
+
+ protected static boolean isCommonObjectMethod(final String name) {
+ return commonObjectMethods.contains(name);
+ }
+
+ protected static boolean isEnumMethod(final String name) {
+ return enumMethods.contains(name);
+ }
+
+ protected static boolean isSystemDataType(final String name) {
+ return systemDataTypes.contains(name);
+ }
+
+ protected static boolean isSystemPackage(final String name) {
+
+ for (final String packagePrefix : systemPackages)
+ if (name.startsWith(packagePrefix))
+ return true;
+
+ return false;
+ }
}
public class RenderDemoClasses {
- public static void main(final String[] args) {
+ public static void main(final String[] args) {
- new ClassGraph().add(SampleClass.class, SampleClass2.class)
- .generateGraph("example");
- }
+ new ClassGraph().add(SampleClass.class, SampleClass2.class)
+ .generateGraph("example");
+ }
}
package eu.svjatoslav.inspector.java.structure.example;
-import java.io.FileNotFoundException;
-
import eu.svjatoslav.inspector.java.structure.ClassGraph;
import eu.svjatoslav.inspector.java.structure.Utils;
+import java.io.FileNotFoundException;
+
public class RenderJavaInspect {
- private static void fullProjectExample() {
- // Create graph
- final ClassGraph graph = new ClassGraph();
+ private static void fullProjectExample() {
+ // Create graph
+ final ClassGraph graph = new ClassGraph();
- // Recursively scan current directory for Java source code and attempt
- // to detect class names from there to be added to the graph.
- graph.addProject(".");
+ // Recursively scan current directory for Java source code and attempt
+ // to detect class names from there to be added to the graph.
+ graph.addProject(".");
- // Blacklist example classes from being shown on the graph
- graph.blacklistClassPattern("eu.svjatoslav.inspector.java.structure.example.*");
+ // Blacklist example classes from being shown on the graph
+ graph.blacklistClassPattern("eu.svjatoslav.inspector.java.structure.example.*");
- // do not show single classes with no relationships on the graph
- graph.hideOrphanedClasses();
+ // do not show single classes with no relationships on the graph
+ graph.hideOrphanedClasses();
- // Produce bitmap image titled "JavaInspect full project.png" to the
- // user Desktop directory.
- graph.generateGraph("JavaInspect full project");
- }
+ // Produce bitmap image titled "JavaInspect full project.png" to the
+ // user Desktop directory.
+ graph.generateGraph("JavaInspect full project");
+ }
- private static void handpickClassesExample() {
- /*
- * This example demonstrates generating of class graph from hand picked
+ private static void handpickClassesExample() {
+ /*
+ * This example demonstrates generating of class graph from hand picked
* classes and visualizing GraphViz itself.
*/
- // Create graph
- final ClassGraph graph = new ClassGraph();
+ // Create graph
+ final ClassGraph graph = new ClassGraph();
- // Add some random object to the graph. GraphViz will detect Class from
- // the object.
- graph.add(graph);
+ // Add some random object to the graph. GraphViz will detect Class from
+ // the object.
+ graph.add(graph);
- // Also add some random class to the graph.
- graph.add(Utils.class);
+ // Also add some random class to the graph.
+ graph.add(Utils.class);
- // Keep intermediary GraphViz DOT file for reference.
- graph.setKeepDotFile(true);
+ // Keep intermediary GraphViz DOT file for reference.
+ graph.setKeepDotFile(true);
- // Produce bitmap image titled "JavaInspect.png" to the user Desktop
- // directory
- graph.generateGraph("JavaInspect");
- }
+ // Produce bitmap image titled "JavaInspect.png" to the user Desktop
+ // directory
+ graph.generateGraph("JavaInspect");
+ }
- public static void main(final String[] args) throws FileNotFoundException {
+ public static void main(final String[] args) throws FileNotFoundException {
- handpickClassesExample();
+ handpickClassesExample();
- fullProjectExample();
+ fullProjectExample();
- }
+ }
}
public class SampleClass extends SampleSuperClass {
- ObjectVisibleAsClassField sampleClassField;
+ ObjectVisibleAsClassField sampleClassField;
- public ObjectReturnedByMethod sampleMethod() {
- return new ObjectReturnedByMethod();
- }
+ public ObjectReturnedByMethod sampleMethod() {
+ return new ObjectReturnedByMethod();
+ }
}
public enum SampleEnum {
- ONE, TWO, THREE, FOUR
+ ONE, TWO, THREE, FOUR
}
package eu.svjatoslav.inspector.java.structure.example.structure;
public interface SampleInterface {
- public SampleEnum getSomeValue();
+ SampleEnum getSomeValue();
}
public class SampleSuperClass implements SampleInterface {
- @Override
- public SampleEnum getSomeValue() {
- return SampleEnum.ONE;
- }
+ @Override
+ public SampleEnum getSomeValue() {
+ return SampleEnum.ONE;
+ }
}