KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > eclipse > team > internal > ui > mapping > LineComparator


1 /*******************************************************************************
2  * Copyright (c) 2004, 2006 IBM Corporation and others.
3  * All rights reserved. This program and the accompanying materials
4  * are made available under the terms of the Eclipse Public License v1.0
5  * which accompanies this distribution, and is available at
6  * http://www.eclipse.org/legal/epl-v10.html
7  *
8  * Contributors:
9  * IBM Corporation - initial API and implementation
10  *******************************************************************************/

11 package org.eclipse.team.internal.ui.mapping;
12
13 import java.io.*;
14 import java.util.ArrayList JavaDoc;
15 import org.eclipse.compare.rangedifferencer.IRangeComparator;
16 import org.eclipse.core.resources.IEncodedStorage;
17 import org.eclipse.core.resources.IStorage;
18 import org.eclipse.core.runtime.CoreException;
19
20 /**
21  * This implementation of IRangeComparator breaks an input stream into lines.
22  * Copied from org.eclipse.compare.internal.merge.LineComparator 1.4 and
23  * modified for {@link IStorage}.
24  */

25 class LineComparator implements IRangeComparator {
26
27     private String JavaDoc[] fLines;
28
29     /*
30      * An input stream reader that detects a trailing LF in the wrapped stream.
31      */

32     private static class TrailingLineFeedDetector extends FilterInputStream {
33
34         boolean trailingLF = false;
35         
36         protected TrailingLineFeedDetector(InputStream in) {
37             super(in);
38         }
39         
40         public int read() throws IOException {
41             int c = super.read();
42             trailingLF = isLineFeed(c);
43             return c;
44         }
45         
46         /*
47          * We don't need to override read(byte[] buffer) as the javadoc of
48          * FilterInputStream states that it will call read(byte[] buffer, int off, int len)
49          */

50         public int read(byte[] buffer, int off, int len) throws IOException {
51             int length = super.read(buffer, off, len);
52             if (length != -1) {
53                 int index = off + length - 1;
54                 if (index >= buffer.length)
55                     index = buffer.length - 1;
56                 trailingLF = isLineFeed(buffer[index]);
57             }
58             return length;
59         }
60
61         private boolean isLineFeed(int c) {
62             return c != -1 && c == '\n';
63         }
64         
65         public boolean hadTrailingLineFeed() {
66             return trailingLF;
67         }
68         
69     }
70     
71     public static LineComparator create(IStorage storage, String JavaDoc outputEncoding) throws CoreException, UnsupportedEncodingException {
72         InputStream is = new BufferedInputStream(storage.getContents());
73         try {
74             String JavaDoc encoding = getEncoding(storage, outputEncoding);
75             return new LineComparator(is, encoding);
76         } finally {
77             try {
78                 is.close();
79             } catch (IOException e) {
80                 // Ignore
81
}
82         }
83     }
84     
85     private static String JavaDoc getEncoding(IStorage storage, String JavaDoc outputEncoding) throws CoreException {
86         if (storage instanceof IEncodedStorage) {
87             IEncodedStorage es = (IEncodedStorage) storage;
88             String JavaDoc charset = es.getCharset();
89             if (charset != null)
90                 return charset;
91         }
92         return outputEncoding;
93     }
94     
95     public LineComparator(InputStream is, String JavaDoc encoding) throws UnsupportedEncodingException {
96         
97         TrailingLineFeedDetector trailingLineFeedDetector = new TrailingLineFeedDetector(is);
98         BufferedReader br = new BufferedReader(new InputStreamReader(trailingLineFeedDetector, encoding));
99         String JavaDoc line;
100         ArrayList JavaDoc ar = new ArrayList JavaDoc();
101         try {
102             while ((line = br.readLine()) != null)
103                 ar.add(line);
104         } catch (IOException e) {
105                 // silently ignored
106
}
107         try {
108             is.close();
109         } catch (IOException e1) {
110         }
111         // Add a trailing line if the last character in the file was a line feed.
112
// We do this because a BufferedReader doesn't distinguish the case
113
// where the last line has or doesn't have a trailing line separator
114
if (trailingLineFeedDetector.hadTrailingLineFeed()) {
115             ar.add(""); //$NON-NLS-1$
116
}
117         fLines = (String JavaDoc[]) ar.toArray(new String JavaDoc[ar.size()]);
118     }
119
120     String JavaDoc getLine(int ix) {
121         return fLines[ix];
122     }
123
124     /* (non-Javadoc)
125      * @see org.eclipse.compare.rangedifferencer.IRangeComparator#getRangeCount()
126      */

127     public int getRangeCount() {
128         return fLines.length;
129     }
130
131     /* (non-Javadoc)
132      * @see org.eclipse.compare.rangedifferencer.IRangeComparator#rangesEqual(int, org.eclipse.compare.rangedifferencer.IRangeComparator, int)
133      */

134     public boolean rangesEqual(int thisIndex, IRangeComparator other,
135             int otherIndex) {
136         String JavaDoc s1 = fLines[thisIndex];
137         String JavaDoc s2 = ((LineComparator) other).fLines[otherIndex];
138         return s1.equals(s2);
139     }
140
141     /* (non-Javadoc)
142      * @see org.eclipse.compare.rangedifferencer.IRangeComparator#skipRangeComparison(int, int, org.eclipse.compare.rangedifferencer.IRangeComparator)
143      */

144     public boolean skipRangeComparison(int length, int maxLength, IRangeComparator other) {
145         return false;
146     }
147 }
148
Popular Tags