-
Jack MacLauchlan CS2015 authoredJack MacLauchlan CS2015 authored
CommitReader.java 6.33 KiB
package git;
import com.fasterxml.jackson.core.type.TypeReference;
import com.fasterxml.jackson.databind.ObjectMapper;
import issueData.Comment;
import issueData.Issue;
import issueData.User;
import org.eclipse.jgit.lib.ObjectId;
import org.eclipse.jgit.lib.ObjectLoader;
import org.eclipse.jgit.lib.ObjectReader;
import org.eclipse.jgit.lib.Repository;
import org.eclipse.jgit.revwalk.RevTree;
import org.eclipse.jgit.treewalk.TreeWalk;
import java.io.File;
import java.io.IOException;
import java.nio.charset.StandardCharsets;
import java.util.*;
class CommitReader {
private final Repository repo;
private final List<Issue> issues;
private final ObjectMapper mapper;
private Map<String, String> nicknames;
CommitReader(Repository repo, RevTree commitTree) {
this.repo = repo;
this.issues = new ArrayList<>();
this.nicknames = new HashMap<>();
mapper = new ObjectMapper();
buildIssues(commitTree);
}
private void buildIssues(RevTree commitTree) {
try (TreeWalk treeWalk = new TreeWalk(repo)) {
treeWalk.addTree(commitTree);
treeWalk.setRecursive(true);
while (treeWalk.next()) {
ObjectId blob = treeWalk.getObjectId(0);
String content = getContent(blob);
if (treeWalk.getNameString().equals(".nicknames")) {
parseNicknames(content);
continue;
}
String hash = split(treeWalk.getPathString(), 0);
if (issues.isEmpty() || getIssue(hash) == null) {
Issue issue = new Issue();
issue.setHash(hash);
issues.add(issue);
addFieldData(issue, treeWalk.getPathString(), content);
} else {
addFieldData(getIssue(hash), treeWalk.getPathString(), content);
}
}
} catch (IOException e) {
System.err.println("Make sure no non-issue files have been created on issue branch");
e.printStackTrace();
}
}
private void parseNicknames(String content) throws IOException {
this.nicknames = mapper.readValue(content, new TypeReference<Map<String, String>>() {
});
}
private Issue getIssue(String hash) {
for (Issue issue : issues) {
if (issue.getHash().equals((hash))) {
return issue;
}
}
return null;
}
private String getContent(ObjectId blob) throws IOException {
try (ObjectReader objectReader = repo.newObjectReader()) {
ObjectLoader objectLoader = objectReader.open(blob);
byte[] bytes = objectLoader.getBytes();
return new String(bytes, StandardCharsets.UTF_8);
}
}
private byte[] getByteContent(ObjectId blob) throws IOException {
try (ObjectReader objectReader = repo.newObjectReader()) {
ObjectLoader objectLoader = objectReader.open(blob);
return objectLoader.getBytes();
}
}
private void addFieldData(Issue issue, String path, String data) throws IOException {
String field = split(path, 1);
switch (field) {
case "title":
issue.setTitle(mapper.readValue(data, String.class));
break;
case "description":
issue.setDescription(mapper.readValue(data, String.class));
break;
case "creator":
issue.setCreator(mapper.readValue(data, User.class));
break;
case "status":
issue.setStatus(mapper.readValue(data, boolean.class));
break;
case "creationTime":
issue.setCreationTime(mapper.readValue(data, long.class));
break;
case "editTime":
issue.setEdited(mapper.readValue(data, long.class));
break;
case "comments":
buildComment(issue, path, data);
break;
case "tags":
issue.setTags(mapper.readValue(data, new TypeReference<Set<String>>() {
}));
break;
case "watchers":
issue.setWatchers(mapper.readValue(data, new TypeReference<Set<User>>() {
}));
break;
case "assignees":
issue.setAssignees(mapper.readValue(data, new TypeReference<Set<User>>() {
}));
break;
case "attachments":
System.out.println(path);
issue.addAttachment(new File(path));
break;
default:
//ignore
break;
}
}
private void buildComment(Issue issue, String path, String data) throws IOException {
String commentHash = split(path, 2);
String commentField = split(path, 3);
if (issue.getComments().isEmpty() || getComment(issue, commentHash) == null) {
Comment comment = new Comment();
comment.setHash(commentHash);
issue.addComment(comment);
addCommentFields(comment, commentField, data);
} else {
addCommentFields(getComment(issue, commentHash), commentField, data);
}
}
private void addCommentFields(Comment comment, String field, String data) throws IOException {
switch (field) {
case "author":
comment.setAuthor(mapper.readValue(data, User.class));
break;
case "message":
comment.setMessage(mapper.readValue(data, String.class));
break;
case "commentTime":
comment.setCreationTime(mapper.readValue(data, long.class));
break;
default:
//ignore
break;
}
}
private Comment getComment(Issue issue, String hash) {
for (Comment comment : issue.getComments()) {
if (comment.getHash().equals((hash))) {
return comment;
}
}
return null;
}
List<Issue> getIssues() {
return issues;
}
Map<String, String> getNicknames() {
return nicknames;
}
private String split(String path, int index) {
return path.split("/")[index];
}
}