001: /*
002: * ====================================================================
003: * Copyright (c) 2004 TMate Software Ltd. All rights reserved.
004: *
005: * This software is licensed as described in the file COPYING, which
006: * you should have received as part of this distribution. The terms
007: * are also available at http://svnkit.com/license.html
008: * If newer versions of this license are posted there, you may use a
009: * newer version instead, at your option.
010: * ====================================================================
011: */
012:
013: package de.regnis.q.sequence.line.diff;
014:
015: import java.io.*;
016: import java.util.*;
017:
018: import de.regnis.q.sequence.*;
019: import de.regnis.q.sequence.line.*;
020:
021: /**
022: * @author Ian Sullivan
023: * @author TMate Software Ltd.
024: */
025: public final class QDiffUniGenerator extends QDiffSequenceGenerator
026: implements QDiffGeneratorFactory {
027:
028: // Constants ==============================================================
029:
030: public static final String TYPE = "unified";
031:
032: // Static =================================================================
033:
034: public static void setup() {
035: QDiffManager.registerDiffGeneratorFactory(
036: new QDiffUniGenerator(), QDiffUniGenerator.TYPE);
037: }
038:
039: // Fields =================================================================
040:
041: private Map myGeneratorsCache;
042:
043: // Setup ==================================================================
044:
045: public QDiffUniGenerator(Map properties, String header) {
046: super (initProperties(properties), header);
047: }
048:
049: private QDiffUniGenerator() {
050: super (null, null);
051: }
052:
053: // Implemented ============================================================
054:
055: public void generateDiffHeader(String item, String leftInfo,
056: String rightInfo, Writer output) throws IOException {
057: leftInfo = leftInfo == null ? "" : "\t" + leftInfo;
058: rightInfo = rightInfo == null ? "" : "\t" + rightInfo;
059: println("--- " + item + leftInfo, output);
060: println("+++ " + item + rightInfo, output);
061: }
062:
063: protected void processBlock(QSequenceDifferenceBlock[] segment,
064: QSequenceLineCache sourceLines,
065: QSequenceLineCache targetLines, String encoding,
066: Writer output) throws IOException {
067: int gutter = getGutter();
068: // header
069: StringBuffer header = new StringBuffer();
070: header.append("@@");
071: int sourceStartLine = segment[0].getLeftFrom();
072: int sourceEndLine = segment[segment.length - 1].getLeftTo();
073: int targetStartLine = segment[0].getRightFrom();
074: int targetEndLine = segment[segment.length - 1].getRightTo();
075:
076: int leftStart = Math.max(sourceStartLine - gutter, 0);
077: int rightStart = Math.max(targetStartLine - gutter, 0);
078: int leftEnd = Math.min(sourceEndLine + gutter, sourceLines
079: .getLineCount() - 1);
080: int rightEnd = Math.min(targetEndLine + gutter, targetLines
081: .getLineCount() - 1);
082:
083: if (leftStart + 1 >= 0 && (leftEnd - leftStart + 1) >= 0) {
084: header.append(" -");
085:
086: if (leftStart == 0 && leftEnd < 0) {
087: header.append("0,0");
088: } else {
089: header.append(leftStart + 1);
090: if (leftEnd - leftStart + 1 > 1) {
091: header.append(",");
092: header.append(leftEnd - leftStart + 1);
093: }
094: }
095:
096: }
097: if (rightStart + 1 > 0 && rightEnd - rightStart + 1 > 0) {
098: header.append(" +");
099: header.append(rightStart + 1);
100: if (rightEnd - rightStart + 1 > 1) {
101: header.append(",");
102: header.append(rightEnd - rightStart + 1);
103: }
104: } else {
105: header.append(" +0,0");
106: }
107: header.append(" @@");
108: println(header.toString(), output);
109:
110: // print gutter context lines before blocks.
111: for (int i = leftStart; i < sourceStartLine; i++) {
112: print(" " + printLine(sourceLines.getLine(i), encoding),
113: output);
114: }
115: for (int i = 0; i < segment.length; i++) {
116: QSequenceDifferenceBlock block = segment[i];
117: for (int j = block.getLeftFrom(); j <= block.getLeftTo(); j++) {
118: String line = printLine(sourceLines.getLine(j),
119: encoding);
120: print("-" + line, output);
121: if (j == sourceLines.getLineCount() - 1) {
122: printNoNewLine(output, line);
123: }
124: }
125: for (int j = block.getRightFrom(); j <= block.getRightTo(); j++) {
126: String line = printLine(targetLines.getLine(j),
127: encoding);
128: print("+" + line, output);
129: if (j == targetLines.getLineCount() - 1) {
130: printNoNewLine(output, line);
131: }
132: }
133: // print glue lines
134: int end = Math.min(block.getLeftTo() + gutter, sourceLines
135: .getLineCount() - 1);
136: if (i + 1 < segment.length) {
137: end = Math.min(end, segment[i + 1].getLeftFrom() - 1);
138: }
139: for (int j = block.getLeftTo() + 1; j <= end; j++) {
140: String line = printLine(sourceLines.getLine(j),
141: encoding);
142: print(
143: " "
144: + printLine(sourceLines.getLine(j),
145: encoding), output);
146: if (j == sourceLines.getLineCount() - 1) {
147: printNoNewLine(output, line);
148: }
149: }
150: }
151: }
152:
153: public QDiffGenerator createGenerator(Map properties) {
154: if (myGeneratorsCache == null) {
155: myGeneratorsCache = new HashMap();
156: }
157: QDiffGenerator generator = (QDiffGenerator) myGeneratorsCache
158: .get(properties);
159: if (generator != null) {
160: return generator;
161: }
162: generator = new QDiffUniGenerator(properties, null);
163: myGeneratorsCache.put(properties, generator);
164: return generator;
165: }
166:
167: // Utils ==================================================================
168:
169: private void printNoNewLine(Writer output, String line)
170: throws IOException {
171: if (!line.endsWith("\n") && !line.endsWith("\r")) {
172: println(output);
173: println("\\ No newline at end of file", output);
174: }
175: }
176:
177: private static Map initProperties(Map properties) {
178: if (properties == null
179: || !properties
180: .containsKey(QDiffGeneratorFactory.GUTTER_PROPERTY)) {
181: properties = new HashMap(
182: properties == null ? Collections.EMPTY_MAP
183: : properties);
184: properties.put(QDiffGeneratorFactory.GUTTER_PROPERTY, "3");
185: }
186: return properties;
187: }
188: }
|