001: /*****************************************************************************
002: * Sun Public License Notice
003: *
004: * The contents of this file are subject to the Sun Public License Version
005: * 1.0 (the "License"). You may not use this file except in compliance with
006: * the License. A copy of the License is available at http://www.sun.com/
007: *
008: * The Original Code is the CVS Client Library.
009: * The Initial Developer of the Original Code is Robert Greig.
010: * Portions created by Robert Greig are Copyright (C) 2000.
011: * All Rights Reserved.
012: *****************************************************************************/
013:
014: /**
015: * This class is based on the original source code from the netbeans javacvs
016: * module (http://www.netbeans.org)
017: */package gruntspud;
018:
019: import gruntspud.connection.ConnectionProfile;
020:
021: import java.io.BufferedInputStream;
022: import java.io.BufferedOutputStream;
023: import java.io.File;
024: import java.io.FileInputStream;
025: import java.io.FileOutputStream;
026: import java.io.IOException;
027: import java.io.InputStream;
028: import java.io.OutputStream;
029: import java.io.PushbackInputStream;
030:
031: import org.netbeans.lib.cvsclient.file.WriteTextFilePreprocessor;
032: import org.netbeans.lib.cvsclient.util.BugLog;
033: import org.netbeans.lib.cvsclient.util.ByteArray;
034:
035: public class GruntspudRcsDiffFilePreprocessor implements
036: WriteTextFilePreprocessor {
037: // Private instance variables
038: private ConnectionProfile profile;
039:
040: private static class ReadInfo {
041:
042: public int getLineNumber() {
043: return lineNumber;
044: }
045:
046: public void setLineNumber(int lineNumber) {
047: this .lineNumber = lineNumber;
048: }
049:
050: public byte[] readLine() throws IOException {
051: line.reset();
052: boolean end = false;
053: do {
054: int b = in.read();
055: if (b == -1) {
056: end = true;
057: break;
058: }
059: if (b == 10) {
060: lineNumber++;
061: break;
062: }
063: if (b == 13) {
064: int next = in.read();
065: if (next != 10)
066: in.unread(next);
067: lineNumber++;
068: break;
069: }
070: line.add((byte) b);
071: } while (true);
072: byte bytes[] = line.getBytes();
073: if (end && bytes.length == 0)
074: bytes = (byte[]) null;
075: return bytes;
076: }
077:
078: public void close() throws IOException {
079: if (in != null)
080: in.close();
081: }
082:
083: private PushbackInputStream in;
084: private int readLength;
085: private int startIndex;
086: private int lineNumber;
087: private ByteArray line;
088:
089: public ReadInfo(InputStream in) {
090: this .in = new PushbackInputStream(in, 1);
091: readLength = -1;
092: startIndex = 0;
093: lineNumber = 0;
094: line = new ByteArray();
095: }
096: }
097:
098: public GruntspudRcsDiffFilePreprocessor(ConnectionProfile profile) {
099: this .profile = profile;
100: }
101:
102: public String getSeparatorSequence() {
103: switch (profile.getLineEndings()) {
104: case ConnectionProfile.UNIX_LINE_ENDINGS:
105: return "\n";
106: case ConnectionProfile.WINDOWS_LINE_ENDINGS:
107: return "\r\n";
108: case ConnectionProfile.IGNORE_LINE_ENDINGS:
109: return System.getProperty("line.separator");
110: default:
111: return System.getProperty("line.separator");
112: }
113: }
114:
115: public void copyTextFileToLocation(InputStream processedInput,
116: File fileToWrite) throws IOException {
117: Constants.CVS_LOG.debug("Preprocessing RCS diff "
118: + fileToWrite.getAbsolutePath());
119: ReadInfo tempFileReader = null;
120: OutputStream out = null;
121: ReadInfo tempDiffReader = null;
122: File tempFile = null;
123: try {
124: tempDiffReader = new ReadInfo(new BufferedInputStream(
125: processedInput));
126: tempFileReader = new ReadInfo(new BufferedInputStream(
127: new FileInputStream(fileToWrite)));
128: File cvsSubdir = new File(fileToWrite.getParent(), "CVS");
129: tempFile = File.createTempFile(".#merg", "cvs", cvsSubdir);
130: Constants.CVS_LOG.debug("Writing to temporary file "
131: + tempFile.getAbsolutePath());
132: out = new BufferedOutputStream(new FileOutputStream(
133: tempFile));
134: int fileStart = 0;
135: int diffCount = 0;
136: for (byte diff[] = tempDiffReader.readLine(); diff != null
137: && diff.length > 0; diff = tempDiffReader
138: .readLine())
139: if (diff[0] == 100) {
140: int startLine = getStart(diff);
141: int count = getLength(diff);
142: if (startLine >= 0 && count > 0) {
143: readToLine(startLine - 1, tempFileReader, out);
144: readToLine((startLine - 1) + count,
145: tempFileReader, null);
146: } else {
147: BugLog.getInstance().bug(
148: "wrong parsing.." + new String(diff));
149: throw new IOException();
150: }
151: } else if (diff[0] == 97) {
152: int startLine = getStart(diff);
153: int count = getLength(diff);
154: if (startLine >= 0 && count > 0) {
155: readToLine(startLine, tempFileReader, out);
156: tempDiffReader.setLineNumber(0);
157: readToLine(count, tempDiffReader, out);
158: } else {
159: BugLog.getInstance().bug(
160: "wrong parsing.." + new String(diff));
161: throw new IOException();
162: }
163: }
164:
165: readToLine(-2, tempFileReader, out);
166: if (tempFile != null) {
167: tempFileReader.close();
168: out.close();
169: Constants.CVS_LOG.debug("Deleting "
170: + fileToWrite.getAbsolutePath());
171: if (fileToWrite.delete()) {
172: Constants.CVS_LOG.debug("Renaming "
173: + tempFile.getAbsolutePath() + " to "
174: + fileToWrite.getAbsolutePath());
175: boolean ok = tempFile.renameTo(fileToWrite);
176: if (!ok)
177: throw new IOException();
178: } else {
179: throw new IOException();
180: }
181: }
182: } catch (Exception exc) {
183: BugLog.getInstance().showException(exc);
184: } finally {
185: if (tempDiffReader != null)
186: try {
187: tempDiffReader.close();
188: } catch (IOException ioexception) {
189: }
190: if (tempFileReader != null)
191: try {
192: tempFileReader.close();
193: } catch (IOException ioexception1) {
194: }
195: if (out != null)
196: try {
197: out.close();
198: } catch (IOException ex) {
199: }
200: }
201: }
202:
203: private void readToLine(int finalLine, ReadInfo reader,
204: OutputStream out) throws IOException {
205: while (reader.getLineNumber() < finalLine || finalLine == -2) {
206: byte line[] = reader.readLine();
207: if (line == null)
208: return;
209: if (out != null) {
210: out.write(line);
211: out.write(getSeparatorSequence().getBytes());
212: }
213: }
214: }
215:
216: private static int indexOf(byte bytes[], byte b) {
217: return indexOf(bytes, b, 0);
218: }
219:
220: private static int indexOf(byte bytes[], byte b, int start) {
221: int index = -1;
222: for (int i = start; i < bytes.length; i++) {
223: if (bytes[i] != b)
224: continue;
225: index = i;
226: break;
227: }
228:
229: return index;
230: }
231:
232: private static int getStart(byte diffLine[]) {
233: int spacePos = indexOf(diffLine, (byte) 32);
234: if (spacePos > 0) {
235: String number = new String(diffLine, 1, spacePos - 1);
236: try {
237: int toReturn = Integer.parseInt(number);
238: return toReturn;
239: } catch (NumberFormatException exc) {
240: return -1;
241: }
242: } else {
243: return -1;
244: }
245: }
246:
247: private static int getLength(byte diffLine[]) {
248: int spacePos = indexOf(diffLine, (byte) 32);
249: if (spacePos > 0) {
250: int end = indexOf(diffLine, (byte) 32, spacePos + 1);
251: if (end < 0)
252: end = diffLine.length;
253: String number = new String(diffLine, spacePos + 1, end
254: - spacePos - 1);
255: try {
256: int toReturn = Integer.parseInt(number);
257: return toReturn;
258: } catch (NumberFormatException exc) {
259: return -1;
260: }
261: } else {
262: return -1;
263: }
264: }
265:
266: private static final int CHUNK_SIZE = 32768;
267: private static final int READ_REMAINING = -2;
268: private String lineEnding;
269: }
|