Skip to main content
summaryrefslogtreecommitdiffstats
blob: 2008989ce1aa7566dfade4eaec45a8e2da3f725c (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
/*
 * (c) Copyright IBM Corp. 2000, 2001.
 * All Rights Reserved.
 */
package org.eclipse.compare.patch;

import java.io.*;
import java.io.ByteArrayInputStream;
import java.text.MessageFormat;
import java.lang.reflect.InvocationTargetException;

import org.eclipse.swt.graphics.Image;

import org.eclipse.core.runtime.*;
import org.eclipse.core.resources.*;

import org.eclipse.jface.viewers.ISelection;

import org.eclipse.compare.*;
import org.eclipse.compare.structuremergeviewer.*;
import org.eclipse.compare.internal.*;


/* package */ class PatchCompareInput extends CompareEditorInput {
		
	private String fPatchName;
	private DiffNode fRoot;
	private IResource fResource;
	private Diff[] fDiffs;

	
	/**
	 * Creates an compare editor input for the given selection.
	 */
	/* package */ PatchCompareInput(CompareConfiguration config, ISelection s, Diff[] diffs, String patchName) {
		super(config);
		IResource[] selection= Utilities.getResources(s);
		if (selection.length == 1)
			fResource= selection[0];		
		fDiffs= diffs;
		fPatchName= patchName;
	}
	
	/**
	 * Performs a two-way or three-way diff on the current selection.
	 */
	public Object prepareInput(IProgressMonitor pm) throws InvocationTargetException {
						
		CompareConfiguration cc= (CompareConfiguration) getCompareConfiguration();
		
		try {				
			pm.beginTask(Utilities.getString("ResourceCompare.taskName"), fDiffs.length); //$NON-NLS-1$
		
			fRoot= new DiffNode(0);
			IContainer rootFolder= null;
			if (fResource instanceof IContainer)
				rootFolder= (IContainer) fResource;
			
			// process diffs
			for (int i= 0; i < fDiffs.length; i++) {
				Diff diff= fDiffs[i];
				
				// strip of first component
				String path= diff.fOldName;
				int pos= path.indexOf('/');
				if (pos >= 0)
					path= path.substring(pos+1);
				
				createPath(fRoot, rootFolder, path, diff);
				pm.worked(1);
			}			
			
			fResource.refreshLocal(IResource.DEPTH_INFINITE, pm);
			
			String leftLabel= fResource.getName();
			cc.setLeftLabel(leftLabel);
			cc.setLeftImage(CompareUIPlugin.getImage(fResource));
			
			String rightLabel= "Patch: " + fPatchName;
			cc.setRightLabel(rightLabel);
			//cc.setRightImage(CompareUIPlugin.getImage(fRightResource));
			
			String format= Utilities.getString("ResourceCompare.twoWay.title"); //$NON-NLS-1$
			String title= MessageFormat.format(format, new String[] {leftLabel, rightLabel} );
			setTitle(title);

			return fRoot;
			
		} catch (CoreException ex) {
			throw new InvocationTargetException(ex);
		} finally {
			pm.done();
		}
	}
	
	public void saveChanges(IProgressMonitor pm) throws CoreException {
		if (fRoot instanceof DiffNode) {
			try {
				commit(pm, (DiffNode) fRoot);
			} finally {	
				setDirty(false);
			}
		}
	}
	
	/*
	 * Recursively walks the diff tree and commits all changes.
	 */
	private static void commit(IProgressMonitor pm, DiffNode node) throws CoreException {
		
		ITypedElement left= node.getLeft();
		if (left instanceof BufferedResourceNode)
			((BufferedResourceNode) left).commit(pm);
			
		ITypedElement right= node.getRight();
		if (right instanceof BufferedResourceNode)
			((BufferedResourceNode) right).commit(pm);

		IDiffElement[] children= node.getChildren();
		if (children != null) {
			for (int i= 0; i < children.length; i++) {
				IDiffElement element= children[i];
				if (element instanceof DiffNode)
					commit(pm, (DiffNode) element);
			}
		}
	}

	/* package */ void createPath(DiffContainer root, IContainer folder, String path, Diff diff) {
		int pos= path.indexOf('/');
		if (pos >= 0) {
			String dir= path.substring(0, pos);
			IFolder f= folder.getFolder(new Path(dir));
			IDiffElement child= root.findChild(dir);
			if (child == null) {
				ResourceNode rn= new ResourceNode(f);
				child= new DiffNode(root, Differencer.CHANGE, null, rn, rn);
			}
			if (child instanceof DiffContainer)
				createPath((DiffContainer)child, f, path.substring(pos+1), diff);
		} else {
			// leaf
			IFile file= folder.getFile(new Path(path));
			BufferedResourceNode rn= new BufferedResourceNode(file);			
			
			new DiffNode(root, diff.getType(), null, rn, new PatchedResource(rn, diff, path));
		}
	}
}


Back to the top