Skip to content

Commit 4caf63c

Browse files
committed
1 parent c0a1a37 commit 4caf63c

File tree

5 files changed

+262
-19
lines changed

5 files changed

+262
-19
lines changed

pom.xml

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -105,6 +105,12 @@
105105
</exclusion>
106106
</exclusions>
107107
</dependency>
108+
<dependency>
109+
<groupId>org.assertj</groupId>
110+
<artifactId>assertj-core</artifactId>
111+
<version>3.11.1</version>
112+
<scope>test</scope>
113+
</dependency>
108114
</dependencies>
109115

110116
<build>

src/main/java/com/github/difflib/unifieddiff/UnifiedDiff.java

Lines changed: 19 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -15,30 +15,33 @@
1515
*/
1616
package com.github.difflib.unifieddiff;
1717

18-
import java.io.BufferedReader;
19-
import java.io.IOException;
20-
import java.io.InputStream;
21-
import java.io.InputStreamReader;
22-
import java.util.logging.Logger;
18+
import java.util.ArrayList;
19+
import java.util.Collections;
20+
import java.util.List;
2321

2422
/**
2523
*
2624
* @author Tobias Warneke (t.warneke@gmx.net)
2725
*/
28-
public final class UnifiedDiff {
26+
public class UnifiedDiff {
2927

30-
private UnifiedDiff(InputStream stream) throws IOException {
31-
try (BufferedReader reader = new BufferedReader(new InputStreamReader(stream));) {
32-
while (reader.ready()) {
33-
String line = reader.readLine();
34-
LOG.info(line);
35-
}
36-
}
28+
private String header;
29+
private final List<UnifiedDiffFile> files = new ArrayList<>();
3730

31+
public String getHeader() {
32+
return header;
3833
}
39-
private static final Logger LOG = Logger.getLogger(UnifiedDiff.class.getName());
4034

41-
public static UnifiedDiff parse(InputStream stream) throws IOException {
42-
return new UnifiedDiff(stream);
35+
public void setHeader(String header) {
36+
this.header = header;
4337
}
38+
39+
void addFile(UnifiedDiffFile file) {
40+
files.add(file);
41+
}
42+
43+
public List<UnifiedDiffFile> getFiles() {
44+
return Collections.unmodifiableList(files);
45+
}
46+
4447
}
Lines changed: 60 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,60 @@
1+
/*
2+
* Copyright 2019 java-diff-utils.
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* http://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*/
16+
package com.github.difflib.unifieddiff;
17+
18+
/**
19+
*
20+
* @author Tobias Warneke (t.warneke@gmx.net)
21+
*/
22+
public class UnifiedDiffFile {
23+
24+
private String diffCommand;
25+
private String fromFile;
26+
private String toFile;
27+
private String index;
28+
29+
public String getDiffCommand() {
30+
return diffCommand;
31+
}
32+
33+
public void setDiffCommand(String diffCommand) {
34+
this.diffCommand = diffCommand;
35+
}
36+
37+
public String getFromFile() {
38+
return fromFile;
39+
}
40+
41+
public void setFromFile(String fromFile) {
42+
this.fromFile = fromFile;
43+
}
44+
45+
public String getToFile() {
46+
return toFile;
47+
}
48+
49+
public void setToFile(String toFile) {
50+
this.toFile = toFile;
51+
}
52+
53+
public void setIndex(String index) {
54+
this.index = index;
55+
}
56+
57+
public String getIndex() {
58+
return index;
59+
}
60+
}
Lines changed: 167 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,167 @@
1+
/*
2+
* Copyright 2019 java-diff-utils.
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* http://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*/
16+
package com.github.difflib.unifieddiff;
17+
18+
import java.io.BufferedReader;
19+
import java.io.IOException;
20+
import java.io.InputStream;
21+
import java.io.InputStreamReader;
22+
import java.io.Reader;
23+
import java.util.function.BiConsumer;
24+
import java.util.logging.Level;
25+
import java.util.logging.Logger;
26+
import java.util.regex.MatchResult;
27+
import java.util.regex.Matcher;
28+
import java.util.regex.Pattern;
29+
30+
/**
31+
*
32+
* @author Tobias Warneke (t.warneke@gmx.net)
33+
*/
34+
public final class UnifiedDiffParser {
35+
36+
private final UnifiedDiffReader READER;
37+
private final UnifiedDiff data = new UnifiedDiff();
38+
private final UnifiedDiffLine[] PARSER_RULES = new UnifiedDiffLine[]{
39+
new UnifiedDiffLine("^\\s+", (m, l) -> LOG.info("normal " + l)),
40+
new UnifiedDiffLine(true, "^diff\\s", UnifiedDiffParser::processDiff),
41+
new UnifiedDiffLine(true, "^index\\s[\\da-zA-Z]+\\.\\.[\\da-zA-Z]+(\\s(\\d+))?$", UnifiedDiffParser::processIndex)
42+
};
43+
private UnifiedDiffFile actualFile;
44+
45+
UnifiedDiffParser(Reader reader) {
46+
this.READER = new UnifiedDiffReader(reader);
47+
}
48+
49+
// schema = [[/^\s+/, normal], [/^diff\s/, start], [/^new file mode \d+$/, new_file],
50+
// [/^deleted file mode \d+$/, deleted_file], [/^index\s[\da-zA-Z]+\.\.[\da-zA-Z]+(\s(\d+))?$/, index],
51+
// [/^---\s/, from_file], [/^\+\+\+\s/, to_file], [/^@@\s+\-(\d+),?(\d+)?\s+\+(\d+),?(\d+)?\s@@/, chunk],
52+
// [/^-/, del], [/^\+/, add], [/^\\ No newline at end of file$/, eof]];
53+
private UnifiedDiff parse() throws IOException {
54+
boolean header = true;
55+
String headerTxt = "";
56+
while (READER.ready()) {
57+
String line = READER.readLine();
58+
if (processLine(header, line) == false) {
59+
if (header) {
60+
headerTxt += line + "\n";
61+
} else {
62+
break;
63+
}
64+
} else {
65+
header = false;
66+
data.setHeader(headerTxt);
67+
}
68+
}
69+
return data;
70+
}
71+
72+
static String[] parseFileNames(String line) {
73+
String[] split = line.split(" ");
74+
return new String[]{
75+
split[2].replaceAll("^a/", ""),
76+
split[3].replaceAll("^b/", "")
77+
};
78+
}
79+
80+
private static final Logger LOG = Logger.getLogger(UnifiedDiffParser.class.getName());
81+
82+
public static UnifiedDiff parseUnifiedDiff(InputStream stream) throws IOException {
83+
UnifiedDiffParser parser = new UnifiedDiffParser(new BufferedReader(new InputStreamReader(stream)));
84+
return parser.parse();
85+
}
86+
87+
private boolean processLine(boolean header, String line) {
88+
for (UnifiedDiffLine rule : PARSER_RULES) {
89+
if (header && rule.isStopsHeaderParsing() || !header) {
90+
if (rule.processLine(line)) {
91+
return true;
92+
}
93+
}
94+
}
95+
return false;
96+
}
97+
98+
private void initFileIfNecessary() {
99+
if (actualFile == null) {
100+
actualFile = new UnifiedDiffFile();
101+
}
102+
}
103+
104+
private void processDiff(MatchResult match, String line) {
105+
initFileIfNecessary();
106+
LOG.log(Level.INFO, "start {0}", line);
107+
String[] fromTo = parseFileNames(READER.lastLine());
108+
actualFile.setFromFile(fromTo[0]);
109+
actualFile.setToFile(fromTo[1]);
110+
}
111+
112+
private void processIndex(MatchResult match, String line) {
113+
initFileIfNecessary();
114+
LOG.log(Level.INFO, "index {0}", line);
115+
actualFile.setIndex(line.substring(6));
116+
}
117+
118+
class UnifiedDiffLine {
119+
120+
private final Pattern pattern;
121+
private final BiConsumer<MatchResult, String> command;
122+
private final boolean stopsHeaderParsing;
123+
124+
public UnifiedDiffLine(String pattern, BiConsumer<MatchResult, String> command) {
125+
this(false, pattern, command);
126+
}
127+
128+
public UnifiedDiffLine(boolean stopsHeaderParsing, String pattern, BiConsumer<MatchResult, String> command) {
129+
this.pattern = Pattern.compile(pattern);
130+
this.command = command;
131+
this.stopsHeaderParsing = stopsHeaderParsing;
132+
}
133+
134+
public boolean processLine(String line) {
135+
Matcher m = pattern.matcher(line);
136+
if (m.find()) {
137+
command.accept(m.toMatchResult(), line);
138+
return true;
139+
} else {
140+
return false;
141+
}
142+
}
143+
144+
public boolean isStopsHeaderParsing() {
145+
return stopsHeaderParsing;
146+
}
147+
}
148+
}
149+
150+
class UnifiedDiffReader extends BufferedReader {
151+
152+
private String lastLine;
153+
154+
public UnifiedDiffReader(Reader reader) {
155+
super(reader);
156+
}
157+
158+
@Override
159+
public String readLine() throws IOException {
160+
lastLine = super.readLine();
161+
return lastLine();
162+
}
163+
164+
String lastLine() {
165+
return lastLine;
166+
}
167+
}

src/test/java/com/github/difflib/unifieddiff/UnifiedDiffTest.java renamed to src/test/java/com/github/difflib/unifieddiff/UnifiedDiffParserTest.java

Lines changed: 10 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@
1616
package com.github.difflib.unifieddiff;
1717

1818
import java.io.IOException;
19+
import static org.assertj.core.api.Java6Assertions.assertThat;
1920
import org.junit.After;
2021
import org.junit.AfterClass;
2122
import org.junit.Before;
@@ -26,9 +27,9 @@
2627
*
2728
* @author Tobias Warneke (t.warneke@gmx.net)
2829
*/
29-
public class UnifiedDiffTest {
30+
public class UnifiedDiffParserTest {
3031

31-
public UnifiedDiffTest() {
32+
public UnifiedDiffParserTest() {
3233
}
3334

3435
@BeforeClass
@@ -49,9 +50,15 @@ public void tearDown() {
4950

5051
@Test
5152
public void testSimpleParse() throws IOException {
52-
UnifiedDiff diff = UnifiedDiff.parse(UnifiedDiffTest.class.getResourceAsStream("jsqlparser_patch_1.diff"));
53+
UnifiedDiff diff = UnifiedDiffParser.parseUnifiedDiff(UnifiedDiffParserTest.class.getResourceAsStream("jsqlparser_patch_1.diff"));
5354

5455
System.out.println(diff);
5556
}
5657

58+
@Test
59+
public void testParseDiffBlock() {
60+
String[] files = UnifiedDiffParser.parseFileNames("diff --git a/src/test/java/net/sf/jsqlparser/statement/select/SelectTest.java b/src/test/java/net/sf/jsqlparser/statement/select/SelectTest.java");
61+
assertThat(files).containsExactly("src/test/java/net/sf/jsqlparser/statement/select/SelectTest.java", "src/test/java/net/sf/jsqlparser/statement/select/SelectTest.java");
62+
}
63+
5764
}

0 commit comments

Comments
 (0)