KickJava   Java API By Example, From Geeks To Geeks.

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


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.io.InputStream JavaDoc;
14 import java.util.List JavaDoc;
15
16 import org.eclipse.compare.patch.IHunk;
17 import org.eclipse.compare.patch.PatchConfiguration;
18 import org.eclipse.core.runtime.IProgressMonitor;
19 import org.eclipse.core.runtime.OperationCanceledException;
20
21 public class HunkResult implements IHunk {
22
23     private static final boolean DEBUG= false;
24     
25     private Hunk fHunk;
26     private boolean fMatches;
27     private int fShift;
28
29     private final FileDiffResult fDiffResult;
30
31     /**
32      * Create a hunk result for the given hunk
33      * @param diffResult the parent diff result
34      * @param hunk the hunk
35      */

36     public HunkResult(FileDiffResult diffResult, Hunk hunk) {
37         fDiffResult = diffResult;
38         fHunk = hunk;
39     }
40
41     /**
42      * Try to apply the specified hunk to the given lines.
43      * If the hunk cannot be applied at the original position
44      * the methods tries fuzz lines before and after.
45      * @param lines the lines to be patched
46      * @return whether the hunk could be applied
47      */

48     public boolean patch(List JavaDoc lines) {
49         fMatches = false;
50         PatchConfiguration configuration = getConfiguration();
51         if (isEnabled(configuration)) {
52             if (fHunk.tryPatch(configuration, lines, fShift)) {
53                 fShift+= fHunk.doPatch(configuration, lines, fShift);
54                 fMatches = true;
55             } else {
56                 boolean found= false;
57                 int oldShift= fShift;
58                 
59                 for (int i= 1; i <= fDiffResult.getFuzz(); i++) {
60                     if (fHunk.tryPatch(configuration, lines, fShift-i)) {
61                         if (isAdjustShift())
62                             fShift-= i;
63                         found= true;
64                         break;
65                     }
66                 }
67                 
68                 if (! found) {
69                     for (int i= 1; i <= fDiffResult.getFuzz(); i++) {
70                         if (fHunk.tryPatch(configuration, lines, fShift+i)) {
71                             if (isAdjustShift())
72                                 fShift+= i;
73                             found= true;
74                             break;
75                         }
76                     }
77                 }
78                 
79                 if (found) {
80                     if (DEBUG) System.out.println("patched hunk at offset: " + (fShift-oldShift)); //$NON-NLS-1$
81
fShift+= fHunk.doPatch(configuration, lines, fShift);
82                     fMatches = true;
83                 }
84             }
85         }
86         return fMatches;
87     }
88
89     private boolean isAdjustShift() {
90         return true;
91     }
92
93     private PatchConfiguration getConfiguration() {
94         return getDiffResult().getConfiguration();
95     }
96
97     /**
98      * Calculate the fuzz factor that will allow the most hunks to be matched.
99      * @param lines the lines of the target file
100      * @param monitor a progress monitor
101      * @return the fuzz factor or -1 if the hunk could not be matched
102      */

103     public int calculateFuzz(List JavaDoc lines, IProgressMonitor monitor) {
104         
105         fMatches= false;
106         int fuzz = 0;
107         PatchConfiguration configuration = getConfiguration();
108         if (fHunk.tryPatch(configuration, lines, fShift)) {
109             fShift+= fHunk.doPatch(configuration, lines, fShift);
110             fMatches = true;
111         } else {
112             int hugeFuzz= lines.size(); // the maximum we need for this file
113
fuzz= -1; // not found
114

115             for (int i= 1; i <= hugeFuzz; i++) {
116                 if (monitor.isCanceled()) {
117                     throw new OperationCanceledException();
118                 }
119                 if (fHunk.tryPatch(configuration, lines, fShift-i)) {
120                     fuzz= i;
121                     if (isAdjustShift())
122                         fShift-= i;
123                     fMatches= true;
124                     break;
125                 }
126             }
127             
128             if (! fMatches) {
129                 for (int i= 1; i <= hugeFuzz; i++) {
130                     if (monitor.isCanceled()) {
131                         throw new OperationCanceledException();
132                     }
133                     if (fHunk.tryPatch(configuration, lines, fShift+i)) {
134                         fuzz= i;
135                         if (isAdjustShift())
136                             fShift+= i;
137                         fMatches= true;
138                         break;
139                     }
140                 }
141             }
142             
143             if (fMatches)
144                 fShift+= fHunk.doPatch(configuration, lines, fShift);
145         }
146         return fuzz;
147     }
148
149     /**
150      * Return the amount that this hunk should be shifted when a match with the file
151      * is attempted. The shift is needed to compensate for previous hunks that have
152      * been applied.
153      * @return the amount that this hunk should be shifted when applied
154      */

155     public int getShift() {
156         return fShift;
157     }
158
159     /**
160      * Set the amount that this hunk should be shifted when a match with the file
161      * is attempted. The shift is needed to compensate for previous hunks that have
162      * been applied.
163      * @param shift the amount to shift this hunk
164      */

165     public void setShift(int shift) {
166         fShift = shift;
167     }
168
169     /**
170      * Return the hunk to which this result applies.
171      * @return the hunk to which this result applies
172      */

173     public Hunk getHunk() {
174         return fHunk;
175     }
176
177     /**
178      * Return the parent diff result.
179      * @return the parent diff result
180      */

181     public FileDiffResult getDiffResult() {
182         return fDiffResult;
183     }
184
185     /**
186      * Return whether the hunk was matched with the target file.
187      * @return whether the hunk was matched with the target file
188      */

189     public boolean isOK() {
190         return fMatches;
191     }
192
193     /**
194      * Return the contents that should be displayed for the hunk result.
195      * @param afterState whether the after state or before state of the hunk is desired
196      * @param fullContext whether the hunk should be displayed with the entire file or
197      * only the lines in the hunk itself
198      * @return the contents to be display
199      */

200     public String JavaDoc getContents(boolean afterState, boolean fullContext) {
201         if (fullContext) {
202             boolean problemFound = false;
203             List JavaDoc lines = getDiffResult().getBeforeLines();
204             if (afterState) {
205                 if (isOK()) {
206                     int oldShift = fShift;
207                     try {
208                         fShift = 0;
209                         problemFound = !patch(lines);
210                     } finally {
211                         fShift = oldShift;
212                     }
213                 } else {
214                     problemFound = true;
215                 }
216             }
217             // Only return the full context if we could apply the hunk
218
if (!problemFound)
219                 return Patcher.createString(fDiffResult.isPreserveLineDelimeters(), lines);
220         }
221         return getHunk().getContents(afterState, getConfiguration().isReversed());
222     }
223     
224     private boolean isEnabled(PatchConfiguration configuration) {
225         Patcher patcher = Patcher.getPatcher(configuration);
226         if (patcher != null)
227             return patcher.isEnabled(fHunk);
228         return true;
229     }
230
231     public void setMatches(boolean matches) {
232         fMatches = matches;
233     }
234
235     public int getStartPosition() {
236         return fHunk.getStart(getConfiguration().isReversed()) + fShift;
237     }
238
239     public String JavaDoc getLabel() {
240         return getHunk().getDescription();
241     }
242
243     public InputStream JavaDoc getOriginalContents() {
244         String JavaDoc contents = getContents(false, false);
245         return asInputStream(contents);
246     }
247
248     protected InputStream JavaDoc asInputStream(String JavaDoc contents) {
249         String JavaDoc charSet = getCharset();
250         return FileDiffResult.asInputStream(contents, charSet);
251     }
252
253     public InputStream JavaDoc getPatchedContents() {
254         String JavaDoc contents = getContents(true, false);
255         return asInputStream(contents);
256     }
257
258     public String JavaDoc getCharset() {
259         return fDiffResult.getCharset();
260     }
261 }
262
Popular Tags