1 11 package org.eclipse.compare.internal.patch; 12 13 import java.io.*; 14 import java.util.*; 15 16 import org.eclipse.compare.internal.CompareUIPlugin; 17 import org.eclipse.compare.internal.Utilities; 18 import org.eclipse.compare.patch.*; 19 import org.eclipse.compare.structuremergeviewer.Differencer; 20 import org.eclipse.core.resources.*; 21 import org.eclipse.core.runtime.*; 22 import org.eclipse.osgi.util.NLS; 23 24 public class FileDiffResult implements IFilePatchResult { 25 26 private FileDiff fDiff; 27 private boolean fMatches= false; 28 private boolean fDiffProblem; 29 private String fErrorMessage; 30 private Map fHunkResults = new HashMap(); 31 private List fBeforeLines, fAfterLines; 32 private final PatchConfiguration configuration; 33 private String charset; 34 private int fuzz; 35 36 public FileDiffResult(FileDiff diff, PatchConfiguration configuration) { 37 super(); 38 fDiff = diff; 39 this.configuration = configuration; 40 } 41 42 public PatchConfiguration getConfiguration() { 43 return configuration; 44 } 45 46 public boolean canApplyHunk(Hunk hunk) { 47 HunkResult result = getHunkResult(hunk); 48 return result.isOK() && !fDiffProblem; 49 } 50 51 61 public void refresh(IStorage storage, IProgressMonitor monitor) { 62 fMatches= false; 63 fDiffProblem= false; 64 boolean create= false; 65 charset = Utilities.getCharset(storage); 66 boolean exists = targetExists(storage); 68 if (fDiff.getDiffType(getConfiguration().isReversed()) == Differencer.ADDITION) { 69 if ((!exists || isEmpty(storage)) && canCreateTarget(storage)) { 70 fMatches= true; 71 } else { 72 fDiffProblem= true; 74 fErrorMessage= PatchMessages.PreviewPatchPage_FileExists_error; 75 } 76 create= true; 77 } else { if (exists) { 80 fMatches= true; 81 } else { 82 fDiffProblem= true; 84 fErrorMessage= PatchMessages.PreviewPatchPage_FileDoesNotExist_error; 85 } 86 } 87 88 if (fDiffProblem) { 89 fBeforeLines = new ArrayList(getLines(storage, false)); 93 fAfterLines = fMatches ? new ArrayList() : fBeforeLines; 94 Hunk[] hunks = fDiff.getHunks(); 95 for (int i = 0; i < hunks.length; i++) { 96 Hunk hunk = hunks[i]; 97 HunkResult result = getHunkResult(hunk); 98 result.setMatches(false); 99 } 100 } else { 101 patch(getLines(storage, create), monitor); 103 } 104 105 if (containsProblems()) { 106 if (fMatches) { 107 fMatches = false; 109 Hunk[] hunks = fDiff.getHunks(); 110 for (int i = 0; i < hunks.length; i++) { 111 Hunk hunk = hunks[i]; 112 HunkResult result = getHunkResult(hunk); 113 if (result.isOK()) { 114 fMatches = true; 115 break; 116 } 117 } 118 } 119 } 120 } 121 122 protected boolean canCreateTarget(IStorage storage) { 123 return true; 124 } 125 126 protected boolean targetExists(IStorage storage) { 127 return storage != null; 128 } 129 130 protected List getLines(IStorage storage, boolean create) { 131 List lines = Patcher.load(storage, create); 132 return lines; 133 } 134 135 protected boolean isEmpty(IStorage storage) { 136 if (storage == null) 137 return true; 138 return Patcher.load(storage, false).isEmpty(); 139 } 140 141 145 public void patch(List lines, IProgressMonitor monitor) { 146 fBeforeLines = new ArrayList(); 147 fBeforeLines.addAll(lines); 148 if (getConfiguration().getFuzz() == -1) { 149 fuzz = calculateFuzz(fBeforeLines, monitor); 150 } 151 int shift= 0; 152 Hunk[] hunks = fDiff.getHunks(); 153 for (int i = 0; i < hunks.length; i++) { 154 Hunk hunk = hunks[i]; 155 HunkResult result = getHunkResult(hunk); 156 result.setShift(shift); 157 if (result.patch(lines)) { 158 shift = result.getShift(); 159 } 160 } 161 fAfterLines = lines; 162 } 163 164 protected boolean getDiffProblem() { 165 return fDiffProblem; 166 } 167 168 172 protected boolean containsProblems() { 173 if (fDiffProblem) 174 return true; 175 for (Iterator iterator = fHunkResults.values().iterator(); iterator.hasNext();) { 176 HunkResult result = (HunkResult) iterator.next(); 177 if (!result.isOK()) 178 return true; 179 } 180 return false; 181 } 182 183 public String getLabel() { 184 String label= getTargetPath().toString(); 185 if (this.fDiffProblem) 186 return NLS.bind(PatchMessages.Diff_2Args, new String [] {label, fErrorMessage}); 187 return label; 188 } 189 190 public boolean hasMatches() { 191 return fMatches; 192 } 193 194 198 public List getLines() { 199 return fAfterLines; 200 } 201 202 208 public int calculateFuzz(List lines, IProgressMonitor monitor) { 209 if (monitor == null) 210 monitor = new NullProgressMonitor(); 211 fBeforeLines = new ArrayList(); 212 fBeforeLines.addAll(lines); 213 if (fDiff.getDiffType(getConfiguration().isReversed()) == Differencer.ADDITION) { 215 return -1; 218 } 219 int shift= 0; 220 int fuzz1 = 0; 221 String name = getTargetPath() != null ? getTargetPath().lastSegment() : ""; Hunk[] hunks = fDiff.getHunks(); 223 for (int j = 0; j < hunks.length; j++) { 224 Hunk h = hunks[j]; 225 monitor.subTask(NLS.bind(PatchMessages.PreviewPatchPage_GuessFuzzProgress_format, new String [] {name, Integer.toString(j + 1)})); 226 HunkResult result = getHunkResult(h); 227 result.setShift(shift); 228 int f= result.calculateFuzz(lines, monitor); 229 if (f >= 0) { 230 shift = result.getShift(); 231 } 232 if (f>fuzz1) 233 fuzz1= f; 234 monitor.worked(1); 235 } 236 fAfterLines = lines; 237 return fuzz1; 238 } 239 240 public IPath getTargetPath() { 241 return fDiff.getStrippedPath(getConfiguration().getPrefixSegmentStripCount(), getConfiguration().isReversed()); 242 } 243 244 private HunkResult getHunkResult(Hunk hunk) { 245 HunkResult result = (HunkResult)fHunkResults.get(hunk); 246 if (result == null) { 247 result = new HunkResult(this, hunk); 248 fHunkResults .put(hunk, result); 249 } 250 return result; 251 } 252 253 List getFailedHunks() { 254 List failedHunks = new ArrayList(); 255 for (Iterator iterator = fHunkResults.values().iterator(); iterator.hasNext();) { 256 HunkResult result = (HunkResult) iterator.next(); 257 if (!result.isOK()) 258 failedHunks.add(result.getHunk()); 259 } 260 return failedHunks; 261 } 262 263 private HunkResult[] getFailedHunkResults() { 264 List failedHunks = new ArrayList(); 265 for (Iterator iterator = fHunkResults.values().iterator(); iterator.hasNext();) { 266 HunkResult result = (HunkResult) iterator.next(); 267 if (!result.isOK()) 268 failedHunks.add(result); 269 } 270 return (HunkResult[]) failedHunks.toArray(new HunkResult[failedHunks.size()]); 271 } 272 273 public FileDiff getDiff() { 274 return fDiff; 275 } 276 277 List getBeforeLines() { 278 return fBeforeLines; 279 } 280 281 List getAfterLines() { 282 return fAfterLines; 283 } 284 285 public HunkResult[] getHunkResults() { 286 return (HunkResult[]) fHunkResults.values().toArray(new HunkResult[fHunkResults.size()]); 287 } 288 289 public InputStream getOriginalContents() { 290 String contents = Patcher.createString(isPreserveLineDelimeters(), getBeforeLines()); 291 return asInputStream(contents, getCharset()); 292 } 293 294 public InputStream getPatchedContents() { 295 String contents = Patcher.createString(isPreserveLineDelimeters(), getLines()); 296 return asInputStream(contents, getCharset()); 297 } 298 299 public String getCharset() { 300 return charset; 301 } 302 303 protected boolean isPreserveLineDelimeters() { 304 return false; 305 } 306 307 public IHunk[] getRejects() { 308 return getFailedHunkResults(); 309 } 310 311 public boolean hasRejects() { 312 return getFailedHunkResults().length > 0; 313 } 314 315 public static InputStream asInputStream(String contents, String charSet) { 316 byte[] bytes = null; 317 if (charSet != null) { 318 try { 319 bytes = contents.getBytes(charSet); 320 } catch (UnsupportedEncodingException e) { 321 CompareUIPlugin.log(e); 322 } 323 } 324 if (bytes == null) { 325 bytes = contents.getBytes(); 326 } 327 return new ByteArrayInputStream(bytes); 328 } 329 330 public int getFuzz() { 331 int cf = configuration.getFuzz(); 332 if (cf == -1) { 333 return fuzz; 334 } 335 return cf; 336 } 337 338 } 339 | Popular Tags |