blob: b8e2b2b9d2b65d66ba3870e77238f32dc996a7c7 [file] [log] [blame]
/*
* Copyright 2000-2012 JetBrains s.r.o.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.intellij.cvsSupport2.actions.merge;
import com.intellij.util.containers.Stack;
import java.io.*;
/**
* @author lesya
*/
public class CvsConflictsParser {
private static final String LEFT = "<<<<<<< ";
private static final String RIGHT = "=======";
private static final String END = ">>>>>>> ";
private static final int LENGTH = RIGHT.length();
private enum State {
RIGHT, LEFT
}
private final StringBuilder myLeftBuffer = new StringBuilder();
private final StringBuilder myCenterBuffer = new StringBuilder();
private final StringBuilder myRightBuffer = new StringBuilder();
private final Stack<State> myStateStack = new Stack<State>();
public String getLeftVersion() {
return myLeftBuffer.toString();
}
public String getCenterVersion() {
return myCenterBuffer.toString();
}
public String getRightVersion() {
return myRightBuffer.toString();
}
private CvsConflictsParser() {}
public static CvsConflictsParser createOn(InputStream merged) throws IOException {
final CvsConflictsParser result = new CvsConflictsParser();
result.parseFile(merged);
return result;
}
private void parseFile(final InputStream merged) throws IOException {
final BufferedReader br = new BufferedReader(new InputStreamReader(merged));
try {
for (String line; (line = br.readLine()) != null; ) {
if (!processLeftMarker(line) && !processRightMarker(line) && !processEndMarker(line)) {
appendToMainOrCurrent(line);
}
}
}
finally {
br.close();
}
}
private boolean processLeftMarker(String line) {
final int idx = line.lastIndexOf(LEFT);
if (idx < 0) {
return false;
}
if (myStateStack.isEmpty()) {
final String fragment = line.substring(0, idx);
if (!fragment.isEmpty()) {
appendToMainOrCurrent(fragment);
}
}
else {
appendToMainOrCurrent(line);
}
myStateStack.push(State.LEFT);
return true;
}
private boolean processRightMarker(String line) {
if (!line.endsWith(RIGHT)) {
return false;
}
if (!myStateStack.isEmpty() && myStateStack.peek() == State.LEFT) {
if (myStateStack.size() > 1) {
appendToMainOrCurrent(line);
}
else {
final String fragment = line.substring(0, line.length() - LENGTH);
if (!fragment.isEmpty()) {
appendToMainOrCurrent(fragment);
}
}
myStateStack.pop();
myStateStack.push(State.RIGHT);
}
else {
appendToMainOrCurrent(line);
}
return true;
}
private boolean processEndMarker(String line) {
final int idx = line.lastIndexOf(END);
if (idx < 0) {
return false;
}
if (!myStateStack.isEmpty()) {
if (myStateStack.size() > 1) {
appendToMainOrCurrent(line);
}
else {
final String fragment = line.substring(0, idx);
if (!fragment.isEmpty()) {
appendToMainOrCurrent(fragment);
}
}
myStateStack.pop();
}
else {
appendToMainOrCurrent(line);
}
return true;
}
private void appendToMainOrCurrent(String line) {
if (myStateStack.isEmpty()) {
append(line, myLeftBuffer);
append(line, myCenterBuffer);
append(line, myRightBuffer);
} else {
if (myStateStack.get(0) == State.RIGHT) {
append(line, myRightBuffer);
} else {
append(line, myLeftBuffer);
}
}
}
private static void append(String line, StringBuilder out) {
if (out.length() > 0) {
out.append("\n");
}
out.append(line);
}
}