Some Eclipse Foundation services are deprecated, or will be soon. Please ensure you've read this important communication.
View | Details | Raw Unified | Return to bug 347557 | Differences between
and this patch

Collapse All | Expand All

(-)META-INF/MANIFEST.MF (-1 / +2 lines)
Lines 14-20 Link Here
14
 org.eclipse.core.resources,
14
 org.eclipse.core.resources,
15
 org.eclipse.core.tests.resources,
15
 org.eclipse.core.tests.resources,
16
 org.eclipse.core.tests.harness,
16
 org.eclipse.core.tests.harness,
17
 org.eclipse.core.filesystem
17
 org.eclipse.core.filesystem,
18
 org.eclipse.team.ui
18
Bundle-Activator: org.eclipse.compare.tests.CompareTestPlugin
19
Bundle-Activator: org.eclipse.compare.tests.CompareTestPlugin
19
Bundle-ActivationPolicy: lazy
20
Bundle-ActivationPolicy: lazy
20
Bundle-Vendor: %providerName
21
Bundle-Vendor: %providerName
(-)src/org/eclipse/compare/tests/ReflectionUtils.java (-1 / +24 lines)
Lines 1-5 Link Here
1
/*******************************************************************************
1
/*******************************************************************************
2
 * Copyright (c) 2009 IBM Corporation and others.
2
 * Copyright (c) 2009, 2011 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 53-56 Link Here
53
		return ret;
53
		return ret;
54
	}
54
	}
55
55
56
	public static Object getField(Object object, String name, boolean deep)
57
			throws IllegalArgumentException, IllegalAccessException,
58
			SecurityException, NoSuchFieldException {
59
		Class clazz = object.getClass();
60
		NoSuchFieldException ex = null;
61
		while (clazz != null) {
62
			try {
63
				Field field = clazz.getDeclaredField(name);
64
				field.setAccessible(true);
65
				return field.get(object);
66
			} catch (NoSuchFieldException e) {
67
				if (ex == null) {
68
					ex = e;
69
				}
70
				if (!deep)
71
					break;
72
				clazz = clazz.getSuperclass();
73
74
			}
75
		}
76
		throw ex;
77
	}
78
56
}
79
}
(-)src/org/eclipse/compare/tests/SaveableCompareEditorInputTest.java (+390 lines)
Added Link Here
1
/*******************************************************************************
2
 * Copyright (c) 2011 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.BufferedReader;
14
import java.io.ByteArrayInputStream;
15
import java.io.IOException;
16
import java.io.InputStreamReader;
17
import java.lang.reflect.InvocationTargetException;
18
import java.util.ArrayList;
19
import java.util.List;
20
21
import junit.framework.TestCase;
22
23
import org.eclipse.compare.CompareConfiguration;
24
import org.eclipse.compare.CompareEditorInput;
25
import org.eclipse.compare.ITypedElement;
26
import org.eclipse.compare.contentmergeviewer.TextMergeViewer;
27
import org.eclipse.compare.internal.MergeSourceViewer;
28
import org.eclipse.compare.structuremergeviewer.Differencer;
29
import org.eclipse.compare.structuremergeviewer.ICompareInput;
30
import org.eclipse.core.resources.IFile;
31
import org.eclipse.core.resources.IProject;
32
import org.eclipse.core.resources.IResource;
33
import org.eclipse.core.resources.ResourcesPlugin;
34
import org.eclipse.core.runtime.CoreException;
35
import org.eclipse.core.runtime.IProgressMonitor;
36
import org.eclipse.core.runtime.ISafeRunnable;
37
import org.eclipse.core.runtime.ListenerList;
38
import org.eclipse.core.runtime.SafeRunner;
39
import org.eclipse.jface.dialogs.Dialog;
40
import org.eclipse.jface.util.IPropertyChangeListener;
41
import org.eclipse.jface.util.PropertyChangeEvent;
42
import org.eclipse.swt.custom.StyledText;
43
import org.eclipse.swt.graphics.Image;
44
import org.eclipse.swt.widgets.Composite;
45
import org.eclipse.swt.widgets.Control;
46
import org.eclipse.swt.widgets.Shell;
47
import org.eclipse.team.internal.ui.mapping.AbstractCompareInput;
48
import org.eclipse.team.internal.ui.mapping.CompareInputChangeNotifier;
49
import org.eclipse.team.internal.ui.synchronize.LocalResourceTypedElement;
50
import org.eclipse.team.ui.synchronize.SaveableCompareEditorInput;
51
import org.eclipse.ui.PlatformUI;
52
53
public class SaveableCompareEditorInputTest extends TestCase {
54
55
	private class FileElement implements ITypedElement {
56
57
		private IFile file;
58
59
		public IFile getFile() {
60
			return file;
61
		}
62
63
		public FileElement(IFile file) {
64
			super();
65
			this.file = file;
66
		}
67
68
		public String getName() {
69
			return file.getName();
70
		}
71
72
		public Image getImage() {
73
			return null;
74
		}
75
76
		public String getType() {
77
			return TEXT_TYPE;
78
		}
79
80
	}
81
82
	public class TestDiffNode extends AbstractCompareInput {
83
84
		private CompareInputChangeNotifier notifier = new CompareInputChangeNotifier() {
85
86
			private IResource getResource(ITypedElement el) {
87
				if (el instanceof LocalResourceTypedElement) {
88
					return ((LocalResourceTypedElement) el).getResource();
89
				}
90
				if (el instanceof FileElement) {
91
					return ((FileElement) el).getFile();
92
				}
93
				return null;
94
			}
95
96
			protected IResource[] getResources(ICompareInput input) {
97
98
				List resources = new ArrayList();
99
				if (getResource(getLeft()) != null) {
100
					resources.add(getResource(getLeft()));
101
				}
102
				if (getResource(getRight()) != null) {
103
					resources.add(getResource(getRight()));
104
				}
105
106
				return (IResource[]) resources.toArray(new IResource[2]);
107
			}
108
		};
109
110
		public TestDiffNode(ITypedElement left, ITypedElement right) {
111
			super(Differencer.CHANGE, null, left, right);
112
		}
113
114
		public void fireChange() {
115
			super.fireChange();
116
		}
117
118
		protected CompareInputChangeNotifier getChangeNotifier() {
119
			return notifier;
120
		}
121
122
		public boolean needsUpdate() {
123
			// The remote never changes
124
			return false;
125
		}
126
127
		public void update() {
128
			fireChange();
129
		}
130
	}
131
132
	private class TestSaveableEditorInputLocal extends
133
			SaveableCompareEditorInput {
134
135
		protected ITypedElement left;
136
		protected ITypedElement right;
137
		private ICompareInput input;
138
139
		public Object getCompareResult() {
140
			return input;
141
		}
142
143
		public TestSaveableEditorInputLocal(ITypedElement left,
144
				ITypedElement right, CompareConfiguration conf) {
145
			super(conf, PlatformUI.getWorkbench().getActiveWorkbenchWindow()
146
					.getActivePage());
147
			this.left = left;
148
			this.right = right;
149
		}
150
151
		protected ICompareInput prepareCompareInput(IProgressMonitor monitor)
152
				throws InvocationTargetException, InterruptedException {
153
			input = createCompareInput();
154
			getCompareConfiguration().setLeftEditable(true);
155
			getCompareConfiguration().setRightEditable(false);
156
			return null;
157
		}
158
159
		private ICompareInput createCompareInput() {
160
			return new TestDiffNode(left, right);
161
		}
162
163
		protected void fireInputChange() {
164
			((TestDiffNode) getCompareResult()).fireChange();
165
166
		}
167
168
		public void saveChanges(IProgressMonitor monitor) throws CoreException {
169
			super.saveChanges(monitor);
170
		}
171
172
	}
173
174
	private TextMergeViewer viewer;
175
176
	public void testDirtyFlagOnStandardLeft() throws CoreException,
177
			InvocationTargetException, InterruptedException,
178
			IllegalArgumentException, SecurityException,
179
			IllegalAccessException, NoSuchFieldException,
180
			NoSuchMethodException, IOException {
181
		IProject project = ResourcesPlugin.getWorkspace().getRoot()
182
				.getProject("Project_" + System.currentTimeMillis());
183
		project.create(null);
184
		project.open(null);
185
186
		String fileContents1 = "FileContents";
187
		String appendFileContents = "_append";
188
		String fileContents2 = "FileContents2";
189
190
		IFile file1 = project.getFile("File1_" + System.currentTimeMillis()
191
				+ ".txt");
192
		file1.create(new ByteArrayInputStream(fileContents1.getBytes()), true,
193
				null);
194
195
		IFile file2 = project.getFile("File2_" + System.currentTimeMillis()
196
				+ ".txt");
197
		file2.create(new ByteArrayInputStream(fileContents2.getBytes()), true,
198
				null);
199
200
		LocalResourceTypedElement el1 = (LocalResourceTypedElement) SaveableCompareEditorInput
201
				.createFileElement(file1);
202
		ITypedElement el2 = new FileElement(file2);
203
204
		CompareConfiguration conf = new CompareConfiguration();
205
		conf.setLeftEditable(true);
206
		TestSaveableEditorInputLocal compareEditorInput = new TestSaveableEditorInputLocal(
207
				el1, el2, conf);
208
209
		final TestSaveableEditorInputLocal[] editorInputs = { compareEditorInput };
210
		compareEditorInput.prepareCompareInput(null);
211
212
		Shell shell = PlatformUI.getWorkbench().getActiveWorkbenchWindow()
213
				.getShell();
214
215
		Dialog dialog = new Dialog(shell) {
216
			protected Control createDialogArea(Composite parent) {
217
				Composite composite = (Composite) super
218
						.createDialogArea(parent);
219
				viewer = (TextMergeViewer) editorInputs[0].findContentViewer(
220
						null, editorInputs[0].input, composite);
221
				viewer.setInput(editorInputs[0].getCompareResult());
222
				return composite;
223
			}
224
		};
225
		dialog.setBlockOnOpen(false);
226
		dialog.open();
227
228
		MergeSourceViewer left = (MergeSourceViewer) ReflectionUtils.getField(
229
				viewer, "fLeft");
230
231
		StyledText leftText = left.getSourceViewer().getTextWidget();
232
233
		// modify the left side of editor
234
		leftText.append(appendFileContents);
235
236
		assertTrue(compareEditorInput.isDirty());
237
238
		// save editor
239
		viewer.flush(null);
240
241
		assertFalse(compareEditorInput.isDirty());
242
243
		dialog.close();
244
245
		// check weather file was saved
246
247
		BufferedReader reader = new BufferedReader(new InputStreamReader(
248
				file1.getContents()));
249
		String line = reader.readLine();
250
251
		assertEquals(fileContents1 + appendFileContents, line);
252
253
	}
254
255
	public void testDirtyFlagOnCustomLeft() throws CoreException,
256
			InvocationTargetException, InterruptedException,
257
			IllegalArgumentException, SecurityException,
258
			IllegalAccessException, NoSuchFieldException,
259
			NoSuchMethodException, IOException {
260
		IProject project = ResourcesPlugin.getWorkspace().getRoot()
261
				.getProject("Project_" + System.currentTimeMillis());
262
		project.create(null);
263
		project.open(null);
264
265
		String fileContents1 = "FileContents";
266
		String appendFileContents = "_append";
267
		String fileContents2 = "FileContents2";
268
269
		IFile file1 = project.getFile("File1_" + System.currentTimeMillis()
270
				+ ".txt");
271
		file1.create(new ByteArrayInputStream(fileContents1.getBytes()), true,
272
				null);
273
274
		IFile file2 = project.getFile("File2_" + System.currentTimeMillis()
275
				+ ".txt");
276
		file2.create(new ByteArrayInputStream(fileContents2.getBytes()), true,
277
				null);
278
279
		ITypedElement el1 = new FileElement(file1);
280
		ITypedElement el2 = new FileElement(file2);
281
282
		CompareConfiguration conf = new CompareConfiguration();
283
		conf.setLeftEditable(true);
284
		TestSaveableEditorInputLocal compareEditorInput = new TestSaveableEditorInputLocal(
285
				el1, el2, conf);
286
287
		final TestSaveableEditorInputLocal[] editorInputs = { compareEditorInput };
288
		compareEditorInput.prepareCompareInput(null);
289
290
		Shell shell = PlatformUI.getWorkbench().getActiveWorkbenchWindow()
291
				.getShell();
292
293
		Dialog dialog = new Dialog(shell) {
294
			protected Control createDialogArea(Composite parent) {
295
				Composite composite = (Composite) super
296
						.createDialogArea(parent);
297
				viewer = (TextMergeViewer) editorInputs[0].findContentViewer(
298
						null, editorInputs[0].input, composite);
299
				viewer.setInput(editorInputs[0].getCompareResult());
300
				return composite;
301
			}
302
		};
303
		dialog.setBlockOnOpen(false);
304
		dialog.open();
305
306
		MergeSourceViewer left = (MergeSourceViewer) ReflectionUtils.getField(
307
				viewer, "fLeft");
308
309
		StyledText leftText = left.getSourceViewer().getTextWidget();
310
311
		leftText.append(appendFileContents);
312
313
		assertTrue(compareEditorInput.isDirty());
314
315
		viewer.flush(null);
316
317
		assertFalse(compareEditorInput.isDirty());
318
319
		dialog.close();
320
321
		/*
322
		 * not checking if changes were saved because in this case saving is not
323
		 * handled
324
		 */
325
326
	}
327
328
	public void testBug347557() throws CoreException, IllegalArgumentException,
329
			NoSuchMethodException, IllegalAccessException,
330
			InvocationTargetException, InterruptedException, SecurityException,
331
			NoSuchFieldException {
332
		IProject project = ResourcesPlugin.getWorkspace().getRoot()
333
				.getProject("Project_" + System.currentTimeMillis());
334
		project.create(null);
335
		project.open(null);
336
337
		String fileContents1 = "FileContents";
338
		String appendFileContents = "_append";
339
		String fileContents2 = "FileContents2";
340
341
		IFile file1 = project.getFile("File1_" + System.currentTimeMillis()
342
				+ ".txt");
343
		file1.create(new ByteArrayInputStream(fileContents1.getBytes()), true,
344
				null);
345
346
		IFile file2 = project.getFile("File2_" + System.currentTimeMillis()
347
				+ ".txt");
348
		file2.create(new ByteArrayInputStream(fileContents2.getBytes()), true,
349
				null);
350
351
		ITypedElement el1 = new FileElement(file1);
352
		ITypedElement el2 = new FileElement(file2);
353
354
		CompareConfiguration conf = new CompareConfiguration();
355
		conf.setLeftEditable(true);
356
		TestSaveableEditorInputLocal compareEditorInput = new TestSaveableEditorInputLocal(
357
				el1, el2, conf);
358
		compareEditorInput.prepareCompareInput(null);
359
360
		Shell shell = PlatformUI.getWorkbench().getActiveWorkbenchWindow()
361
				.getShell();
362
363
		viewer = (TextMergeViewer) compareEditorInput.findContentViewer(null,
364
				compareEditorInput.input, shell);
365
		viewer.setInput(compareEditorInput.getCompareResult());
366
367
		// get listeners list
368
		final ListenerList listenerList = (ListenerList) ReflectionUtils
369
				.getField(viewer, "fListenerList", true);
370
371
		final PropertyChangeEvent event = new PropertyChangeEvent(viewer,
372
				CompareEditorInput.DIRTY_STATE, null, Boolean.TRUE);
373
374
		// Notify all the listeners about dirty property change
375
		Object[] listeners = listenerList.getListeners();
376
		for (int i = 0; i < listeners.length; i++) {
377
			final IPropertyChangeListener listener = (IPropertyChangeListener) listeners[i];
378
			SafeRunner.run(new ISafeRunnable() {
379
				public void run() throws Exception {
380
					listener.propertyChange(event);
381
				}
382
383
				public void handleException(Throwable exception) {
384
					fail(exception.getMessage());
385
				}
386
			});
387
		}
388
389
	}
390
}
(-)src/org/eclipse/team/internal/ui/synchronize/LocalResourceSaveableComparison.java (-4 / +4 lines)
Lines 247-256 Link Here
247
	 */
247
	 */
248
	public String getName() {
248
	public String getName() {
249
		// Return the name of the file element as held in the compare input
249
		// Return the name of the file element as held in the compare input
250
		if (fileElement.equals(input.getLeft())) {
250
		if (input.getLeft().equals(fileElement)) {
251
			return input.getLeft().getName();
251
			return input.getLeft().getName();
252
		}
252
		}
253
		if (fileElement.equals(input.getRight())) {
253
		if (input.getRight().equals(fileElement)) {
254
			return input.getRight().getName();
254
			return input.getRight().getName();
255
		}
255
		}
256
		// Fallback call returning name of the main non-null element of the input
256
		// Fallback call returning name of the main non-null element of the input
Lines 288-301 Link Here
288
288
289
			ContentMergeViewer cmv = (ContentMergeViewer) e.getSource();
289
			ContentMergeViewer cmv = (ContentMergeViewer) e.getSource();
290
290
291
			if (fileElement.equals(input.getLeft())) {
291
			if (input.getLeft().equals(fileElement)) {
292
				if (changed && cmv.internalIsLeftDirty())
292
				if (changed && cmv.internalIsLeftDirty())
293
					setDirty(changed);
293
					setDirty(changed);
294
				else if (!changed && !cmv.internalIsLeftDirty()) {
294
				else if (!changed && !cmv.internalIsLeftDirty()) {
295
					setDirty(changed);
295
					setDirty(changed);
296
				}
296
				}
297
			}
297
			}
298
			if (fileElement.equals(input.getRight())) {
298
			if (input.getRight().equals(fileElement)) {
299
				if (changed && cmv.internalIsRightDirty())
299
				if (changed && cmv.internalIsRightDirty())
300
					setDirty(changed);
300
					setDirty(changed);
301
				else if (!changed && !cmv.internalIsRightDirty()) {
301
				else if (!changed && !cmv.internalIsRightDirty()) {

Return to bug 347557