KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > eclipse > compare > internal > patch > Diff


1 /*******************************************************************************
2  * Copyright (c) 2000, 2005 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.internal.patch;
12
13 import java.util.ArrayList JavaDoc;
14 import java.util.Iterator JavaDoc;
15 import java.util.List JavaDoc;
16
17 import org.eclipse.compare.internal.CompareUIPlugin;
18 import org.eclipse.compare.structuremergeviewer.Differencer;
19 import org.eclipse.core.resources.IFile;
20 import org.eclipse.core.runtime.IAdaptable;
21 import org.eclipse.core.runtime.IPath;
22 import org.eclipse.jface.resource.ImageDescriptor;
23 import org.eclipse.osgi.util.NLS;
24 import org.eclipse.ui.model.IWorkbenchAdapter;
25
26 public class Diff implements IWorkbenchAdapter, IAdaptable {
27
28     IPath fOldPath, fNewPath;
29     long fOldDate, fNewDate; // if 0: no file
30
List JavaDoc fHunks= new ArrayList JavaDoc();
31     boolean fMatches= false;
32     private boolean fIsEnabled2= true;
33     String JavaDoc fRejected;
34     DiffProject fProject; //the project that contains this diff
35
boolean fDiffProblem;
36     String JavaDoc fErrorMessage;
37     int fStrip;
38     int fFuzzFactor;
39
40     static ImageDescriptor addId= CompareUIPlugin.getImageDescriptor("ovr16/add_ov.gif"); //$NON-NLS-1$
41
static ImageDescriptor delId= CompareUIPlugin.getImageDescriptor("ovr16/del_ov.gif"); //$NON-NLS-1$
42
private WorkspacePatcher patcher;
43     
44     /* package */ Diff(IPath oldPath, long oldDate, IPath newPath, long newDate) {
45         fOldPath= oldPath;
46         fOldDate= oldPath == null ? 0 : oldDate;
47         fNewPath= newPath;
48         fNewDate= newPath == null ? 0 : newDate;
49     }
50     
51     boolean isEnabled() {
52         return fIsEnabled2;
53     }
54     
55     void setEnabled(boolean b) {
56         fIsEnabled2= b;
57     }
58     
59     void reverse() {
60         IPath tp= fOldPath;
61         fOldPath= fNewPath;
62         fNewPath= tp;
63         
64         long t= fOldDate;
65         fOldDate= fNewDate;
66         fNewDate= t;
67         
68         Iterator JavaDoc iter= fHunks.iterator();
69         while (iter.hasNext()) {
70             Hunk hunk= (Hunk) iter.next();
71             hunk.reverse();
72         }
73     }
74     
75     Hunk[] getHunks() {
76         return (Hunk[]) fHunks.toArray(new Hunk[fHunks.size()]);
77     }
78
79     IPath getPath() {
80         if (fOldPath != null)
81             return fOldPath;
82         return fNewPath;
83     }
84     
85     void finish() {
86         if (fHunks.size() == 1) {
87             Hunk h= (Hunk) fHunks.get(0);
88             if (h.fNewLength == 0) {
89                 fNewDate= 0;
90                 fNewPath= fOldPath;
91             }
92         }
93     }
94     
95     /* package */ void add(Hunk hunk) {
96         fHunks.add(hunk);
97     }
98     
99     /* package */ int getType() {
100         if (fOldDate == 0)
101             return Differencer.ADDITION;
102         if (fNewDate == 0)
103             return Differencer.DELETION;
104         return Differencer.CHANGE;
105     }
106     
107     /* package */ String JavaDoc getDescription(int strip) {
108         IPath path= getStrippedPath(strip);
109         return path.toOSString();
110     }
111
112     private IPath getStrippedPath(int strip) {
113         IPath path= fOldPath;
114         if (fOldDate == 0)
115             path= fNewPath;
116         if (strip > 0 && strip < path.segmentCount())
117             path= path.removeFirstSegments(strip);
118         return path;
119     }
120
121     DiffProject getProject() {
122         return fProject;
123     }
124
125     public void setProject(DiffProject diffProject) {
126         this.fProject= diffProject;
127         fProject.addDiff(this);
128     }
129     
130     /**
131      * Resets the state of this diff to {no matches, no problems} and checks to see what hunks contained
132      * by this Diff can actually be applied
133      * @param wspatcher
134      * @param strip
135      * @param fuzzfactor
136      * @return ArrayList containing which hunks contained by this diff can be checked
137      */

138     ArrayList JavaDoc reset(WorkspacePatcher wspatcher, int strip, int fuzzfactor) {
139         //reset state - no matches, no problems
140
this.fMatches= false;
141         this.fDiffProblem= false;
142         this.fStrip= strip;
143         this.fFuzzFactor= fuzzfactor;
144         this.patcher= wspatcher;
145         //Make sure that the file that contains this diff exists and is modifiable
146
ArrayList JavaDoc failedHunks= checkForFileExistance();
147         ArrayList JavaDoc hunksToCheck= new ArrayList JavaDoc();
148         //Ensure that, for workspace patches, the containing project exists in the workspace
149
boolean projectExistsInWorkspace=true;
150         if (fProject != null){
151             projectExistsInWorkspace = fProject.getProject().exists();
152         }
153         //Verify if any of the hunks have failed, and reset the state of each hunk
154
//accordingly
155
for (Iterator JavaDoc iter= fHunks.iterator(); iter.hasNext();) {
156             Hunk hunk= (Hunk) iter.next();
157             boolean hunkFailed= failedHunks.contains(hunk);
158             //if any hunk has failed we have to alter this Diff's fMatches field
159
if (hunkFailed)
160                 this.fMatches= false;
161             hunk.reset(hunkFailed);
162             //If the hunk can be applied and the project exists in the workspace and
163
//there are no problems with the hunk's containing diff, then check the hunk
164
if (!hunkFailed && projectExistsInWorkspace && !fDiffProblem)
165                 hunksToCheck.add(hunk);
166         }
167         return hunksToCheck;
168     }
169
170     /**
171      * Checks to see:
172      * 1) if the target file specified in fNewPath exists and is patchable
173      * 2) which hunks contained by this diff can be catually applied to the file
174      * @return a list containg the hunks that could not be applied
175      */

176     private ArrayList JavaDoc checkForFileExistance() {
177         IFile file= getTargetFile();
178         boolean create= false;
179         //If this diff is an addition, make sure that it doesn't already exist
180
if (getType() == Differencer.ADDITION) {
181             if (file == null || !file.exists()) {
182                 fMatches= true;
183             } else {
184                 // file already exists
185
fDiffProblem= true;
186                 fErrorMessage= PatchMessages.PreviewPatchPage_FileExists_error;
187             }
188             create= true;
189         } else { //This diff is not an addition, try to find a match for it
190
//Ensure that the file described by the path exists and is modifiable
191
if (file != null) {
192                 fMatches= true;
193             } else {
194                 // file doesn't exist
195
fDiffProblem= true;
196                 fErrorMessage= PatchMessages.PreviewPatchPage_FileDoesNotExist_error;
197             }
198         }
199
200         ArrayList JavaDoc failedHunks= new ArrayList JavaDoc();
201         patcher.setFuzz(fFuzzFactor);
202         //If this diff has no problems discovered so far, try applying the patch
203
if (!fDiffProblem)
204             patcher.apply(this, file, create, failedHunks);
205
206         if (failedHunks.size() > 0)
207             fRejected= patcher.getRejected(failedHunks);
208
209         return failedHunks;
210     }
211
212     public WorkspacePatcher getPatcher() {
213         return patcher;
214     }
215
216     public IFile getTargetFile() {
217         if (fProject != null)
218             return fProject.getFile(getStrippedPath(fStrip));
219         return getPatcher().existsInTarget(getStrippedPath(fStrip));
220     }
221
222     //IWorkbenchAdapter methods
223
public Object JavaDoc[] getChildren(Object JavaDoc o) {
224         return fHunks.toArray();
225     }
226
227     public ImageDescriptor getImageDescriptor(Object JavaDoc object) {
228         if (object instanceof Diff) {
229             Diff diff= (Diff) object;
230             switch (diff.getType()) {
231                 case Differencer.ADDITION :
232                     return addId;
233                 case Differencer.DELETION :
234                     return delId;
235             }
236         }
237         return null;
238     }
239
240     public String JavaDoc getLabel(Object JavaDoc o) {
241         String JavaDoc label= getDescription(fStrip);
242         if (this.fDiffProblem)
243             return NLS.bind(PatchMessages.Diff_2Args, new String JavaDoc[] {label, fErrorMessage});
244         return label;
245     }
246
247     public Object JavaDoc getParent(Object JavaDoc o) {
248         return fProject;
249     }
250
251     //IAdaptable methods
252
public Object JavaDoc getAdapter(Class JavaDoc adapter) {
253         if (adapter == IWorkbenchAdapter.class)
254             return this;
255         return null;
256     }
257     
258     protected boolean getDiffProblem() {
259         return fDiffProblem;
260     }
261
262     /**
263      * Returns whether this Diff has any problems
264      * @return true if this Diff or any of its children Hunks have a problem, false if it doesn't
265      */

266     protected boolean containsProblems() {
267
268         if (fDiffProblem)
269             return true;
270
271         for (Iterator JavaDoc iter = fHunks.iterator(); iter.hasNext();) {
272             Hunk element = (Hunk) iter.next();
273             if (element.getHunkProblem()) {
274                 return true;
275             }
276         }
277         return false;
278     }
279
280 }
281
282
Popular Tags