View | Details | Raw Unified | Return to bug 183226 | Differences between
and this patch

Collapse All | Expand All

(-)src/org/eclipse/compare/tests/PatchTest.java (-135 / +20 lines)
Lines 10-22 Link Here
10
 *******************************************************************************/
10
 *******************************************************************************/
11
package org.eclipse.compare.tests;
11
package org.eclipse.compare.tests;
12
12
13
import java.io.BufferedInputStream;
14
import java.io.BufferedReader;
13
import java.io.BufferedReader;
15
import java.io.ByteArrayInputStream;
14
import java.io.ByteArrayInputStream;
16
import java.io.File;
15
import java.io.File;
17
import java.io.FileFilter;
16
import java.io.FileFilter;
18
import java.io.FileInputStream;
17
import java.io.FileInputStream;
19
import java.io.FileNotFoundException;
20
import java.io.IOException;
18
import java.io.IOException;
21
import java.io.InputStream;
19
import java.io.InputStream;
22
import java.io.InputStreamReader;
20
import java.io.InputStreamReader;
Lines 38-44 Link Here
38
import junit.framework.AssertionFailedError;
36
import junit.framework.AssertionFailedError;
39
import junit.framework.TestCase;
37
import junit.framework.TestCase;
40
38
41
import org.eclipse.compare.internal.Utilities;
42
import org.eclipse.compare.internal.core.patch.FileDiff;
39
import org.eclipse.compare.internal.core.patch.FileDiff;
43
import org.eclipse.compare.internal.core.patch.FileDiffResult;
40
import org.eclipse.compare.internal.core.patch.FileDiffResult;
44
import org.eclipse.compare.internal.core.patch.LineReader;
41
import org.eclipse.compare.internal.core.patch.LineReader;
Lines 49-56 Link Here
49
import org.eclipse.compare.patch.IHunk;
46
import org.eclipse.compare.patch.IHunk;
50
import org.eclipse.compare.patch.IHunkFilter;
47
import org.eclipse.compare.patch.IHunkFilter;
51
import org.eclipse.compare.patch.PatchConfiguration;
48
import org.eclipse.compare.patch.PatchConfiguration;
49
import org.eclipse.compare.tests.PatchUtils.JarEntryStorage;
50
import org.eclipse.compare.tests.PatchUtils.PatchTestConfiguration;
51
import org.eclipse.compare.tests.PatchUtils.StringStorage;
52
import org.eclipse.core.resources.IStorage;
52
import org.eclipse.core.resources.IStorage;
53
import org.eclipse.core.resources.ResourcesPlugin;
54
import org.eclipse.core.runtime.CoreException;
53
import org.eclipse.core.runtime.CoreException;
55
import org.eclipse.core.runtime.FileLocator;
54
import org.eclipse.core.runtime.FileLocator;
56
import org.eclipse.core.runtime.IPath;
55
import org.eclipse.core.runtime.IPath;
Lines 59-161 Link Here
59
import org.eclipse.core.runtime.Path;
58
import org.eclipse.core.runtime.Path;
60
import org.eclipse.core.runtime.Platform;
59
import org.eclipse.core.runtime.Platform;
61
import org.eclipse.core.runtime.Status;
60
import org.eclipse.core.runtime.Status;
62
import org.osgi.framework.Bundle;
63
61
64
public class PatchTest extends TestCase {
62
public class PatchTest extends TestCase {
65
63
66
	private static final String PATCHDATA = "patchdata";
67
	private static final String PATCH_CONFIGURATION = "patchConfiguration.properties";
64
	private static final String PATCH_CONFIGURATION = "patchConfiguration.properties";
68
	
65
	
69
	Properties defaultPatchProperties;
66
	Properties defaultPatchProperties;
70
	
67
	
71
	class StringStorage implements IStorage {
72
		String fileName;
73
		public StringStorage(String old) {
74
			fileName = old;
75
		}
76
		public Object getAdapter(Class adapter) {
77
			return null;
78
		}
79
		public boolean isReadOnly() {
80
			return false;
81
		}
82
		public String getName() {
83
			return fileName;
84
		}
85
		public IPath getFullPath() {
86
			return null;
87
		}
88
		public InputStream getContents() throws CoreException {
89
			return new BufferedInputStream(asInputStream(fileName));
90
		}
91
	}
92
	
93
	class FileStorage implements IStorage {
94
		File file;
95
		public FileStorage(File file) {
96
			this.file = file;
97
		}
98
		public InputStream getContents() throws CoreException {
99
			try {
100
				return new FileInputStream(file);
101
			} catch (FileNotFoundException e) {
102
				// ignore, should never happen
103
			}
104
			return null;
105
		}
106
		public IPath getFullPath() {
107
			return new Path(file.getAbsolutePath());
108
		}
109
		public String getName() {
110
			return file.getName();
111
		}
112
		public boolean isReadOnly() {
113
			return true;
114
		}
115
		public Object getAdapter(Class adapter) {
116
			return null;
117
		}
118
	}
119
	
120
	class JarEntryStorage implements IStorage {
121
		JarEntry jarEntry;
122
		JarFile jarFile;
123
		public JarEntryStorage(JarEntry jarEntry, JarFile jarFile) {
124
			this.jarEntry = jarEntry;
125
			this.jarFile = jarFile;
126
		}
127
		public InputStream getContents() throws CoreException {
128
			try {
129
				return jarFile.getInputStream(jarEntry);
130
			} catch (IOException e) {
131
				// ignore, should never happen
132
			}
133
			return null;
134
		}
135
		public IPath getFullPath() {
136
			return new Path(jarFile.getName());
137
		}
138
		public String getName() {
139
			return jarEntry.getName();
140
		}
141
		public boolean isReadOnly() {
142
			return true;
143
		}
144
		public Object getAdapter(Class adapter) {
145
			return null;
146
		}
147
	}
148
	
149
	class PatchTestConfiguration {
150
		String subfolderName;
151
		PatchConfiguration pc;
152
		String patchFileName;
153
		String[] originalFileNames;
154
		String[] expectedFileNames;
155
		String[] actualFileNames;
156
		// TODO: getters, setters
157
	}
158
	
159
	public PatchTest(String name) {
68
	public PatchTest(String name) {
160
		super(name);
69
		super(name);
161
		defaultPatchProperties = new Properties();
70
		defaultPatchProperties = new Properties();
Lines 217-227 Link Here
217
126
218
		InputStream actual = result.getPatchedContents();
127
		InputStream actual = result.getPatchedContents();
219
128
220
		LineReader lr = new LineReader(getReader("exp_hunkFilter.txt"));
129
		LineReader lr = new LineReader(PatchUtils.getReader("exp_hunkFilter.txt"));
221
		List inLines = lr.readLines();
130
		List inLines = lr.readLines();
222
		String expected = LineReader.createString(false, inLines);
131
		String expected = LineReader.createString(false, inLines);
223
132
224
		assertEquals(expected, asString(actual));
133
		assertEquals(expected, PatchUtils.asString(actual));
225
	}
134
	}
226
135
227
	public void testContext3PatchWithHeader() throws CoreException, IOException {
136
	public void testContext3PatchWithHeader() throws CoreException, IOException {
Lines 298-304 Link Here
298
	private List failures = new ArrayList();
207
	private List failures = new ArrayList();
299
	
208
	
300
	public void testPatchdataSubfolders() throws IOException, CoreException {
209
	public void testPatchdataSubfolders() throws IOException, CoreException {
301
		URL patchdataUrl = new URL(getBundle().getEntry("/"), new Path(PATCHDATA).toString());
210
		URL patchdataUrl = new URL(PatchUtils.getBundle().getEntry("/"),
211
				new Path(PatchUtils.PATCHDATA).toString());
302
		patchdataUrl = FileLocator.resolve(patchdataUrl);
212
		patchdataUrl = FileLocator.resolve(patchdataUrl);
303
		
213
		
304
		Map map = null;
214
		Map map = null;
Lines 321-327 Link Here
321
			PatchConfiguration pc = ptc.pc;
231
			PatchConfiguration pc = ptc.pc;
322
			
232
			
323
			// create a message to distinguish tests from different subfolders
233
			// create a message to distinguish tests from different subfolders
324
			String msg = "Test for subfolder [" + PATCHDATA + "/" + sf + "] failed.";
234
			String msg = "Test for subfolder [" + PatchUtils.PATCHDATA + "/"
235
					+ sf + "] failed.";
325
			
236
			
326
			try {
237
			try {
327
				// test with expected result
238
				// test with expected result
Lines 339-346 Link Here
339
					continue; // continue with a next subfolder
250
					continue; // continue with a next subfolder
340
				}
251
				}
341
				failures.add(new AssertionFailedError(
252
				failures.add(new AssertionFailedError(
342
						"\npatchWorkspace should fail for folder [" + PATCHDATA
253
						"\npatchWorkspace should fail for folder ["
343
								+ "/" + sf + "]."));
254
								+ PatchUtils.PATCHDATA + "/" + sf + "]."));
344
			}
255
			}
345
		}
256
		}
346
		
257
		
Lines 391-397 Link Here
391
		while (entries.hasMoreElements()) {
302
		while (entries.hasMoreElements()) {
392
			JarEntry entry = (JarEntry) entries.nextElement();
303
			JarEntry entry = (JarEntry) entries.nextElement();
393
			String entryName = entry.getName();
304
			String entryName = entry.getName();
394
			if (entryName.endsWith("/" + PATCHDATA + "/")) {
305
			if (entryName.endsWith("/" + PatchUtils.PATCHDATA + "/")) {
395
				patchdataName = entryName;
306
				patchdataName = entryName;
396
				break;
307
				break;
397
			}
308
			}
Lines 512-543 Link Here
512
		result.put(subfolderName, tpc);
423
		result.put(subfolderName, tpc);
513
	}
424
	}
514
425
515
516
	// Test changing
517
	private BufferedReader getReader(String name) {
518
		InputStream resourceAsStream = asInputStream(name);
519
		InputStreamReader reader2= new InputStreamReader(resourceAsStream);
520
		return new BufferedReader(reader2);
521
	}
522
523
	private InputStream asInputStream(String name) {
524
		IPath path= new Path(PATCHDATA).append(name);
525
		try {
526
			URL url= new URL(getBundle().getEntry("/"), path.toString());
527
			return url.openStream();
528
		} catch (IOException e) {
529
			fail("Failed while reading " + name);
530
			return null; // never reached
531
		}
532
	}
533
534
	private void patch(final String old, String patch, String expt) throws CoreException, IOException {
426
	private void patch(final String old, String patch, String expt) throws CoreException, IOException {
535
		patcherPatch(old, patch, expt);
427
		patcherPatch(old, patch, expt);
536
		filePatch(old, patch, expt);
428
		filePatch(old, patch, expt);
537
	}
429
	}
538
430
539
	private void filePatch(final String old, String patch, String expt) throws CoreException, IOException {
431
	private void filePatch(final String old, String patch, String expt) throws CoreException, IOException {
540
		LineReader lr= new LineReader(getReader(expt));
432
		LineReader lr= new LineReader(PatchUtils.getReader(expt));
541
		List inLines= lr.readLines();
433
		List inLines= lr.readLines();
542
		String expected = LineReader.createString(false, inLines);
434
		String expected = LineReader.createString(false, inLines);
543
		
435
		
Lines 549-569 Link Here
549
		assertTrue(result.hasMatches());
441
		assertTrue(result.hasMatches());
550
		assertFalse(result.hasRejects());
442
		assertFalse(result.hasRejects());
551
		InputStream actualStream = result.getPatchedContents();
443
		InputStream actualStream = result.getPatchedContents();
552
		String actual = asString(actualStream);
444
		String actual = PatchUtils.asString(actualStream);
553
		assertEquals(expected, actual);
445
		assertEquals(expected, actual);
554
	}
446
	}
555
447
556
	private String asString(InputStream exptStream) throws IOException {
557
		return Utilities.readString(exptStream, ResourcesPlugin.getEncoding());
558
	}
559
560
	private void patcherPatch(String old, String patch, String expt) {
448
	private void patcherPatch(String old, String patch, String expt) {
561
		LineReader lr= new LineReader(getReader(old));
449
		LineReader lr= new LineReader(PatchUtils.getReader(old));
562
		List inLines= lr.readLines();
450
		List inLines= lr.readLines();
563
451
564
		WorkspacePatcher patcher= new WorkspacePatcher();
452
		WorkspacePatcher patcher= new WorkspacePatcher();
565
		try {
453
		try {
566
			patcher.parse(getReader(patch));
454
			patcher.parse(PatchUtils.getReader(patch));
567
		} catch (IOException e) {
455
		} catch (IOException e) {
568
			e.printStackTrace();
456
			e.printStackTrace();
569
		}
457
		}
Lines 574-580 Link Here
574
		FileDiffResult diffResult = patcher.getDiffResult(diffs[0]);
462
		FileDiffResult diffResult = patcher.getDiffResult(diffs[0]);
575
		diffResult.patch(inLines, null);
463
		diffResult.patch(inLines, null);
576
		
464
		
577
		LineReader expectedContents= new LineReader(getReader(expt));
465
		LineReader expectedContents= new LineReader(PatchUtils.getReader(expt));
578
		List expectedLines= expectedContents.readLines();
466
		List expectedLines= expectedContents.readLines();
579
		
467
		
580
		Object[] expected= expectedLines.toArray();
468
		Object[] expected= expectedLines.toArray();
Lines 618-624 Link Here
618
			patcher.getConfiguration().setFuzz(patchConfiguration.getFuzz());
506
			patcher.getConfiguration().setFuzz(patchConfiguration.getFuzz());
619
			patcher.getConfiguration().setIgnoreWhitespace(patchConfiguration.isIgnoreWhitespace());
507
			patcher.getConfiguration().setIgnoreWhitespace(patchConfiguration.isIgnoreWhitespace());
620
			patcher.getConfiguration().setPrefixSegmentStripCount(patchConfiguration.getPrefixSegmentStripCount());
508
			patcher.getConfiguration().setPrefixSegmentStripCount(patchConfiguration.getPrefixSegmentStripCount());
621
			patcher.parse(getReader(patch));
509
			patcher.parse(PatchUtils.getReader(patch));
622
			patcher.setReversed(patchConfiguration.isReversed());
510
			patcher.setReversed(patchConfiguration.isReversed());
623
		} catch (IOException e) {
511
		} catch (IOException e) {
624
			e.printStackTrace();
512
			e.printStackTrace();
Lines 630-642 Link Here
630
		//Iterate through all of the original files, apply the diffs that belong to the file and compare
518
		//Iterate through all of the original files, apply the diffs that belong to the file and compare
631
		//with the corresponding outcome file
519
		//with the corresponding outcome file
632
		for (int i = 0; i < originalFiles.length; i++) {	
520
		for (int i = 0; i < originalFiles.length; i++) {	
633
			LineReader lr= new LineReader(getReader(originalFiles[i]));
521
			LineReader lr= new LineReader(PatchUtils.getReader(originalFiles[i]));
634
			List inLines= lr.readLines();
522
			List inLines= lr.readLines();
635
		
523
		
636
			FileDiffResult diffResult = patcher.getDiffResult(diffs[i]);
524
			FileDiffResult diffResult = patcher.getDiffResult(diffs[i]);
637
			diffResult.patch(inLines, null);
525
			diffResult.patch(inLines, null);
638
			
526
			
639
			LineReader expectedContents= new LineReader(getReader(expectedOutcomeFiles[i]));
527
			LineReader expectedContents= new LineReader(PatchUtils.getReader(expectedOutcomeFiles[i]));
640
			List expectedLines= expectedContents.readLines();
528
			List expectedLines= expectedContents.readLines();
641
			
529
			
642
			Object[] expected= expectedLines.toArray();
530
			Object[] expected= expectedLines.toArray();
Lines 652-658 Link Here
652
		}
540
		}
653
	}
541
	}
654
	
542
	
655
	private Bundle getBundle() {
656
		return CompareTestPlugin.getDefault().getBundle();
657
	}	
658
}
543
}
(-)src/org/eclipse/compare/tests/AllTests.java (-1 / +2 lines)
Lines 1-5 Link Here
1
/*******************************************************************************
1
/*******************************************************************************
2
 * Copyright (c) 2000, 2008 IBM Corporation and others.
2
 * Copyright (c) 2000, 2009 IBM Corporation and others.
3
 * All rights reserved. This program and the accompanying materials
3
 * All rights reserved. This program and the accompanying materials
4
 * are made available under the terms of the Eclipse Public License v1.0
4
 * are made available under the terms of the Eclipse Public License v1.0
5
 * which accompanies this distribution, and is available at
5
 * which accompanies this distribution, and is available at
Lines 28-33 Link Here
28
		suite.addTestSuite(DocLineComparatorTest.class);
28
		suite.addTestSuite(DocLineComparatorTest.class);
29
		suite.addTestSuite(FilterTest.class);
29
		suite.addTestSuite(FilterTest.class);
30
		suite.addTestSuite(PatchTest.class);
30
		suite.addTestSuite(PatchTest.class);
31
		suite.addTestSuite(PatchBuilderTest.class);
31
		suite.addTestSuite(AsyncExecTests.class);
32
		suite.addTestSuite(AsyncExecTests.class);
32
		suite.addTestSuite(DiffTest.class);
33
		suite.addTestSuite(DiffTest.class);
33
		suite.addTestSuite(FileDiffResultTest.class);
34
		suite.addTestSuite(FileDiffResultTest.class);
(-)src/org/eclipse/compare/tests/PatchUtils.java (+170 lines)
Added Link Here
1
/*******************************************************************************
2
 * Copyright (c) 2009 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.compare.tests;
12
13
import java.io.BufferedInputStream;
14
import java.io.BufferedReader;
15
import java.io.File;
16
import java.io.FileInputStream;
17
import java.io.FileNotFoundException;
18
import java.io.IOException;
19
import java.io.InputStream;
20
import java.io.InputStreamReader;
21
import java.net.URL;
22
import java.util.jar.JarEntry;
23
import java.util.jar.JarFile;
24
25
import junit.framework.Assert;
26
27
import org.eclipse.compare.internal.Utilities;
28
import org.eclipse.compare.patch.PatchConfiguration;
29
import org.eclipse.core.resources.IStorage;
30
import org.eclipse.core.resources.ResourcesPlugin;
31
import org.eclipse.core.runtime.CoreException;
32
import org.eclipse.core.runtime.IPath;
33
import org.eclipse.core.runtime.Path;
34
import org.osgi.framework.Bundle;
35
36
public class PatchUtils {
37
38
	public static final String PATCHDATA = "patchdata";
39
40
	public static class PatchTestConfiguration {
41
		String subfolderName;
42
		PatchConfiguration pc;
43
		String patchFileName;
44
		String[] originalFileNames;
45
		String[] expectedFileNames;
46
		String[] actualFileNames;
47
	}
48
49
	public static class StringStorage implements IStorage {
50
		String fileName;
51
52
		public StringStorage(String old) {
53
			fileName = old;
54
		}
55
56
		public Object getAdapter(Class adapter) {
57
			return null;
58
		}
59
60
		public boolean isReadOnly() {
61
			return false;
62
		}
63
64
		public String getName() {
65
			return fileName;
66
		}
67
68
		public IPath getFullPath() {
69
			return null;
70
		}
71
72
		public InputStream getContents() throws CoreException {
73
			return new BufferedInputStream(asInputStream(fileName));
74
		}
75
	}
76
77
	public static class FileStorage implements IStorage {
78
		File file;
79
80
		public FileStorage(File file) {
81
			this.file = file;
82
		}
83
84
		public InputStream getContents() throws CoreException {
85
			try {
86
				return new FileInputStream(file);
87
			} catch (FileNotFoundException e) {
88
				// ignore, should never happen
89
			}
90
			return null;
91
		}
92
93
		public IPath getFullPath() {
94
			return new Path(file.getAbsolutePath());
95
		}
96
97
		public String getName() {
98
			return file.getName();
99
		}
100
101
		public boolean isReadOnly() {
102
			return true;
103
		}
104
105
		public Object getAdapter(Class adapter) {
106
			return null;
107
		}
108
	}
109
110
	public static class JarEntryStorage implements IStorage {
111
		JarEntry jarEntry;
112
		JarFile jarFile;
113
114
		public JarEntryStorage(JarEntry jarEntry, JarFile jarFile) {
115
			this.jarEntry = jarEntry;
116
			this.jarFile = jarFile;
117
		}
118
119
		public InputStream getContents() throws CoreException {
120
			try {
121
				return jarFile.getInputStream(jarEntry);
122
			} catch (IOException e) {
123
				// ignore, should never happen
124
			}
125
			return null;
126
		}
127
128
		public IPath getFullPath() {
129
			return new Path(jarFile.getName());
130
		}
131
132
		public String getName() {
133
			return jarEntry.getName();
134
		}
135
136
		public boolean isReadOnly() {
137
			return true;
138
		}
139
140
		public Object getAdapter(Class adapter) {
141
			return null;
142
		}
143
	}
144
145
	public static String asString(InputStream exptStream) throws IOException {
146
		return Utilities.readString(exptStream, ResourcesPlugin.getEncoding());
147
	}
148
149
	public static InputStream asInputStream(String name) {
150
		IPath path = new Path(PATCHDATA).append(name);
151
		try {
152
			URL url = new URL(getBundle().getEntry("/"), path.toString());
153
			return url.openStream();
154
		} catch (IOException e) {
155
			Assert.fail("Failed while reading " + name);
156
			return null; // never reached
157
		}
158
	}
159
160
	public static BufferedReader getReader(String name) {
161
		InputStream resourceAsStream = PatchUtils.asInputStream(name);
162
		InputStreamReader reader2 = new InputStreamReader(resourceAsStream);
163
		return new BufferedReader(reader2);
164
	}
165
166
	public static Bundle getBundle() {
167
		return CompareTestPlugin.getDefault().getBundle();
168
	}
169
170
}
(-)patchdata/context_full.txt (+76 lines)
Added Link Here
1
### Eclipse Workspace Patch 1.0
2
#P Bug202944
3
Index: tmp/context_full.txt
4
===================================================================
5
RCS file: /TEST/Bug202944/tmp/context_full.txt,v
6
retrieving revision 1.1
7
diff -u -r1.1 context_full.txt
8
--- tmp/context_full.txt	23 Feb 2009 09:39:56 -0000	1.1
Added Link Here
1
### Eclipse Workspace Patch 1.0
2
#P Bug202944
3
Index: tmp/list.txt
4
===================================================================
5
RCS file: /TEST/Bug202944/tmp/list.txt,v
6
retrieving revision 1.2
7
diff -u -r1.2 list.txt
8
--- tmp/list.txt	20 Feb 2009 11:02:27 -0000	1.2
Added Link Here
1
### Eclipse Workspace Patch 1.0
2
#P Bug202944
3
Index: tmp/context_full.txt
4
===================================================================
5
RCS file: /TEST/Bug202944/tmp/context_full.txt,v
6
retrieving revision 1.1
7
diff -u -r1.1 context_full.txt
8
--- tmp/context_full.txt	23 Feb 2009 09:39:56 -0000	1.1
Added Link Here
1
[a]
2
[b]
3
[c]
4
[d]
5
[e]
6
[f]
7
[g]
8
[h]
9
[i]
10
[j]
11
[k]
12
[l]
13
[m]
14
[n]
15
[o]
16
[p]
17
[q]
18
[r]
19
[s]
20
[t]
21
[u]
22
[v]
23
[w]
24
[x]
25
[y]
26
[z]
27
[A]
28
[B]
29
[C]
30
[D]
31
[E]
32
[F]
33
[G]
34
[H]
35
[I]
36
[J]
37
[K]
38
[L]
39
[M]
40
[N]
41
[O]
42
[P]
43
[Q]
44
[R]
45
[S]
46
[T]
47
[U]
48
[V]
49
[W]
50
[X]
51
[Y]
52
[Z]
(-)patchdata/exp_removeHunks.txt (+59 lines)
Added Link Here
1
### Eclipse Workspace Patch 1.0
2
#P Bug202944
3
Index: tmp/a.txt
4
===================================================================
5
RCS file: /TEST/Bug202944/tmp/a.txt,v
6
retrieving revision 1.1
7
diff -u -r1.1 a.txt
8
--- tmp/a.txt	20 Feb 2009 11:37:35 -0000	1.1
Added Link Here
1
[a]
2
[b]
3
[c]
4
[d]
5
[e]
6
[f]
7
[g]
8
[h]
9
[i]
10
[j]
11
[k]
12
[l]
13
[m]
14
[n]
15
[o]
16
[p]
17
[q]
18
[r]
19
[s]
20
[t]
21
[u]
22
[v]
23
[y]
24
[z]
25
[A]
26
[B]
27
[C]
28
[D]
29
[E]
30
[F]
31
[I]
32
[J]
33
[J1]
34
[K]
35
[L]
36
[M]
37
[N]
38
[O]
39
[P]
40
[Q]
41
[R]
42
[S]
43
[T]
44
[U]
45
[V]
46
[W]
47
[W1]
48
[W2]
49
[W3]
50
[Y]
51
[Z]
(-)patchdata/exp_addHunks.txt (+59 lines)
Added Link Here
1
[a1]
2
[a2]
3
[a]
4
[b]
5
[c]
6
[d]
7
[d1]
8
[d2]
9
[d3]
10
[d4]
11
[e]
12
[f]
13
[g]
14
[h]
15
[i]
16
[j]
17
[k]
18
[l]
19
[m]
20
[n]
21
[o]
22
[p]
23
[q]
24
[r]
25
[s]
26
[t]
27
[u]
28
[v]
29
[y]
30
[z]
31
[A]
32
[B]
33
[C]
34
[D]
35
[E]
36
[F]
37
[G]
38
[H]
39
[I]
40
[J]
41
[K]
42
[L]
43
[N]
44
[N1]
45
[N2]
46
[O]
47
[P]
48
[Q]
49
[R]
50
[S]
51
[T]
52
[U]
53
[V]
54
[W]
55
[W1]
56
[W2]
57
[W3]
58
[Y]
59
[Z]
(-)src/org/eclipse/compare/tests/PatchBuilderTest.java (+296 lines)
Added Link Here
1
/*******************************************************************************
2
 * Copyright (c) 2009 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.compare.tests;
12
13
import java.io.IOException;
14
import java.io.InputStream;
15
import java.util.List;
16
17
import junit.framework.TestCase;
18
19
import org.eclipse.compare.internal.core.patch.FileDiff;
20
import org.eclipse.compare.internal.core.patch.Hunk;
21
import org.eclipse.compare.internal.core.patch.LineReader;
22
import org.eclipse.compare.internal.patch.FileDiffWrapper;
23
import org.eclipse.compare.patch.ApplyPatchOperation;
24
import org.eclipse.compare.patch.IFilePatch;
25
import org.eclipse.compare.patch.IFilePatch2;
26
import org.eclipse.compare.patch.IFilePatchResult;
27
import org.eclipse.compare.patch.IHunk;
28
import org.eclipse.compare.patch.PatchBuilder;
29
import org.eclipse.compare.patch.PatchConfiguration;
30
import org.eclipse.compare.tests.PatchUtils.StringStorage;
31
import org.eclipse.core.resources.IStorage;
32
import org.eclipse.core.runtime.CoreException;
33
import org.eclipse.core.runtime.NullProgressMonitor;
34
import org.eclipse.core.runtime.Path;
35
36
public class PatchBuilderTest extends TestCase {
37
38
	public PatchBuilderTest() {
39
40
	}
41
42
	protected void setUp() throws Exception {
43
		// Nothing to do
44
	}
45
46
	protected void tearDown() throws Exception {
47
		super.tearDown();
48
	}
49
50
	public void testModifyHunks() throws CoreException, IOException {
51
		IStorage patchStorage = new StringStorage("patch_modifyHunks.txt");
52
		IStorage contextStorage = new StringStorage("context.txt");
53
		IFilePatch[] patches = ApplyPatchOperation.parsePatch(patchStorage);
54
		assertEquals(1, patches.length);
55
		IHunk[] hunksBefore = patches[0].getHunks();
56
		assertEquals(5, hunksBefore.length);
57
58
		String[] lines = new String[] { " [d]", "+[d1]", "+[d2]", "+[d3]",
59
				"+[d4]", " [e]" };
60
		addLineDelimiters(lines);
61
		IHunk[] toAdd = new IHunk[] { PatchBuilder.createHunk(3, lines) };
62
		IFilePatch2 filePatch = PatchBuilder.addHunks(patches[0], toAdd);
63
64
		IHunk[] toRemove = new IHunk[] { hunksBefore[0], hunksBefore[2] };
65
		filePatch = PatchBuilder.removeHunks(filePatch, toRemove);
66
67
		IHunk[] hunksAfter = filePatch.getHunks();
68
		assertEquals(4, hunksAfter.length);
69
		assertEquals(3, ((Hunk) hunksAfter[0]).getStart(false));
70
		assertEquals(3, ((Hunk) hunksAfter[0]).getStart(true));
71
		assertEquals(7, ((Hunk) hunksAfter[1]).getStart(false));
72
		assertEquals(11, ((Hunk) hunksAfter[1]).getStart(true));
73
		assertEquals(18, ((Hunk) hunksAfter[2]).getStart(false));
74
		assertEquals(22, ((Hunk) hunksAfter[2]).getStart(true));
75
		assertEquals(28, ((Hunk) hunksAfter[3]).getStart(false));
76
		assertEquals(33, ((Hunk) hunksAfter[3]).getStart(true));
77
78
		FileDiffWrapper wrapper = new FileDiffWrapper((FileDiff) filePatch);
79
		IFilePatchResult result = wrapper.apply(contextStorage,
80
				new PatchConfiguration(), new NullProgressMonitor());
81
82
		IHunk[] rejects = result.getRejects();
83
		assertEquals(1, rejects.length);
84
85
		InputStream actual = result.getPatchedContents();
86
87
		LineReader lr = new LineReader(PatchUtils
88
				.getReader("exp_modifyHunks.txt"));
89
		List inLines = lr.readLines();
90
		String expected = LineReader.createString(false, inLines);
91
92
		assertEquals(expected, PatchUtils.asString(actual));
93
	}
94
95
	public void testAddHunks() throws CoreException, IOException {
96
		IStorage patchStorage = new StringStorage("patch_addHunks.txt");
97
		IStorage contextStorage = new StringStorage("context_full.txt");
98
		IFilePatch[] patches = ApplyPatchOperation.parsePatch(patchStorage);
99
		assertEquals(1, patches.length);
100
		IHunk[] hunksBefore = patches[0].getHunks();
101
		assertEquals(3, hunksBefore.length);
102
103
		String[] lines0 = new String[] { " [d]", "+[d1]", "+[d2]", "+[d3]",
104
				"+[d4]", " [e]" };
105
		addLineDelimiters(lines0);
106
		IHunk hunk0 = PatchBuilder.createHunk(3, lines0);
107
108
		String[] lines1 = new String[] { " [K]", " [L]", "-[M]", " [N]",
109
				"+[N1]", "+[N2]", " [O]", " [P]" };
110
		addLineDelimiters(lines1);
111
		IHunk hunk1 = PatchBuilder.createHunk(36, lines1);
112
113
		IHunk[] toAdd = new IHunk[] { hunk0, hunk1 };
114
		IFilePatch2 filePatch = PatchBuilder.addHunks(patches[0], toAdd);
115
116
		IHunk[] hunksAfter = filePatch.getHunks();
117
		assertEquals(5, hunksAfter.length);
118
		assertEquals(0, ((Hunk) hunksAfter[0]).getStart(false));
119
		assertEquals(0, ((Hunk) hunksAfter[0]).getStart(true));
120
		assertEquals(3, ((Hunk) hunksAfter[1]).getStart(false));
121
		assertEquals(5, ((Hunk) hunksAfter[1]).getStart(true));
122
		assertEquals(19, ((Hunk) hunksAfter[2]).getStart(false));
123
		assertEquals(25, ((Hunk) hunksAfter[2]).getStart(true));
124
		assertEquals(36, ((Hunk) hunksAfter[3]).getStart(false));
125
		assertEquals(40, ((Hunk) hunksAfter[3]).getStart(true));
126
		assertEquals(46, ((Hunk) hunksAfter[4]).getStart(false));
127
		assertEquals(51, ((Hunk) hunksAfter[4]).getStart(true));
128
129
		FileDiffWrapper wrapper = new FileDiffWrapper((FileDiff) filePatch);
130
		IFilePatchResult result = wrapper.apply(contextStorage,
131
				new PatchConfiguration(), new NullProgressMonitor());
132
133
		IHunk[] rejects = result.getRejects();
134
		assertEquals(0, rejects.length);
135
136
		InputStream actual = result.getPatchedContents();
137
138
		LineReader lr = new LineReader(PatchUtils.getReader("exp_addHunks.txt"));
139
		List inLines = lr.readLines();
140
		String expected = LineReader.createString(false, inLines);
141
142
		assertEquals(expected, PatchUtils.asString(actual));
143
	}
144
145
	public void testRemoveHunks() throws CoreException, IOException {
146
		IStorage patchStorage = new StringStorage("patch_removeHunks.txt");
147
		IStorage contextStorage = new StringStorage("context_full.txt");
148
		IFilePatch[] patches = ApplyPatchOperation.parsePatch(patchStorage);
149
		assertEquals(1, patches.length);
150
		IHunk[] hunksBefore = patches[0].getHunks();
151
		assertEquals(5, hunksBefore.length);
152
153
		IHunk[] toRemove = new IHunk[] { hunksBefore[0], hunksBefore[1] };
154
		IFilePatch2 filePatch = PatchBuilder.removeHunks(patches[0], toRemove);
155
156
		IHunk[] hunksAfter = filePatch.getHunks();
157
		assertEquals(3, hunksAfter.length);
158
		assertEquals(19, ((Hunk) hunksAfter[0]).getStart(false));
159
		assertEquals(19, ((Hunk) hunksAfter[0]).getStart(true));
160
		assertEquals(29, ((Hunk) hunksAfter[1]).getStart(false));
161
		assertEquals(27, ((Hunk) hunksAfter[1]).getStart(true));
162
		assertEquals(46, ((Hunk) hunksAfter[2]).getStart(false));
163
		assertEquals(43, ((Hunk) hunksAfter[2]).getStart(true));
164
165
		FileDiffWrapper wrapper = new FileDiffWrapper((FileDiff) filePatch);
166
		IFilePatchResult result = wrapper.apply(contextStorage,
167
				new PatchConfiguration(), new NullProgressMonitor());
168
169
		IHunk[] rejects = result.getRejects();
170
		assertEquals(0, rejects.length);
171
172
		InputStream actual = result.getPatchedContents();
173
174
		LineReader lr = new LineReader(PatchUtils
175
				.getReader("exp_removeHunks.txt"));
176
		List inLines = lr.readLines();
177
		String expected = LineReader.createString(false, inLines);
178
179
		assertEquals(expected, PatchUtils.asString(actual));
180
	}
181
182
	public void testCreateFilePatch() throws CoreException, IOException {
183
		IStorage contextStorage = new StringStorage("context.txt");
184
185
		String[] lines0 = new String[] { "+[a1]", "+[a2]", "+[a3]", " [a]" };
186
		addLineDelimiters(lines0);
187
		Hunk hunk0 = (Hunk) PatchBuilder.createHunk(0, lines0);
188
189
		String[] lines1 = new String[] { " [b]", " [c]", "-[d]", "-[e]",
190
				" [f]", " [g]", " [h]", "+[h1]", " [i]", " [j]", "+[j1]",
191
				"+[j2]", " [k]", " [l]" };
192
		addLineDelimiters(lines1);
193
		Hunk hunk1 = (Hunk) PatchBuilder.createHunk(1, lines1);
194
195
		IHunk[] hunks = new IHunk[] { hunk1, hunk0 };
196
197
		IFilePatch2 filePatch = PatchBuilder.createFilePatch(new Path(""),
198
				IFilePatch2.DATE_UNKNOWN, new Path(""),
199
				IFilePatch2.DATE_UNKNOWN, hunks);
200
201
		assertEquals(2, filePatch.getHunks().length);
202
		assertEquals(hunk0, filePatch.getHunks()[0]);
203
		assertEquals(hunk1, filePatch.getHunks()[1]);
204
205
		FileDiffWrapper wrapper = new FileDiffWrapper((FileDiff) filePatch);
206
		IFilePatchResult result = wrapper.apply(contextStorage,
207
				new PatchConfiguration(), new NullProgressMonitor());
208
209
		InputStream actual = result.getPatchedContents();
210
211
		LineReader lr = new LineReader(PatchUtils
212
				.getReader("exp_createFilePatch.txt"));
213
		List inLines = lr.readLines();
214
		String expected = LineReader.createString(false, inLines);
215
216
		assertEquals(expected, PatchUtils.asString(actual));
217
	}
218
219
	public void testCreateHunk0() throws CoreException {
220
		IStorage patch = new StringStorage("patch_createHunk0.txt");
221
		IFilePatch[] filePatches = ApplyPatchOperation.parsePatch(patch);
222
		assertEquals(1, filePatches.length);
223
		assertEquals(1, filePatches[0].getHunks().length);
224
225
		String[] lines = new String[] { "+[a1]", "+[a2]", "+[a3]", " [a]",
226
				" [b]", "-[c]", " [d]", " [e]", " [f]" };
227
		addLineDelimiters(lines);
228
		Hunk hunk = (Hunk) PatchBuilder.createHunk(0, lines);
229
230
		assertHunkEquals(hunk, (Hunk) filePatches[0].getHunks()[0]);
231
	}
232
233
	public void testCreateHunk1() throws CoreException {
234
		IStorage patch = new StringStorage("patch_createHunk1.txt");
235
		IFilePatch[] filePatches = ApplyPatchOperation.parsePatch(patch);
236
		assertEquals(1, filePatches.length);
237
		assertEquals(1, filePatches[0].getHunks().length);
238
239
		String[] lines = new String[] { " [a]", " [b]", "-[c]", " [d]", "-[e]",
240
				" [f]", " [g]", " [h]", "+[h1]", " [i]", " [j]", "+[j1]",
241
				"+[j2]", " [k]", " [l]", " [m]" };
242
		addLineDelimiters(lines);
243
		Hunk hunk = (Hunk) PatchBuilder.createHunk(0, lines);
244
245
		assertHunkEquals(hunk, (Hunk) filePatches[0].getHunks()[0]);
246
	}
247
248
	public void testCreateHunk2() throws CoreException {
249
		IStorage patch = new StringStorage("patch_createHunk2.txt");
250
		IFilePatch[] filePatches = ApplyPatchOperation.parsePatch(patch);
251
		assertEquals(1, filePatches.length);
252
		assertEquals(1, filePatches[0].getHunks().length);
253
254
		String[] lines = new String[] { "+[aa]", "+[bb]", "+[cc]" };
255
		addLineDelimiters(lines);
256
		Hunk hunk = (Hunk) PatchBuilder.createHunk(0, lines);
257
258
		assertHunkEquals(hunk, (Hunk) filePatches[0].getHunks()[0]);
259
	}
260
261
	public void testCreateHunk3() throws CoreException {
262
		IStorage patch = new StringStorage("patch_createHunk3.txt");
263
		IFilePatch[] filePatches = ApplyPatchOperation.parsePatch(patch);
264
		assertEquals(1, filePatches.length);
265
		assertEquals(1, filePatches[0].getHunks().length);
266
267
		String[] lines = new String[] { "-[aa]", "-[bb]", "-[cc]", "-[dd]" };
268
		addLineDelimiters(lines);
269
		Hunk hunk = (Hunk) PatchBuilder.createHunk(0, lines);
270
271
		assertHunkEquals(hunk, (Hunk) filePatches[0].getHunks()[0]);
272
	}
273
274
	private void assertHunkEquals(Hunk h1, Hunk h2) {
275
		String[] l1 = h1.getLines();
276
		String[] l2 = h2.getLines();
277
		assertEquals(l1.length, l2.length);
278
		for (int i = 0; i < l1.length; i++) {
279
			assertFalse(l1[i] == null && l2[i] != null);
280
			assertEquals(l1[i], (l2[i]));
281
		}
282
		assertEquals(h1.getStart(false), h2.getStart(false));
283
		assertEquals(h1.getStart(true), h2.getStart(true));
284
		assertEquals(h1.getLength(false), h2.getLength(false));
285
		assertEquals(h1.getLength(true), h2.getLength(true));
286
		assertEquals(h1.getHunkType(false), h2.getHunkType(false));
287
		assertEquals(h1.getHunkType(true), h2.getHunkType(true));
288
	}
289
290
	private void addLineDelimiters(String[] lines) {
291
		for (int i = 0; i < lines.length; i++) {
292
			lines[i] = lines[i] + "\r\n";
293
		}
294
	}
295
296
}
(-)patchdata/exp_createFilePatch.txt (+34 lines)
Added Link Here
1
### Eclipse Workspace Patch 1.0
2
#P Bug202944
3
Index: tmp/a.txt
4
===================================================================
5
RCS file: tmp/a.txt
6
diff -N tmp/a.txt
7
--- /dev/null	1 Jan 1970 00:00:00 -0000
Added Link Here
1
[a1]
2
[a2]
3
[a3]
4
[a]
5
[b]
6
[c]
7
[f]
8
[g]
9
[h]
10
[h1]
11
[i]
12
[j]
13
[j1]
14
[j2]
15
[k]
16
[l]
17
[m]
18
[n]
19
[o]
20
[p]
21
[q]
22
[r]
23
[s]
24
[t]
25
[u]
26
[v]
27
[w]
(-)patchdata/exp_modifyHunks.txt (+28 lines)
Added Link Here
1
[a]
2
[b]
3
[c]
4
[d]
5
[d1]
6
[d2]
7
[d3]
8
[d4]
9
[e]
10
[f]
11
[g]
12
[h]
13
[i1]
14
[j]
15
[k]
16
[l]
17
[m]
18
[n]
19
[o]
20
[p]
21
[q]
22
[r]
23
[s]
24
[s1]
25
[t]
26
[u]
27
[v]
28
[w]
(-)src/org/eclipse/compare/internal/core/patch/FileDiffResult.java (-4 / +22 lines)
Added Link Here
1
### Eclipse Workspace Patch 1.0
2
#P Bug202944
3
Index: tmp/list.txt
4
===================================================================
5
RCS file: /TEST/Bug202944/tmp/list.txt,v
6
retrieving revision 1.2
7
diff -u -r1.2 list.txt
8
--- tmp/list.txt	20 Feb 2009 11:02:27 -0000	1.2
Added Link Here
1
--- old.txt	2005-05-07 00:16:20.000000000 +0200
Added Link Here
259
259
260
	public List getFailedHunks() {
260
	public List getFailedHunks() {
261
		List failedHunks = new ArrayList();
261
		List failedHunks = new ArrayList();
262
		for (Iterator iterator = fHunkResults.values().iterator(); iterator.hasNext();) {
262
		IHunk[] hunks = fDiff.getHunks();
263
			HunkResult result = (HunkResult) iterator.next();
263
		for (int i = 0; i < hunks.length; i++) {
264
			if (!result.isOK())
264
			HunkResult result = (HunkResult) fHunkResults.get(hunks[i]);
265
			if (result != null && !result.isOK())
265
				failedHunks.add(result.getHunk());
266
				failedHunks.add(result.getHunk());
266
		}
267
		}
267
		return failedHunks;
268
		return failedHunks;
Added Link Here
280
	}
281
	}
281
282
282
	public HunkResult[] getHunkResults() {
283
	public HunkResult[] getHunkResults() {
283
		return (HunkResult[]) fHunkResults.values().toArray(new HunkResult[fHunkResults.size()]);
284
		List results = new ArrayList();
285
		IHunk[] hunks = fDiff.getHunks();
286
		for (int i = 0; i < hunks.length; i++) {
287
			HunkResult result = (HunkResult) fHunkResults.get(hunks[i]);
288
			if (result != null) {
289
				results.add(result.getHunk());
290
			}
291
		}
292
		return (HunkResult[]) results.toArray(new HunkResult[results.size()]);
284
	}
293
	}
285
294
286
	public InputStream getOriginalContents() {
295
	public InputStream getOriginalContents() {
(-)src/org/eclipse/compare/internal/core/patch/Hunk.java (-6 / +14 lines)
Lines 127-133 Link Here
127
		return sb.toString();
127
		return sb.toString();
128
	}
128
	}
129
	
129
	
130
	int getHunkType(boolean reverse) {
130
	public int getHunkType(boolean reverse) {
131
		if (reverse) {
131
		if (reverse) {
132
			if (hunkType == FileDiff.ADDITION)
132
			if (hunkType == FileDiff.ADDITION)
133
				return FileDiff.DELETION;
133
				return FileDiff.DELETION;
Lines 291-305 Link Here
291
		return true;
291
		return true;
292
	}
292
	}
293
	
293
	
294
	int getStart(boolean reverse) {
294
	public int getStart(boolean after) {
295
		if (reverse) {
295
		if (after) {
296
			return fNewStart;
296
			return fNewStart;
297
		}
297
		}
298
		return fOldStart;
298
		return fOldStart;
299
	}
299
	}
300
	
300
301
	private int getLength(boolean reverse) {
301
	public void setStart(int start, boolean after) {
302
		if (reverse) {
302
		if (after) {
303
			fNewStart = start;
304
		} else {
305
			fOldStart = start;
306
		}
307
	}
308
309
	public int getLength(boolean after) {
310
		if (after) {
303
			return fNewLength;
311
			return fNewLength;
304
		}
312
		}
305
		return fOldLength;
313
		return fOldLength;
(-)src/org/eclipse/compare/patch/PatchBuilder.java (+238 lines)
Added Link Here
1
/*******************************************************************************
2
 * Copyright (c) 2009 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.compare.patch;
12
13
import java.util.Arrays;
14
import java.util.Comparator;
15
16
import org.eclipse.compare.internal.core.patch.FileDiff;
17
import org.eclipse.compare.internal.core.patch.Hunk;
18
import org.eclipse.core.runtime.IPath;
19
20
/**
21
 * Builder for creating IFilePatch2 and IHunk objects as well as building
22
 * relationship between them.
23
 * 
24
 * @since org.eclipse.compare.core 1.0.0
25
 */
26
public class PatchBuilder {
27
28
	public static final char CONTEXT_PREFIX = ' ';
29
	public static final char ADDITION_PREFIX = '+';
30
	public static final char REMOVAL_PREFIX = '-';
31
32
	/**
33
	 * Creates an IHunk instance.
34
	 * 
35
	 * @param start
36
	 *            the start position in the before file
37
	 * @param lines
38
	 *            content of the hunk. Each line starts with a control
39
	 *            character. Their meaning is as follows:
40
	 *            <ul>
41
	 *            <li>
42
	 *            '+': add the line
43
	 *            <li>
44
	 *            '-': delete the line
45
	 *            <li>
46
	 *            ' ': no change, context line
47
	 *            </ul>
48
	 * @return IHunk instance
49
	 */
50
	public static IHunk createHunk(int start, String[] lines) {
51
		int type = getHunkType(lines);
52
		int oldLength = getHunkLength(lines, true);
53
		int newLength = getHunkLength(lines, false);
54
		return new Hunk(null, type, start, oldLength, start, newLength, lines);
55
	}
56
57
	/**
58
	 * Creates an IFilePatch2 instance and performs recalculation of all hunks'
59
	 * after positions. Hunk's after position is position in the file state
60
	 * after applying a patch. It is affected by all the hunks that are to be
61
	 * applied before a given one. This recalculation is necessary to keep
62
	 * IFilePatch2's state coherent.
63
	 * 
64
	 * @param oldPath
65
	 *            the path of the before state of the file
66
	 * @param oldDate
67
	 *            the timestamp of the before state of the file, see also
68
	 *            {@link IFilePatch2#DATE_UNKNOWN}
69
	 * @param newPath
70
	 *            the path of the after state of the file
71
	 * @param newDate
72
	 *            the timestamp of the after state of the file, see also
73
	 *            {@link IFilePatch2#DATE_UNKNOWN}
74
	 * @param hunks
75
	 *            a set of hunks to insert into IFilePatch2
76
	 * @return IFilePatch2 instance
77
	 */
78
	public static IFilePatch2 createFilePatch(IPath oldPath, long oldDate,
79
			IPath newPath, long newDate, IHunk[] hunks) {
80
		reorder(hunks);
81
		FileDiff fileDiff = new FileDiff(oldPath, oldDate, newPath, newDate);
82
		for (int i = 0; i < hunks.length; i++) {
83
			fileDiff.add((Hunk) hunks[i]);
84
		}
85
		return fileDiff;
86
	}
87
88
	/**
89
	 * Adds IHunks to a given IFilePatch2 and performs recalculation of all
90
	 * hunks' after positions. Hunk's after position is position in the file
91
	 * state after applying a patch. It is affected by all the hunks that are to
92
	 * be applied before a given one. This recalculation is necessary to keep
93
	 * IFilePatch2's state coherent.
94
	 * 
95
	 * @param filePatch
96
	 *            a file patch to add hunks to
97
	 * @param toAdd
98
	 *            a set of IHunks to add
99
	 * @return newly created file patch with added hunks
100
	 */
101
	public static IFilePatch2 addHunks(IFilePatch2 filePatch, IHunk[] toAdd) {
102
		IHunk[] result = addHunks(filePatch.getHunks(), toAdd);
103
		reorder(result);
104
		return createFilePatch(filePatch, result);
105
	}
106
107
	/**
108
	 * Removes IHunks from a given IFilePatch2 and performs recalculation of all
109
	 * hunks' after positions. Hunk's after position is position in the file
110
	 * state after applying a patch. It is affected by all the hunks that are to
111
	 * be applied before a given one. This recalculation is necessary to keep
112
	 * IFilePatch2's state coherent.
113
	 * 
114
	 * @param filePatch
115
	 *            a file patch to add hunks to
116
	 * @param toRemove
117
	 *            a set of IHunks to add
118
	 * @return newly created file patch with removed hunks
119
	 */
120
	public static IFilePatch2 removeHunks(IFilePatch2 filePatch,
121
			IHunk[] toRemove) {
122
		IHunk[] result = removeHunks(filePatch.getHunks(), toRemove);
123
		reorder(result);
124
		return createFilePatch(filePatch, result);
125
	}
126
127
	private static IFilePatch2 createFilePatch(IFilePatch2 filePatch,
128
			IHunk[] hunks) {
129
		PatchConfiguration config = new PatchConfiguration();
130
		IPath beforePath = filePatch.getTargetPath(config);
131
		config.setReversed(true);
132
		IPath afterPath = filePatch.getTargetPath(config);
133
		return createFilePatch(beforePath, filePatch.getBeforeDate(),
134
				afterPath, filePatch.getAfterDate(), hunks);
135
	}
136
137
	private static int getHunkType(String[] lines) {
138
		boolean hasContextLines = checkForPrefix(CONTEXT_PREFIX, lines);
139
		if (!hasContextLines) {
140
			boolean hasLineAdditions = checkForPrefix(ADDITION_PREFIX, lines);
141
			boolean hasLineDeletions = checkForPrefix(REMOVAL_PREFIX, lines);
142
			if (hasLineAdditions && !hasLineDeletions) {
143
				return FileDiff.ADDITION;
144
			} else if (!hasLineAdditions && hasLineDeletions) {
145
				return FileDiff.DELETION;
146
			}
147
		}
148
		return FileDiff.CHANGE;
149
	}
150
151
	private static int getHunkLength(String[] lines, boolean old) {
152
		int length = 0;
153
		for (int i = 0; i < lines.length; i++) {
154
			if (lines[i].length() > 0) {
155
				switch (lines[i].charAt(0)) {
156
				case ' ':
157
					length++;
158
					break;
159
				case '+':
160
					if (!old) {
161
						length++;
162
					}
163
					break;
164
				case '-':
165
					if (old) {
166
						length++;
167
					}
168
					break;
169
				default:
170
					throw new IllegalArgumentException("");
171
				}
172
			}
173
		}
174
		return length;
175
	}
176
177
	private static boolean checkForPrefix(char prefix, String[] lines) {
178
		for (int i = 0; i < lines.length; i++) {
179
			if (lines[i].length() > 0) {
180
				if (lines[i].charAt(0) == prefix) {
181
					return true;
182
				}
183
			}
184
		}
185
		return false;
186
	}
187
188
	private static IHunk[] addHunks(IHunk[] hunks, IHunk[] toAdd) {
189
		IHunk[] ret = new IHunk[hunks.length + toAdd.length];
190
		System.arraycopy(hunks, 0, ret, 0, hunks.length);
191
		System.arraycopy(toAdd, 0, ret, hunks.length, toAdd.length);
192
		return ret;
193
	}
194
195
	private static IHunk[] removeHunks(IHunk[] hunks, IHunk[] toRemove) {
196
		int removed = 0;
197
		for (int i = 0; i < hunks.length; i++) {
198
			for (int j = 0; j < toRemove.length; j++) {
199
				if (toRemove[j] == hunks[i]) {
200
					hunks[i] = null;
201
					removed++;
202
				}
203
			}
204
		}
205
		IHunk[] ret = new IHunk[hunks.length - removed];
206
		for (int i = 0, j = 0; i < hunks.length; i++) {
207
			if (hunks[i] != null) {
208
				ret[j++] = hunks[i];
209
			}
210
		}
211
		return ret;
212
	}
213
214
	private static void reorder(IHunk[] hunks) {
215
		Arrays.sort(hunks, new HunkComparator());
216
		int shift = 0;
217
		for (int i = 0; i < hunks.length; i++) {
218
			Hunk hunk = (Hunk) hunks[i];
219
			int start = hunk.getStart(false) + shift;
220
			hunk.setStart(start, true);
221
			shift += hunk.getLength(true) - hunk.getLength(false);
222
		}
223
	}
224
225
	static class HunkComparator implements Comparator {
226
		public int compare(Object arg0, Object arg1) {
227
			if ((arg0 != null && arg0 instanceof Hunk)
228
					&& (arg1 != null && arg1 instanceof Hunk)) {
229
				Hunk hunk0 = (Hunk) arg0;
230
				Hunk hunk1 = (Hunk) arg1;
231
				int shift = hunk0.getStart(true) - hunk1.getStart(true);
232
				return shift;
233
			}
234
			return 0;
235
		}
236
	}
237
238
}

Return to bug 183226