package com.chrome.codereview.model; import java.util.ArrayList; import java.util.List; import java.util.Scanner; import java.util.regex.Matcher; import java.util.regex.Pattern; /** * Created by sergeyv on 12/5/14. */ public class FileDiff { public enum LineType { MARKER, BOTH_SIDE, LEFT, RIGHT } public static class DiffLine { private final int leftLineNumber; private final int rightLineNumber; private final LineType type; private final String text; private DiffLine(LineType type, int leftLineNumber, int rightLineNumber, String text) { this.leftLineNumber = leftLineNumber; this.rightLineNumber = rightLineNumber; this.type = type; this.text = text.replace(" ", "\u00A0"); } public int leftLineNumber() { return leftLineNumber; } public int rightLineNumber() { return rightLineNumber; } public LineType type() { return type; } public String text() { return text; } private static DiffLine markerLine(int leftLineNumber, int rightLineNumber ,String text) { return new DiffLine(LineType.MARKER, leftLineNumber, rightLineNumber, text); } private static DiffLine leftSideLine(int lineNumber, String text) { return new DiffLine(LineType.LEFT, lineNumber, 0, text); } private static DiffLine rightSideLine(int lineNumber, String text) { return new DiffLine(LineType.RIGHT, 0, lineNumber, text); } private static DiffLine bothSideLine(int leftLineNumber, int rightLineNumber, String text) { return new DiffLine(LineType.BOTH_SIDE, leftLineNumber, rightLineNumber, text); } } private static final Pattern MARKER_PATTERN = Pattern.compile("^@@\\s+\\-(?:(\\d+)(?:,(\\d+))?)\\s+\\+(?:(\\d+)(?:,(\\d+))?)\\s+@@.*"); private final List<DiffLine> diffLines; public FileDiff(List<DiffLine> diffLines) { this.diffLines = diffLines; } public List<DiffLine> content() { return diffLines; } public static FileDiff from(String fileDiff) { Scanner scanner = new Scanner(fileDiff); int leftLines = -1; int rightLines = -1; boolean chunkInitialised = false; List<DiffLine> diffs = new ArrayList<DiffLine>(); while (scanner.hasNextLine()) { String line = scanner.nextLine(); Matcher matcher = MARKER_PATTERN.matcher(line); if (matcher.matches()) { chunkInitialised = true; leftLines = Integer.parseInt(matcher.group(1)); rightLines = Integer.parseInt(matcher.group(3)); diffs.add(DiffLine.markerLine(leftLines, rightLines, line)); continue; } if (!chunkInitialised) { continue; } if (line.startsWith("-")) { diffs.add(DiffLine.leftSideLine(leftLines, line)); leftLines++; continue; } if (line.startsWith("+")) { diffs.add(DiffLine.rightSideLine(rightLines, line)); rightLines++; continue; } diffs.add(DiffLine.bothSideLine(leftLines, rightLines, line)); leftLines++; rightLines++; } return new FileDiff(diffs); } }