Skip to content

Commit

Permalink
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Refactor JSON writing behavior
Browse files Browse the repository at this point in the history
sanderploegsma committed Jan 18, 2024
1 parent c1a6325 commit 3038944
Showing 40 changed files with 753 additions and 790 deletions.
1 change: 0 additions & 1 deletion build.gradle
Original file line number Diff line number Diff line change
@@ -15,7 +15,6 @@ repositories {
dependencies {
implementation "org.json:json:20231013"
implementation "com.github.javaparser:javaparser-core:3.25.7"
implementation "com.google.guava:guava:33.0.0-jre"

testImplementation platform("org.junit:junit-bom:5.10.0")
testImplementation "org.junit.jupiter:junit-jupiter"
9 changes: 9 additions & 0 deletions src/main/java/analyzer/Analysis.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
package analyzer;

import java.util.Set;

public record Analysis(Set<Comment> comments, String summary) {
public Analysis {
comments = Set.copyOf(comments);
}
}
43 changes: 43 additions & 0 deletions src/main/java/analyzer/Comment.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
package analyzer;

import java.util.Map;
import java.util.Objects;

public abstract class Comment {

public abstract String getKey();

public Map<String, String> getParameters() {
return Map.of();
}

public CommentType getType() {
return null;
}

@Override
public boolean equals(Object obj) {
return (obj instanceof Comment other) && equals(other);
}

public boolean equals(Comment other) {
if (!getKey().equals(other.getKey()) || getType() != other.getType()) {
return false;
}

var params = this.getParameters().entrySet();
var otherParams = other.getParameters().entrySet();

return params.containsAll(otherParams) && otherParams.containsAll(params);
}

@Override
public int hashCode() {
return Objects.hash(getKey(), getType(), getParameters());
}

@Override
public String toString() {
return String.format("Comment{key=%s,params=%s,type=%s}", getKey(), getParameters(), getType());
}
}
8 changes: 8 additions & 0 deletions src/main/java/analyzer/CommentType.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
package analyzer;

public enum CommentType {
ESSENTIAL,
ACTIONABLE,
INFORMATIVE,
CELEBRATORY
}
67 changes: 67 additions & 0 deletions src/main/java/analyzer/Exercise.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,67 @@
package analyzer;

import analyzer.comments.FailedParse;
import analyzer.comments.FileNotFound;
import com.github.javaparser.JavaParser;
import com.github.javaparser.ParseProblemException;
import com.github.javaparser.ast.CompilationUnit;

import java.io.File;
import java.io.FileNotFoundException;
import java.util.HashSet;
import java.util.Set;

public abstract class Exercise {
private CompilationUnit compilationUnit;

private String summary;
private final Set<Comment> comments = new HashSet<>();
private final Set<String> tags = new HashSet<>();

protected Exercise(String directory, String solutionFile) {
this(getSolutionFile(directory, solutionFile));
}

protected Exercise(File solutionFile) {
try {
this.compilationUnit = new JavaParser().parse(solutionFile).getResult().get();
} catch (ParseProblemException e) {
addComment(new FailedParse());
} catch (FileNotFoundException e) {
addComment(new FileNotFound(solutionFile.getName()));
}
}

private static File getSolutionFile(String directory, String solutionFile) {
return new File(directory + "src/main/java/" + solutionFile);
}

public final void parse() {
if (compilationUnit == null) {
return;
}
parse(compilationUnit);
}

abstract public void parse(CompilationUnit compilationUnit);

protected void addComment(Comment comment) {
this.comments.add(comment);
}

protected void setSummary(String summary) {
this.summary = summary;
}

protected void addTag(String tag) {
this.tags.add(tag);
}

public Analysis getAnalysis() {
return new Analysis(this.comments, this.summary);
}

public Tags getTags() {
return new Tags(this.tags);
}
}
38 changes: 38 additions & 0 deletions src/main/java/analyzer/JsonSerializer.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
package analyzer;

import org.json.JSONObject;

public class JsonSerializer {
public static JSONObject serialize(Comment comment) {
var object = new JSONObject();
object.put("comment", comment.getKey());

if (comment.getType() != null) {
object.put("type", comment.getType().name().toLowerCase());
}

if (comment.getParameters().isEmpty()) {
return object;
}

var paramsObject = new JSONObject();
comment.getParameters().forEach(paramsObject::put);
object.put("params", paramsObject);
return object;
}

public static JSONObject serialize(Analysis analysis) {
var object = new JSONObject();

object.put("summary", analysis.summary());
analysis.comments().forEach(c -> object.append("comments", serialize(c)));

return object;
}

public static JSONObject serialize(Tags tags) {
var json = new JSONObject();
tags.tags().forEach(t -> json.append("tags", t));
return json;
}
}
30 changes: 25 additions & 5 deletions src/main/java/analyzer/Main.java
Original file line number Diff line number Diff line change
@@ -1,17 +1,20 @@
package analyzer;

import analyzer.exercises.Exercise;
import analyzer.exercises.twofer.Twofer;
import analyzer.exercises.hamming.Hamming;
import org.json.JSONObject;

import java.io.File;
import java.io.FileWriter;
import java.io.IOException;

public class Main {
private static final int JSON_INDENTATION = 2;
private static boolean isNotValidDirectory(String p) {
return !p.endsWith("/") || !new File(p).isDirectory();
}

public static void main(String... args) {
public static void main(String... args) throws IOException {
if (args.length < 3) {
System.err.println("Invalid arguments. Usage: java-analyzer <exercise slug> <exercise directory> <output directory>");
System.exit(-1);
@@ -33,18 +36,35 @@ public static void main(String... args) {
Exercise ex = null;
switch (slug) {
case "two-fer":
ex = new Twofer(inputDirectory, outputDirectory);
ex = new Twofer(inputDirectory);
break;
case "hamming":
ex = new Hamming(inputDirectory, outputDirectory);
ex = new Hamming(inputDirectory);
break;
default:
System.err.println("Exercise not found");
System.exit(-1);
}

ex.parse();
ex.writeAnalysisToFile();
writeAnalysisToFile(ex.getAnalysis(), outputDirectory);
writeTagsToFile(ex.getTags(), outputDirectory);
System.out.println("Analysis completed successfully");
}

private static void writeAnalysisToFile(Analysis analysis, String outputDirectory) throws IOException {
var json = JsonSerializer.serialize(analysis);
writeJsonToFile(json, outputDirectory, "analysis.json");
}

private static void writeTagsToFile(Tags tags, String outputDirectory) throws IOException {
var json = JsonSerializer.serialize(tags);
writeJsonToFile(json, outputDirectory, "tags.json");
}

private static void writeJsonToFile(JSONObject json, String outputDirectory, String filename) throws IOException {
try (var writer = new FileWriter(outputDirectory + filename)) {
writer.write(json.toString(JSON_INDENTATION));
}
}
}
9 changes: 9 additions & 0 deletions src/main/java/analyzer/Tags.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
package analyzer;

import java.util.Set;

public record Tags(Set<String> tags) {
public Tags {
tags = Set.copyOf(tags);
}
}
13 changes: 13 additions & 0 deletions src/main/java/analyzer/comments/AvoidHardCodedTestCases.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
package analyzer.comments;

import analyzer.Comment;

/**
* @see <a href="https://github.com/exercism/website-copy/blob/main/analyzer-comments/java/general/avoid_hard_coded_test_cases.md">Markdown Template</a>
*/
public class AvoidHardCodedTestCases extends Comment {
@Override
public String getKey() {
return "java.general.avoid_hard_coded_test_cases";
}
}
32 changes: 32 additions & 0 deletions src/main/java/analyzer/comments/ConstructorTooLong.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
package analyzer.comments;

import analyzer.Comment;

import java.util.Collection;
import java.util.List;
import java.util.Map;

/**
* @see <a href="https://github.com/exercism/website-copy/blob/main/analyzer-comments/java/general/constructor_too_long.md">Markdown Template</a>
*/
public class ConstructorTooLong extends Comment {
private final Collection<String> constructorNames;

public ConstructorTooLong(Collection<String> constructorNames) {
this.constructorNames = constructorNames;
}

public ConstructorTooLong(String constructorName) {
this(List.of(constructorName));
}

@Override
public String getKey() {
return "java.general.constructor_too_long";
}

@Override
public Map<String, String> getParameters() {
return Map.of("constructorNames", String.join(", ", this.constructorNames));
}
}
13 changes: 13 additions & 0 deletions src/main/java/analyzer/comments/FailedParse.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
package analyzer.comments;

import analyzer.Comment;

/**
* @see <a href="https://github.com/exercism/website-copy/blob/main/analyzer-comments/java/general/failed_parse.md">Markdown Template</a>
*/
public class FailedParse extends Comment {
@Override
public String getKey() {
return "java.general.failed_parse";
}
}
26 changes: 26 additions & 0 deletions src/main/java/analyzer/comments/FileNotFound.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
package analyzer.comments;

import analyzer.Comment;

import java.util.Map;

/**
* @see <a href="https://github.com/exercism/website-copy/blob/main/analyzer-comments/java/general/file_not_found.md">Markdown Template</a>
*/
public class FileNotFound extends Comment {
private final String solutionFile;

public FileNotFound(String solutionFile) {
this.solutionFile = solutionFile;
}

@Override
public String getKey() {
return "java.general.file_not_found";
}

@Override
public Map<String, String> getParameters() {
return Map.of("solutionFile", this.solutionFile);
}
}
32 changes: 32 additions & 0 deletions src/main/java/analyzer/comments/MethodTooLong.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
package analyzer.comments;

import analyzer.Comment;

import java.util.Collection;
import java.util.List;
import java.util.Map;

/**
* @see <a href="https://github.com/exercism/website-copy/blob/main/analyzer-comments/java/general/method_too_long.md">Markdown Template</a>
*/
public class MethodTooLong extends Comment {
private final Collection<String> methodNames;

public MethodTooLong(Collection<String> methodNames) {
this.methodNames = methodNames;
}

public MethodTooLong(String methodName) {
this(List.of(methodName));
}

@Override
public String getKey() {
return "java.general.method_too_long";
}

@Override
public Map<String, String> getParameters() {
return Map.of("methodNames", String.join(", ", this.methodNames));
}
}
26 changes: 26 additions & 0 deletions src/main/java/analyzer/comments/UseProperClassName.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
package analyzer.comments;

import analyzer.Comment;

import java.util.Map;

/**
* @see <a href="https://github.com/exercism/website-copy/blob/main/analyzer-comments/java/general/use_proper_class_name.md">Markdown Template</a>
*/
public class UseProperClassName extends Comment {
private final String className;

public UseProperClassName(String className) {
this.className = className;
}

@Override
public String getKey() {
return "java.general.use_proper_class_name";
}

@Override
public Map<String, String> getParameters() {
return Map.of("className", className);
}
}
Loading

0 comments on commit 3038944

Please sign in to comment.