KickJava   Java API By Example, From Geeks To Geeks.

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


1 /*******************************************************************************
2  * Copyright (c) 2006, 2007 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.*;
14
15 import org.eclipse.compare.patch.*;
16 import org.eclipse.compare.structuremergeviewer.Differencer;
17 import org.eclipse.core.resources.IStorage;
18 import org.eclipse.core.runtime.*;
19
20 /**
21  * A file diff represents a set of hunks that were associated with the
22  * same path in a patch file.
23  */

24 public class FileDiff implements IFilePatch {
25
26     private IPath fOldPath, fNewPath;
27     private List fHunks= new ArrayList();
28     private DiffProject fProject; //the project that contains this diff
29
private String JavaDoc header;
30     
31     /**
32      * Create a file diff for the given path and date information.
33      * @param oldPath the path of the before state of the file
34      * @param oldDate the timestamp of the before state
35      * @param newPath the path of the after state
36      * @param newDate the timestamp of the after state
37      */

38     protected FileDiff(IPath oldPath, long oldDate, IPath newPath, long newDate) {
39         fOldPath= oldPath;
40         fNewPath= newPath;
41     }
42     
43     /**
44      * Return the parent project or <code>null</code> if there isn't one.
45      * @return the parent project or <code>null</code>
46      */

47     public DiffProject getProject() {
48         return fProject;
49     }
50     
51     /**
52      * Set the project of this diff to the given project.
53      * This method should only be called from
54      * {@link DiffProject#add(FileDiff)}
55      * @param diffProject the parent project
56      */

57     void setProject(DiffProject diffProject) {
58         if (fProject == diffProject)
59             return;
60         if (fProject != null)
61             fProject.remove(this);
62         this.fProject= diffProject;
63     }
64     
65     /**
66      * Get the path of the file diff.
67      * @param reverse whether the path of the before state or after state
68      * should be used
69      * @return the path of the file diff
70      */

71     protected IPath getPath(boolean reverse) {
72         if (getDiffType(reverse) == Differencer.ADDITION) {
73             if (reverse)
74                 return fOldPath;
75             return fNewPath;
76         }
77         if (reverse && fNewPath != null)
78             return fNewPath;
79         if (fOldPath != null)
80             return fOldPath;
81         return fNewPath;
82     }
83     
84     /**
85      * Add the hunk to this file diff.
86      * @param hunk the hunk
87      */

88     protected void add(Hunk hunk) {
89         fHunks.add(hunk);
90         hunk.setParent(this);
91     }
92     
93     /**
94      * Remove the hunk from this file diff
95      * @param hunk the hunk
96      */

97     protected void remove(Hunk hunk) {
98         fHunks.remove(hunk);
99     }
100     
101     /**
102      * Return the hunks associated with this file diff.
103      * @return the hunks associated with this file diff
104      */

105     public Hunk[] getHunks() {
106         return (Hunk[]) fHunks.toArray(new Hunk[fHunks.size()]);
107     }
108     
109     /**
110      * Return the number of hunks associated with this file diff.
111      * @return the number of hunks associated with this file diff
112      */

113     public int getHunkCount() {
114         return fHunks.size();
115     }
116     
117     /**
118      * Return the difference type of this file diff.
119      * @param reverse whether the patch is being reversed
120      * @return the type of this file diff
121      */

122     public int getDiffType(boolean reverse) {
123         if (fHunks.size() == 1) {
124             boolean add = false;
125             boolean delete = false;
126             Iterator iter = fHunks.iterator();
127             while (iter.hasNext()){
128                 Hunk hunk = (Hunk) iter.next();
129                 int type =hunk.getHunkType(reverse);
130                 if (type == Hunk.ADDED){
131                     add = true;
132                 } else if (type == Hunk.DELETED ){
133                     delete = true;
134                 }
135             }
136             if (add && !delete){
137                 return Differencer.ADDITION;
138             } else if (!add && delete){
139                 return Differencer.DELETION;
140             }
141         }
142         return Differencer.CHANGE;
143     }
144     
145     /**
146      * Return the path of this file diff with the specified number
147      * of leading segments striped.
148      * @param strip the number of leading segments to strip from the path
149      * @param reverse whether the patch is being reversed
150      * @return the path of this file diff with the specified number
151      * of leading segments striped
152      */

153     protected IPath getStrippedPath(int strip, boolean reverse) {
154         IPath path= getPath(reverse);
155         if (strip > 0 && strip < path.segmentCount())
156             path= path.removeFirstSegments(strip);
157         return path;
158     }
159     
160     /**
161      * Return the segment count of the path of this file diff.
162      * @return the segment count of the path of this file diff
163      */

164     public int segmentCount() {
165         //Update prefix count - go through all of the diffs and find the smallest
166
//path segment contained in all diffs.
167
int length= 99;
168         if (fOldPath != null)
169             length= Math.min(length, fOldPath.segmentCount());
170         if (fNewPath != null)
171             length= Math.min(length, fNewPath.segmentCount());
172         return length;
173     }
174
175     public IFilePatchResult apply(IStorage contents,
176             PatchConfiguration configuration, IProgressMonitor monitor) {
177         FileDiffResult result = new FileDiffResult(this, configuration);
178         result.refresh(contents, monitor);
179         return result;
180     }
181
182     public IPath getTargetPath(PatchConfiguration configuration) {
183         return getStrippedPath(configuration.getPrefixSegmentStripCount(), configuration.isReversed());
184     }
185
186     public FileDiff asRelativeDiff() {
187         if (fProject == null)
188             return this;
189         IPath adjustedOldPath = null;
190         if (fOldPath != null) {
191             adjustedOldPath = new Path(null, fProject.getName()).append(fOldPath);
192         }
193         IPath adjustedNewPath = null;
194         if (fNewPath != null) {
195             adjustedNewPath = new Path(null, fProject.getName()).append(fNewPath);
196         }
197         FileDiff diff = new FileDiff(adjustedOldPath, 0, adjustedNewPath, 0);
198         for (Iterator iterator = fHunks.iterator(); iterator.hasNext();) {
199             Hunk hunk = (Hunk) iterator.next();
200             // Creating the hunk adds it to the parent diff
201
new Hunk(diff, hunk);
202         }
203         return diff;
204     }
205
206     public void setHeader(String JavaDoc header) {
207         this.header = header;
208     }
209
210     public String JavaDoc getHeader() {
211         return header;
212     }
213 }
214
Popular Tags