Skip to main content
aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMichael Valenta2007-01-31 17:02:30 +0000
committerMichael Valenta2007-01-31 17:02:30 +0000
commitf7531a446d4dd692983731eaa570e357b16aa2d3 (patch)
tree263d0a301e0dfb1b0c5b0f06dfade6d4ecdd776d /bundles
parent0a5a225d2889ffe9b23a5ca8faa41a762d457f82 (diff)
downloadeclipse.platform.team-f7531a446d4dd692983731eaa570e357b16aa2d3.tar.gz
eclipse.platform.team-f7531a446d4dd692983731eaa570e357b16aa2d3.tar.xz
eclipse.platform.team-f7531a446d4dd692983731eaa570e357b16aa2d3.zip
Bug 172336 [Apply Patch] Provide core level API
Diffstat (limited to 'bundles')
-rw-r--r--bundles/org.eclipse.compare/compare/org/eclipse/compare/internal/Utilities.java2
-rw-r--r--bundles/org.eclipse.compare/compare/org/eclipse/compare/internal/patch/FileDiff.java45
-rw-r--r--bundles/org.eclipse.compare/compare/org/eclipse/compare/internal/patch/FileDiffResult.java144
-rw-r--r--bundles/org.eclipse.compare/compare/org/eclipse/compare/internal/patch/Hunk.java27
-rw-r--r--bundles/org.eclipse.compare/compare/org/eclipse/compare/internal/patch/HunkDiffNode.java5
-rw-r--r--bundles/org.eclipse.compare/compare/org/eclipse/compare/internal/patch/HunkResult.java90
-rw-r--r--bundles/org.eclipse.compare/compare/org/eclipse/compare/internal/patch/HunkTypedElement.java29
-rw-r--r--bundles/org.eclipse.compare/compare/org/eclipse/compare/internal/patch/PatchCompareEditorInput.java13
-rw-r--r--bundles/org.eclipse.compare/compare/org/eclipse/compare/internal/patch/PatchDiffNode.java7
-rw-r--r--bundles/org.eclipse.compare/compare/org/eclipse/compare/internal/patch/PatchFileDiffNode.java11
-rw-r--r--bundles/org.eclipse.compare/compare/org/eclipse/compare/internal/patch/PatchFileTypedElement.java24
-rw-r--r--bundles/org.eclipse.compare/compare/org/eclipse/compare/internal/patch/PatchProjectDiffNode.java15
-rw-r--r--bundles/org.eclipse.compare/compare/org/eclipse/compare/internal/patch/PatchReader.java39
-rw-r--r--bundles/org.eclipse.compare/compare/org/eclipse/compare/internal/patch/Patcher.java117
-rw-r--r--bundles/org.eclipse.compare/compare/org/eclipse/compare/internal/patch/PreviewPatchPage2.java2
-rw-r--r--bundles/org.eclipse.compare/compare/org/eclipse/compare/internal/patch/UnmatchedHunkTypedElement.java13
-rw-r--r--bundles/org.eclipse.compare/compare/org/eclipse/compare/internal/patch/WorkspaceFileDiffResult.java53
-rw-r--r--bundles/org.eclipse.compare/compare/org/eclipse/compare/internal/patch/WorkspacePatcher.java4
-rw-r--r--bundles/org.eclipse.compare/compare/org/eclipse/compare/patch/AbstractHunk.java23
-rw-r--r--bundles/org.eclipse.compare/compare/org/eclipse/compare/patch/ApplyPatchOperation.java12
-rw-r--r--bundles/org.eclipse.compare/compare/org/eclipse/compare/patch/IFilePatch.java62
-rw-r--r--bundles/org.eclipse.compare/compare/org/eclipse/compare/patch/IFilePatchResult.java76
-rw-r--r--bundles/org.eclipse.compare/compare/org/eclipse/compare/patch/IHunk.java52
-rw-r--r--bundles/org.eclipse.compare/compare/org/eclipse/compare/patch/PatchConfiguration.java124
-rw-r--r--bundles/org.eclipse.compare/plugins/org.eclipse.compare/compare/org/eclipse/compare/internal/Utilities.java2
-rw-r--r--bundles/org.eclipse.compare/plugins/org.eclipse.compare/compare/org/eclipse/compare/internal/patch/FileDiff.java45
-rw-r--r--bundles/org.eclipse.compare/plugins/org.eclipse.compare/compare/org/eclipse/compare/internal/patch/FileDiffResult.java144
-rw-r--r--bundles/org.eclipse.compare/plugins/org.eclipse.compare/compare/org/eclipse/compare/internal/patch/Hunk.java27
-rw-r--r--bundles/org.eclipse.compare/plugins/org.eclipse.compare/compare/org/eclipse/compare/internal/patch/HunkDiffNode.java5
-rw-r--r--bundles/org.eclipse.compare/plugins/org.eclipse.compare/compare/org/eclipse/compare/internal/patch/HunkResult.java90
-rw-r--r--bundles/org.eclipse.compare/plugins/org.eclipse.compare/compare/org/eclipse/compare/internal/patch/HunkTypedElement.java29
-rw-r--r--bundles/org.eclipse.compare/plugins/org.eclipse.compare/compare/org/eclipse/compare/internal/patch/PatchCompareEditorInput.java13
-rw-r--r--bundles/org.eclipse.compare/plugins/org.eclipse.compare/compare/org/eclipse/compare/internal/patch/PatchDiffNode.java7
-rw-r--r--bundles/org.eclipse.compare/plugins/org.eclipse.compare/compare/org/eclipse/compare/internal/patch/PatchFileDiffNode.java11
-rw-r--r--bundles/org.eclipse.compare/plugins/org.eclipse.compare/compare/org/eclipse/compare/internal/patch/PatchFileTypedElement.java24
-rw-r--r--bundles/org.eclipse.compare/plugins/org.eclipse.compare/compare/org/eclipse/compare/internal/patch/PatchProjectDiffNode.java15
-rw-r--r--bundles/org.eclipse.compare/plugins/org.eclipse.compare/compare/org/eclipse/compare/internal/patch/PatchReader.java39
-rw-r--r--bundles/org.eclipse.compare/plugins/org.eclipse.compare/compare/org/eclipse/compare/internal/patch/Patcher.java117
-rw-r--r--bundles/org.eclipse.compare/plugins/org.eclipse.compare/compare/org/eclipse/compare/internal/patch/PreviewPatchPage2.java2
-rw-r--r--bundles/org.eclipse.compare/plugins/org.eclipse.compare/compare/org/eclipse/compare/internal/patch/UnmatchedHunkTypedElement.java13
-rw-r--r--bundles/org.eclipse.compare/plugins/org.eclipse.compare/compare/org/eclipse/compare/internal/patch/WorkspaceFileDiffResult.java53
-rw-r--r--bundles/org.eclipse.compare/plugins/org.eclipse.compare/compare/org/eclipse/compare/internal/patch/WorkspacePatcher.java4
-rw-r--r--bundles/org.eclipse.compare/plugins/org.eclipse.compare/compare/org/eclipse/compare/patch/AbstractHunk.java23
-rw-r--r--bundles/org.eclipse.compare/plugins/org.eclipse.compare/compare/org/eclipse/compare/patch/ApplyPatchOperation.java12
-rw-r--r--bundles/org.eclipse.compare/plugins/org.eclipse.compare/compare/org/eclipse/compare/patch/Attic/IFilePatch.java62
-rw-r--r--bundles/org.eclipse.compare/plugins/org.eclipse.compare/compare/org/eclipse/compare/patch/IFilePatch.java62
-rw-r--r--bundles/org.eclipse.compare/plugins/org.eclipse.compare/compare/org/eclipse/compare/patch/IFilePatchResult.java76
-rw-r--r--bundles/org.eclipse.compare/plugins/org.eclipse.compare/compare/org/eclipse/compare/patch/IHunk.java52
-rw-r--r--bundles/org.eclipse.compare/plugins/org.eclipse.compare/compare/org/eclipse/compare/patch/PatchConfiguration.java124
49 files changed, 1562 insertions, 478 deletions
diff --git a/bundles/org.eclipse.compare/compare/org/eclipse/compare/internal/Utilities.java b/bundles/org.eclipse.compare/compare/org/eclipse/compare/internal/Utilities.java
index 83831b7bf..3123eac35 100644
--- a/bundles/org.eclipse.compare/compare/org/eclipse/compare/internal/Utilities.java
+++ b/bundles/org.eclipse.compare/compare/org/eclipse/compare/internal/Utilities.java
@@ -623,7 +623,7 @@ public class Utilities {
}
}
- public static String getCharset(IResource resource) {
+ public static String getCharset(Object resource) {
if (resource instanceof IEncodedStorage) {
try {
return ((IEncodedStorage)resource).getCharset();
diff --git a/bundles/org.eclipse.compare/compare/org/eclipse/compare/internal/patch/FileDiff.java b/bundles/org.eclipse.compare/compare/org/eclipse/compare/internal/patch/FileDiff.java
index 90ed12228..8e0222752 100644
--- a/bundles/org.eclipse.compare/compare/org/eclipse/compare/internal/patch/FileDiff.java
+++ b/bundles/org.eclipse.compare/compare/org/eclipse/compare/internal/patch/FileDiff.java
@@ -12,18 +12,21 @@ package org.eclipse.compare.internal.patch;
import java.util.*;
+import org.eclipse.compare.patch.*;
import org.eclipse.compare.structuremergeviewer.Differencer;
-import org.eclipse.core.runtime.IPath;
+import org.eclipse.core.resources.IStorage;
+import org.eclipse.core.runtime.*;
/**
* A file diff represents a set of hunks that were associated with the
* same path in a patch file.
*/
-public class FileDiff {
+public class FileDiff implements IFilePatch {
private IPath fOldPath, fNewPath;
private List fHunks= new ArrayList();
private DiffProject fProject; //the project that contains this diff
+ private String header;
/**
* Create a file diff for the given path and date information.
@@ -168,4 +171,42 @@ public class FileDiff {
length= Math.min(length, fNewPath.segmentCount());
return length;
}
+
+ public IFilePatchResult apply(IStorage contents,
+ PatchConfiguration configuration, IProgressMonitor monitor) {
+ FileDiffResult result = new FileDiffResult(this, configuration);
+ result.refresh(contents, monitor);
+ return result;
+ }
+
+ public IPath getTargetPath(PatchConfiguration configuration) {
+ return getStrippedPath(configuration.getPrefixSegmentStripCount(), configuration.isReversed());
+ }
+
+ public FileDiff asRelativeDiff() {
+ if (fProject == null)
+ return this;
+ IPath adjustedOldPath = null;
+ if (fOldPath != null) {
+ adjustedOldPath = new Path(null, fProject.getName()).append(fOldPath);
+ }
+ IPath adjustedNewPath = null;
+ if (fNewPath != null) {
+ adjustedNewPath = new Path(null, fProject.getName()).append(fNewPath);
+ }
+ FileDiff diff = new FileDiff(adjustedOldPath, 0, adjustedNewPath, 0);
+ for (Iterator iterator = fHunks.iterator(); iterator.hasNext();) {
+ Hunk hunk = (Hunk) iterator.next();
+ diff.add(hunk);
+ }
+ return diff;
+ }
+
+ public void setHeader(String header) {
+ this.header = header;
+ }
+
+ public String getHeader() {
+ return header;
+ }
}
diff --git a/bundles/org.eclipse.compare/compare/org/eclipse/compare/internal/patch/FileDiffResult.java b/bundles/org.eclipse.compare/compare/org/eclipse/compare/internal/patch/FileDiffResult.java
index a2705ee27..c56ecddc1 100644
--- a/bundles/org.eclipse.compare/compare/org/eclipse/compare/internal/patch/FileDiffResult.java
+++ b/bundles/org.eclipse.compare/compare/org/eclipse/compare/internal/patch/FileDiffResult.java
@@ -10,30 +10,37 @@
*******************************************************************************/
package org.eclipse.compare.internal.patch;
+import java.io.*;
import java.util.*;
+import org.eclipse.compare.internal.CompareUIPlugin;
+import org.eclipse.compare.internal.Utilities;
+import org.eclipse.compare.patch.*;
import org.eclipse.compare.structuremergeviewer.Differencer;
-import org.eclipse.core.resources.IFile;
-import org.eclipse.core.resources.IProject;
-import org.eclipse.core.runtime.IProgressMonitor;
+import org.eclipse.core.resources.*;
+import org.eclipse.core.runtime.*;
import org.eclipse.osgi.util.NLS;
-public class FileDiffResult {
+public class FileDiffResult implements IFilePatchResult {
private FileDiff fDiff;
private boolean fMatches= false;
private boolean fDiffProblem;
private String fErrorMessage;
- private String fRejected;
- private Patcher fPatcher;
private Map fHunkResults = new HashMap();
private List fBeforeLines, fAfterLines;
+ private final PatchConfiguration configuration;
+ private String charset;
+ private int fuzz;
-
- public FileDiffResult(FileDiff diff, Patcher patcher) {
+ public FileDiffResult(FileDiff diff, PatchConfiguration configuration) {
super();
fDiff = diff;
- fPatcher = patcher;
+ this.configuration = configuration;
+ }
+
+ public PatchConfiguration getConfiguration() {
+ return configuration;
}
public boolean canApplyHunk(Hunk hunk) {
@@ -48,16 +55,18 @@ public class FileDiffResult {
* Checks to see:
* 1) if the target file specified in fNewPath exists and is patchable
* 2) which hunks contained by this diff can actually be applied to the file
+ * @param storage the contents being patched or <code>null</code> for an addition
+ * @param monitor a progress monitor or <code>null</code> if no progress monitoring is desired
*/
- public void refresh() {
+ public void refresh(IStorage storage, IProgressMonitor monitor) {
fMatches= false;
fDiffProblem= false;
- IFile file= getTargetFile();
boolean create= false;
+ charset = Utilities.getCharset(storage);
//If this diff is an addition, make sure that it doesn't already exist
- if (fDiff.getDiffType(getPatcher().isReversed()) == Differencer.ADDITION) {
- IProject project = fPatcher.getTargetProject(fDiff);
- if ((file == null || !file.exists() || isEmpty(file)) && project != null && project.isAccessible()) {
+ boolean exists = targetExists(storage);
+ if (fDiff.getDiffType(getConfiguration().isReversed()) == Differencer.ADDITION) {
+ if ((!exists || isEmpty(storage)) && canCreateTarget(storage)) {
fMatches= true;
} else {
// file already exists
@@ -67,7 +76,7 @@ public class FileDiffResult {
create= true;
} else { //This diff is not an addition, try to find a match for it
//Ensure that the file described by the path exists and is modifiable
- if (file != null && file.isAccessible()) {
+ if (exists) {
fMatches= true;
} else {
// file doesn't exist
@@ -89,11 +98,10 @@ public class FileDiffResult {
}
} else {
// If this diff has no problems discovered so far, try applying the patch
- apply(file, create);
+ patch(getLines(storage, create), monitor);
}
if (containsProblems()) {
- fRejected= fPatcher.getRejected(getFailedHunks());
if (fMatches) {
// Check to see if we have at least one hunk that matches
fMatches = false;
@@ -110,33 +118,35 @@ public class FileDiffResult {
}
}
- private boolean isEmpty(IFile file) {
- if (file == null || !file.exists())
- return true;
- return getPatcher().load(file, false).isEmpty();
+ protected boolean canCreateTarget(IStorage storage) {
+ return true;
}
- protected IFile getTargetFile() {
- return fPatcher.getTargetFile(fDiff);
+ protected boolean targetExists(IStorage storage) {
+ return storage != null;
}
- List apply(IFile file, boolean create) {
- List lines = fPatcher.load(file, create);
- patch(lines);
- if (fPatcher.hasCachedContents(fDiff)) {
- // TODO: We should reapply the patch to see if anything new matches
- return fPatcher.getCachedLines(fDiff);
- }
- return getLines();
+ protected List getLines(IStorage storage, boolean create) {
+ List lines = Patcher.load(storage, create);
+ return lines;
}
+ protected boolean isEmpty(IStorage storage) {
+ if (storage == null)
+ return true;
+ return Patcher.load(storage, false).isEmpty();
+ }
+
/*
* Tries to patch the given lines with the specified Diff.
* Any hunk that couldn't be applied is returned in the list failedHunks.
*/
- public void patch(List lines) {
+ public void patch(List lines, IProgressMonitor monitor) {
fBeforeLines = new ArrayList();
fBeforeLines.addAll(lines);
+ if (getConfiguration().getFuzz() == -1) {
+ fuzz = calculateFuzz(fBeforeLines, monitor);
+ }
int shift= 0;
Hunk[] hunks = fDiff.getHunks();
for (int i = 0; i < hunks.length; i++) {
@@ -170,15 +180,11 @@ public class FileDiffResult {
}
public String getLabel() {
- String label= fDiff.getStrippedPath(fPatcher.getStripPrefixSegments(), fPatcher.isReversed()).toString();
+ String label= getTargetPath().toString();
if (this.fDiffProblem)
return NLS.bind(PatchMessages.Diff_2Args, new String[] {label, fErrorMessage});
return label;
}
-
- public String isRejected() {
- return fRejected;
- }
public boolean hasMatches() {
return fMatches;
@@ -199,17 +205,19 @@ public class FileDiffResult {
* @return the fuzz factor or <code>-1</code> if no hunks could be matched
*/
public int calculateFuzz(List lines, IProgressMonitor monitor) {
+ if (monitor == null)
+ monitor = new NullProgressMonitor();
fBeforeLines = new ArrayList();
fBeforeLines.addAll(lines);
// TODO: What about deletions?
- if (fDiff.getDiffType(getPatcher().isReversed()) == Differencer.ADDITION) {
+ if (fDiff.getDiffType(getConfiguration().isReversed()) == Differencer.ADDITION) {
// Additions don't need to adjust the fuzz factor
// TODO: What about the after lines?
return -1;
}
int shift= 0;
int fuzz = 0;
- String name= fPatcher.getPath(fDiff).lastSegment();
+ String name= getTargetPath().lastSegment();
Hunk[] hunks = fDiff.getHunks();
for (int j = 0; j < hunks.length; j++) {
Hunk h = hunks[j];
@@ -227,6 +235,10 @@ public class FileDiffResult {
fAfterLines = lines;
return fuzz;
}
+
+ public IPath getTargetPath() {
+ return fDiff.getStrippedPath(getConfiguration().getPrefixSegmentStripCount(), getConfiguration().isReversed());
+ }
private HunkResult getHunkResult(Hunk hunk) {
HunkResult result = (HunkResult)fHunkResults.get(hunk);
@@ -251,10 +263,6 @@ public class FileDiffResult {
return fDiff;
}
- Patcher getPatcher() {
- return fPatcher;
- }
-
List getBeforeLines() {
return fBeforeLines;
}
@@ -266,5 +274,55 @@ public class FileDiffResult {
public HunkResult[] getHunkResults() {
return (HunkResult[]) fHunkResults.values().toArray(new HunkResult[fHunkResults.size()]);
}
+
+ public InputStream getOriginalContents() {
+ String contents = Patcher.createString(isPreserveLineDelimeters(), getBeforeLines());
+ return asInputStream(contents, getCharSet());
+ }
+
+ public InputStream getPatchedContents() {
+ String contents = Patcher.createString(isPreserveLineDelimeters(), getLines());
+ return asInputStream(contents, getCharSet());
+ }
+
+ protected String getCharSet() {
+ return charset;
+ }
+
+ protected boolean isPreserveLineDelimeters() {
+ return false;
+ }
+
+ public IHunk[] getRejects() {
+ List failedHunks = getFailedHunks();
+ return (IHunk[]) failedHunks.toArray(new IHunk[failedHunks.size()]);
+ }
+
+ public boolean hasRejects() {
+ return !getFailedHunks().isEmpty();
+ }
+
+ public static InputStream asInputStream(String contents, String charSet) {
+ byte[] bytes = null;
+ if (charSet != null) {
+ try {
+ bytes = contents.getBytes(charSet);
+ } catch (UnsupportedEncodingException e) {
+ CompareUIPlugin.log(e);
+ }
+ }
+ if (bytes == null) {
+ bytes = contents.getBytes();
+ }
+ return new ByteArrayInputStream(bytes);
+ }
+
+ public int getFuzz() {
+ int cf = configuration.getFuzz();
+ if (cf == -1) {
+ return fuzz;
+ }
+ return cf;
+ }
}
diff --git a/bundles/org.eclipse.compare/compare/org/eclipse/compare/internal/patch/Hunk.java b/bundles/org.eclipse.compare/compare/org/eclipse/compare/internal/patch/Hunk.java
index b47d71532..ad75da482 100644
--- a/bundles/org.eclipse.compare/compare/org/eclipse/compare/internal/patch/Hunk.java
+++ b/bundles/org.eclipse.compare/compare/org/eclipse/compare/internal/patch/Hunk.java
@@ -12,6 +12,7 @@ package org.eclipse.compare.internal.patch;
import java.util.List;
+import org.eclipse.compare.patch.PatchConfiguration;
import org.eclipse.core.runtime.Assert;
/**
@@ -152,8 +153,8 @@ public class Hunk {
* The parameter shift is added to the line numbers given
* in the hunk.
*/
- public boolean tryPatch(Patcher patcher, List lines, int shift) {
- boolean reverse = patcher.isReversed();
+ public boolean tryPatch(PatchConfiguration configuration, List lines, int shift) {
+ boolean reverse = configuration.isReversed();
int pos= getStart(reverse) + shift;
int deleteMatches= 0;
for (int i= 0; i < fLines.length; i++) {
@@ -165,7 +166,7 @@ public class Hunk {
while (true) {
if (pos < 0 || pos >= lines.size())
return false;
- if (linesMatch(patcher, line, (String) lines.get(pos))) {
+ if (linesMatch(configuration, line, (String) lines.get(pos))) {
pos++;
break;
}
@@ -176,7 +177,7 @@ public class Hunk {
while (true) {
if (pos < 0 || pos >= lines.size())
return false;
- if (linesMatch(patcher, line, (String) lines.get(pos))) {
+ if (linesMatch(configuration, line, (String) lines.get(pos))) {
deleteMatches++;
pos++;
break;
@@ -215,8 +216,8 @@ public class Hunk {
return fNewLength - fOldLength;
}
- int doPatch(Patcher patcher, List lines, int shift) {
- boolean reverse = patcher.isReversed();
+ int doPatch(PatchConfiguration configuration, List lines, int shift) {
+ boolean reverse = configuration.isReversed();
int pos = getStart(reverse) + shift;
for (int i= 0; i < fLines.length; i++) {
String s= fLines[i];
@@ -226,7 +227,7 @@ public class Hunk {
if (controlChar == ' ') { // context lines
while (true) {
Assert.isTrue(pos < lines.size(), "doPatch: inconsistency in context"); //$NON-NLS-1$
- if (linesMatch(patcher, line, (String) lines.get(pos))) {
+ if (linesMatch(configuration, line, (String) lines.get(pos))) {
pos++;
break;
}
@@ -236,7 +237,7 @@ public class Hunk {
// deleted lines
while (true) {
Assert.isTrue(pos < lines.size(), "doPatch: inconsistency in deleted lines"); //$NON-NLS-1$
- if (linesMatch(patcher, line, (String) lines.get(pos))) {
+ if (linesMatch(configuration, line, (String) lines.get(pos))) {
break;
}
pos++;
@@ -267,10 +268,10 @@ public class Hunk {
* Compares two strings.
* If fIgnoreWhitespace is true whitespace is ignored.
*/
- private boolean linesMatch(Patcher patcher, String line1, String line2) {
- if (patcher.isIgnoreWhitespace())
+ private boolean linesMatch(PatchConfiguration configuration, String line1, String line2) {
+ if (configuration.isIgnoreWhitespace())
return stripWhiteSpace(line1).equals(stripWhiteSpace(line2));
- if (patcher.isIgnoreLineDelimiter()) {
+ if (isIgnoreLineDelimiter()) {
int l1= Patcher.length(line1);
int l2= Patcher.length(line2);
if (l1 != l2)
@@ -280,6 +281,10 @@ public class Hunk {
return line1.equals(line2);
}
+ private boolean isIgnoreLineDelimiter() {
+ return true;
+ }
+
/*
* Returns the given string with all whitespace characters removed.
* Whitespace is defined by <code>Character.isWhitespace(...)</code>.
diff --git a/bundles/org.eclipse.compare/compare/org/eclipse/compare/internal/patch/HunkDiffNode.java b/bundles/org.eclipse.compare/compare/org/eclipse/compare/internal/patch/HunkDiffNode.java
index 178ae45ae..009efeeb6 100644
--- a/bundles/org.eclipse.compare/compare/org/eclipse/compare/internal/patch/HunkDiffNode.java
+++ b/bundles/org.eclipse.compare/compare/org/eclipse/compare/internal/patch/HunkDiffNode.java
@@ -11,6 +11,7 @@
package org.eclipse.compare.internal.patch;
import org.eclipse.compare.ITypedElement;
+import org.eclipse.compare.patch.PatchConfiguration;
import org.eclipse.compare.structuremergeviewer.Differencer;
public class HunkDiffNode extends PatchDiffNode {
@@ -50,8 +51,8 @@ public class HunkDiffNode extends PatchDiffNode {
return result;
}
- protected Patcher getPatcher() {
- return result.getDiffResult().getPatcher();
+ protected PatchConfiguration getConfiguration() {
+ return result.getDiffResult().getConfiguration();
}
public boolean isManuallyMerged() {
diff --git a/bundles/org.eclipse.compare/compare/org/eclipse/compare/internal/patch/HunkResult.java b/bundles/org.eclipse.compare/compare/org/eclipse/compare/internal/patch/HunkResult.java
index b478a006d..7124ff5cb 100644
--- a/bundles/org.eclipse.compare/compare/org/eclipse/compare/internal/patch/HunkResult.java
+++ b/bundles/org.eclipse.compare/compare/org/eclipse/compare/internal/patch/HunkResult.java
@@ -10,13 +10,15 @@
*******************************************************************************/
package org.eclipse.compare.internal.patch;
+import java.io.InputStream;
import java.util.List;
-import org.eclipse.compare.patch.AbstractHunk;
+import org.eclipse.compare.patch.IHunk;
+import org.eclipse.compare.patch.PatchConfiguration;
import org.eclipse.core.runtime.IProgressMonitor;
import org.eclipse.core.runtime.OperationCanceledException;
-public class HunkResult extends AbstractHunk {
+public class HunkResult implements IHunk {
private static final boolean DEBUG= false;
@@ -45,18 +47,18 @@ public class HunkResult extends AbstractHunk {
*/
public boolean patch(List lines) {
fMatches = false;
- Patcher patcher = getPatcher();
- if (patcher.isEnabled(fHunk)) {
- if (fHunk.tryPatch(patcher, lines, fShift)) {
- fShift+= fHunk.doPatch(patcher, lines, fShift);
+ PatchConfiguration configuration = getConfiguration();
+ if (isEnabled(configuration)) {
+ if (fHunk.tryPatch(configuration, lines, fShift)) {
+ fShift+= fHunk.doPatch(configuration, lines, fShift);
fMatches = true;
} else {
boolean found= false;
int oldShift= fShift;
- for (int i= 1; i <= patcher.getFuzz(); i++) {
- if (fHunk.tryPatch(patcher, lines, fShift-i)) {
- if (patcher.isAdjustShift())
+ for (int i= 1; i <= fDiffResult.getFuzz(); i++) {
+ if (fHunk.tryPatch(configuration, lines, fShift-i)) {
+ if (isAdjustShift())
fShift-= i;
found= true;
break;
@@ -64,9 +66,9 @@ public class HunkResult extends AbstractHunk {
}
if (! found) {
- for (int i= 1; i <= patcher.getFuzz(); i++) {
- if (fHunk.tryPatch(patcher, lines, fShift+i)) {
- if (patcher.isAdjustShift())
+ for (int i= 1; i <= fDiffResult.getFuzz(); i++) {
+ if (fHunk.tryPatch(configuration, lines, fShift+i)) {
+ if (isAdjustShift())
fShift+= i;
found= true;
break;
@@ -76,16 +78,20 @@ public class HunkResult extends AbstractHunk {
if (found) {
if (DEBUG) System.out.println("patched hunk at offset: " + (fShift-oldShift)); //$NON-NLS-1$
- fShift+= fHunk.doPatch(patcher, lines, fShift);
+ fShift+= fHunk.doPatch(configuration, lines, fShift);
fMatches = true;
}
}
}
return fMatches;
}
-
- private Patcher getPatcher() {
- return getDiffResult().getPatcher();
+
+ private boolean isAdjustShift() {
+ return true;
+ }
+
+ private PatchConfiguration getConfiguration() {
+ return getDiffResult().getConfiguration();
}
/**
@@ -98,9 +104,9 @@ public class HunkResult extends AbstractHunk {
fMatches= false;
int fuzz = 0;
- Patcher patcher = getPatcher();
- if (fHunk.tryPatch(patcher, lines, fShift)) {
- fShift+= fHunk.doPatch(patcher, lines, fShift);
+ PatchConfiguration configuration = getConfiguration();
+ if (fHunk.tryPatch(configuration, lines, fShift)) {
+ fShift+= fHunk.doPatch(configuration, lines, fShift);
fMatches = true;
} else {
int hugeFuzz= lines.size(); // the maximum we need for this file
@@ -110,9 +116,9 @@ public class HunkResult extends AbstractHunk {
if (monitor.isCanceled()) {
throw new OperationCanceledException();
}
- if (fHunk.tryPatch(patcher, lines, fShift-i)) {
+ if (fHunk.tryPatch(configuration, lines, fShift-i)) {
fuzz= i;
- if (patcher.isAdjustShift())
+ if (isAdjustShift())
fShift-= i;
fMatches= true;
break;
@@ -124,9 +130,9 @@ public class HunkResult extends AbstractHunk {
if (monitor.isCanceled()) {
throw new OperationCanceledException();
}
- if (fHunk.tryPatch(patcher, lines, fShift+i)) {
+ if (fHunk.tryPatch(configuration, lines, fShift+i)) {
fuzz= i;
- if (patcher.isAdjustShift())
+ if (isAdjustShift())
fShift+= i;
fMatches= true;
break;
@@ -135,7 +141,7 @@ public class HunkResult extends AbstractHunk {
}
if (fMatches)
- fShift+= fHunk.doPatch(patcher, lines, fShift);
+ fShift+= fHunk.doPatch(configuration, lines, fShift);
}
return fuzz;
}
@@ -210,9 +216,16 @@ public class HunkResult extends AbstractHunk {
}
// Only return the full context if we could apply the hunk
if (!problemFound)
- return getPatcher().createString(lines);
+ return Patcher.createString(fDiffResult.isPreserveLineDelimeters(), lines);
}
- return getHunk().getContents(afterState, getPatcher().isReversed());
+ return getHunk().getContents(afterState, getConfiguration().isReversed());
+ }
+
+ private boolean isEnabled(PatchConfiguration configuration) {
+ Patcher patcher = Patcher.getPatcher(configuration);
+ if (patcher != null)
+ return patcher.isEnabled(fHunk);
+ return true;
}
public void setMatches(boolean matches) {
@@ -220,6 +233,29 @@ public class HunkResult extends AbstractHunk {
}
public int getStartPosition() {
- return fHunk.getStart(getPatcher().isReversed()) + fShift;
+ return fHunk.getStart(getConfiguration().isReversed()) + fShift;
+ }
+
+ public String getLabel() {
+ return getHunk().getDescription();
+ }
+
+ public InputStream getOriginalContents() {
+ String contents = getContents(false, false);
+ return asInputStream(contents);
+ }
+
+ protected InputStream asInputStream(String contents) {
+ String charSet = getCharset();
+ return FileDiffResult.asInputStream(contents, charSet);
+ }
+
+ public InputStream getPatchedContents() {
+ String contents = getContents(true, false);
+ return asInputStream(contents);
+ }
+
+ public String getCharset() {
+ return fDiffResult.getCharSet();
}
}
diff --git a/bundles/org.eclipse.compare/compare/org/eclipse/compare/internal/patch/HunkTypedElement.java b/bundles/org.eclipse.compare/compare/org/eclipse/compare/internal/patch/HunkTypedElement.java
index a872ad884..cdc659b59 100644
--- a/bundles/org.eclipse.compare/compare/org/eclipse/compare/internal/patch/HunkTypedElement.java
+++ b/bundles/org.eclipse.compare/compare/org/eclipse/compare/internal/patch/HunkTypedElement.java
@@ -38,7 +38,7 @@ public class HunkTypedElement implements ITypedElement, IEncodedStreamContentAcc
*/
public Image getImage() {
if (!fHunkResult.isOK()) {
- LocalResourceManager imageCache = PatchCompareEditorInput.getImageCache(fHunkResult.getDiffResult().getPatcher());
+ LocalResourceManager imageCache = PatchCompareEditorInput.getImageCache(fHunkResult.getDiffResult().getConfiguration());
return getHunkErrorImage(null, imageCache, false);
}
return null;
@@ -51,21 +51,25 @@ public class HunkTypedElement implements ITypedElement, IEncodedStreamContentAcc
}
public boolean isManuallyMerged() {
- return getHunkResult().getDiffResult().getPatcher().isManuallyMerged(getHunkResult().getHunk());
+ return getPatcher().isManuallyMerged(getHunkResult().getHunk());
+ }
+
+ private Patcher getPatcher() {
+ return Patcher.getPatcher(fHunkResult.getDiffResult().getConfiguration());
}
/* (non-Javadoc)
* @see org.eclipse.compare.ITypedElement#getName()
*/
public String getName() {
- return fHunkResult.getHunk().getDescription();
+ return fHunkResult.getLabel();
}
/* (non-Javadoc)
* @see org.eclipse.compare.ITypedElement#getType()
*/
public String getType() {
- return fHunkResult.getDiffResult().getPatcher().getPath(fHunkResult.getDiffResult().getDiff()).getFileExtension();
+ return fHunkResult.getDiffResult().getDiff().getTargetPath(fHunkResult.getDiffResult().getConfiguration()).getFileExtension();
}
/* (non-Javadoc)
@@ -73,24 +77,11 @@ public class HunkTypedElement implements ITypedElement, IEncodedStreamContentAcc
*/
public InputStream getContents() throws CoreException {
String contents = fHunkResult.getContents(fIsAfterState, fFullContext);
- String charSet = getCharset();
- byte[] bytes = null;
- if (charSet != null) {
- try {
- bytes = contents.getBytes(charSet);
- } catch (UnsupportedEncodingException e) {
- CompareUIPlugin.log(e);
- }
- }
- if (bytes == null) {
- bytes = contents.getBytes();
- }
- return new ByteArrayInputStream(bytes);
+ return fHunkResult.asInputStream(contents);
}
public String getCharset() throws CoreException {
- // TODO Auto-generated method stub
- return null;
+ return fHunkResult.getCharset();
}
public HunkResult getHunkResult() {
diff --git a/bundles/org.eclipse.compare/compare/org/eclipse/compare/internal/patch/PatchCompareEditorInput.java b/bundles/org.eclipse.compare/compare/org/eclipse/compare/internal/patch/PatchCompareEditorInput.java
index 9712a7b7f..8cb2c35c1 100644
--- a/bundles/org.eclipse.compare/compare/org/eclipse/compare/internal/patch/PatchCompareEditorInput.java
+++ b/bundles/org.eclipse.compare/compare/org/eclipse/compare/internal/patch/PatchCompareEditorInput.java
@@ -4,6 +4,7 @@ import java.lang.reflect.InvocationTargetException;
import org.eclipse.compare.*;
import org.eclipse.compare.internal.*;
+import org.eclipse.compare.patch.PatchConfiguration;
import org.eclipse.compare.structuremergeviewer.*;
import org.eclipse.core.runtime.Assert;
import org.eclipse.core.runtime.IProgressMonitor;
@@ -77,14 +78,14 @@ public abstract class PatchCompareEditorInput extends CompareEditorInput {
if (element instanceof PatchDiffNode){
PatchDiffNode node = (PatchDiffNode) element;
if (!node.isEnabled() && image != null) {
- LocalResourceManager imageCache = PatchCompareEditorInput.getImageCache(getPatcher());
+ LocalResourceManager imageCache = PatchCompareEditorInput.getImageCache(getPatcher().getConfiguration());
return imageCache.createImage(createOverlay(image, CompareUIPlugin.getImageDescriptor(ICompareUIConstants.REMOVED_OVERLAY), IDecoration.TOP_LEFT));
}
}
if (element instanceof HunkDiffNode) {
HunkDiffNode node = (HunkDiffNode) element;
if (node.isManuallyMerged()) {
- LocalResourceManager imageCache = PatchCompareEditorInput.getImageCache(getPatcher());
+ LocalResourceManager imageCache = PatchCompareEditorInput.getImageCache(getPatcher().getConfiguration());
return imageCache.createImage(PatchCompareEditorInput.createOverlay(image, CompareUIPlugin.getImageDescriptor(ICompareUIConstants.IS_MERGED_OVERLAY), IDecoration.TOP_LEFT));
}
}
@@ -123,11 +124,11 @@ public abstract class PatchCompareEditorInput extends CompareEditorInput {
protected void handleDispose() {
super.handleDispose();
- getImageCache(patcher).dispose();
+ getImageCache(getPatcher().getConfiguration()).dispose();
}
- public static LocalResourceManager getImageCache(Patcher patcher) {
- return (LocalResourceManager)patcher.getProperty(IMAGE_CACHE_KEY);
+ public static LocalResourceManager getImageCache(PatchConfiguration patchConfiguration) {
+ return (LocalResourceManager)patchConfiguration.getProperty(IMAGE_CACHE_KEY);
}
protected Object prepareInput(IProgressMonitor monitor) throws InvocationTargetException, InterruptedException {
@@ -190,7 +191,7 @@ public abstract class PatchCompareEditorInput extends CompareEditorInput {
private void processProjects(DiffProject[] diffProjects) {
//create diffProject nodes
for (int i = 0; i < diffProjects.length; i++) {
- PatchProjectDiffNode projectNode = new PatchProjectDiffNode(getRoot(), diffProjects[i], getPatcher());
+ PatchProjectDiffNode projectNode = new PatchProjectDiffNode(getRoot(), diffProjects[i], getPatcher().getConfiguration());
FileDiff[] diffs = diffProjects[i].getFileDiffs();
for (int j = 0; j < diffs.length; j++) {
FileDiff fileDiff = diffs[j];
diff --git a/bundles/org.eclipse.compare/compare/org/eclipse/compare/internal/patch/PatchDiffNode.java b/bundles/org.eclipse.compare/compare/org/eclipse/compare/internal/patch/PatchDiffNode.java
index 38a83b25d..a957e4bc3 100644
--- a/bundles/org.eclipse.compare/compare/org/eclipse/compare/internal/patch/PatchDiffNode.java
+++ b/bundles/org.eclipse.compare/compare/org/eclipse/compare/internal/patch/PatchDiffNode.java
@@ -11,6 +11,7 @@
package org.eclipse.compare.internal.patch;
import org.eclipse.compare.ITypedElement;
+import org.eclipse.compare.patch.PatchConfiguration;
import org.eclipse.compare.structuremergeviewer.*;
public abstract class PatchDiffNode extends DiffNode {
@@ -36,11 +37,15 @@ public abstract class PatchDiffNode extends DiffNode {
getPatcher().setEnabled(getPatchElement(), enabled);
}
+ protected final Patcher getPatcher() {
+ return Patcher.getPatcher(getConfiguration());
+ }
+
public Object getPatchElement() {
return fElement;
}
- protected abstract Patcher getPatcher();
+ protected abstract PatchConfiguration getConfiguration();
public boolean equals(Object other) {
if (other instanceof PatchDiffNode) {
diff --git a/bundles/org.eclipse.compare/compare/org/eclipse/compare/internal/patch/PatchFileDiffNode.java b/bundles/org.eclipse.compare/compare/org/eclipse/compare/internal/patch/PatchFileDiffNode.java
index 4f3d75855..8b4b1a080 100644
--- a/bundles/org.eclipse.compare/compare/org/eclipse/compare/internal/patch/PatchFileDiffNode.java
+++ b/bundles/org.eclipse.compare/compare/org/eclipse/compare/internal/patch/PatchFileDiffNode.java
@@ -11,6 +11,7 @@
package org.eclipse.compare.internal.patch;
import org.eclipse.compare.*;
+import org.eclipse.compare.patch.PatchConfiguration;
import org.eclipse.compare.structuremergeviewer.*;
import org.eclipse.core.resources.IFile;
@@ -25,7 +26,7 @@ public class PatchFileDiffNode extends PatchDiffNode implements IContentChangeLi
private static int getKind(FileDiffResult result) {
if (!result.hasMatches())
return Differencer.NO_CHANGE;
- return result.getDiff().getDiffType(result.getPatcher().isReversed()) | Differencer.RIGHT;
+ return result.getDiff().getDiffType(result.getConfiguration().isReversed()) | Differencer.RIGHT;
}
private static ITypedElement getRightElement(FileDiffResult result) {
@@ -49,9 +50,9 @@ public class PatchFileDiffNode extends PatchDiffNode implements IContentChangeLi
public FileDiffResult getDiffResult() {
return result;
}
-
- protected Patcher getPatcher() {
- return result.getPatcher();
+
+ protected PatchConfiguration getConfiguration() {
+ return result.getConfiguration();
}
/* (non-Javadoc)
@@ -86,7 +87,7 @@ public class PatchFileDiffNode extends PatchDiffNode implements IContentChangeLi
}
public boolean fileExists() {
- IFile file = getDiffResult().getTargetFile();
+ IFile file = ((WorkspaceFileDiffResult)getDiffResult()).getTargetFile();
return file != null && file.isAccessible();
}
diff --git a/bundles/org.eclipse.compare/compare/org/eclipse/compare/internal/patch/PatchFileTypedElement.java b/bundles/org.eclipse.compare/compare/org/eclipse/compare/internal/patch/PatchFileTypedElement.java
index 3ed8ac6a7..4ea76e630 100644
--- a/bundles/org.eclipse.compare/compare/org/eclipse/compare/internal/patch/PatchFileTypedElement.java
+++ b/bundles/org.eclipse.compare/compare/org/eclipse/compare/internal/patch/PatchFileTypedElement.java
@@ -31,19 +31,19 @@ public class PatchFileTypedElement implements ITypedElement, IEncodedStreamConte
}
public Image getImage() {
- IFile file = result.getPatcher().getTargetFile(result.getDiff());
+ IFile file = getPatcher().getTargetFile(result.getDiff());
if (file == null) {
// We don't get a target file if the file doesn't exist
DiffProject project = result.getDiff().getProject();
if (project != null) {
- file = project.getFile(result.getDiff().getPath(result.getPatcher().isReversed()));
+ file = project.getFile(result.getDiff().getPath(result.getConfiguration().isReversed()));
} else {
- IResource target = result.getPatcher().getTarget();
+ IResource target = getPatcher().getTarget();
if (target instanceof IFile) {
file = (IFile) target;
} else if (target instanceof IContainer) {
IContainer container = (IContainer) target;
- file = container.getFile(result.getDiff().getStrippedPath(result.getPatcher().getStripPrefixSegments(), result.getPatcher().isReversed()));
+ file = container.getFile(result.getTargetPath());
}
}
}
@@ -52,7 +52,7 @@ public class PatchFileTypedElement implements ITypedElement, IEncodedStreamConte
image = CompareUI.getImage(file);
}
if (result.containsProblems()) {
- LocalResourceManager imageCache = PatchCompareEditorInput.getImageCache(result.getPatcher());
+ LocalResourceManager imageCache = PatchCompareEditorInput.getImageCache(result.getConfiguration());
image = HunkTypedElement.getHunkErrorImage(image, imageCache, true);
}
return image;
@@ -62,14 +62,14 @@ public class PatchFileTypedElement implements ITypedElement, IEncodedStreamConte
* @see org.eclipse.compare.ITypedElement#getName()
*/
public String getName() {
- return result.getDiff().getStrippedPath(result.getPatcher().getStripPrefixSegments(), result.getPatcher().isReversed()).toString();
+ return result.getTargetPath().toString();
}
/* (non-Javadoc)
* @see org.eclipse.compare.ITypedElement#getType()
*/
public String getType() {
- return result.getPatcher().getPath(result.getDiff()).getFileExtension();
+ return result.getTargetPath().getFileExtension();
}
public String getCharset() throws CoreException {
@@ -79,8 +79,8 @@ public class PatchFileTypedElement implements ITypedElement, IEncodedStreamConte
public InputStream getContents() throws CoreException {
// If there are cached contents, use them
- if (isAfterState && result.getPatcher().hasCachedContents(result.getDiff()))
- return new ByteArrayInputStream(result.getPatcher().getCachedContents(result.getDiff()));
+ if (isAfterState && getPatcher().hasCachedContents(result.getDiff()))
+ return new ByteArrayInputStream(getPatcher().getCachedContents(result.getDiff()));
// Otherwise, get the lines from the diff result
List lines;
if (isAfterState) {
@@ -88,7 +88,7 @@ public class PatchFileTypedElement implements ITypedElement, IEncodedStreamConte
} else {
lines = result.getBeforeLines();
}
- String contents = result.getPatcher().createString(lines);
+ String contents = Patcher.createString(getPatcher().isPreserveLineDelimeters(), lines);
String charSet = getCharset();
byte[] bytes = null;
if (charSet != null) {
@@ -104,4 +104,8 @@ public class PatchFileTypedElement implements ITypedElement, IEncodedStreamConte
return new ByteArrayInputStream(bytes);
}
+ private Patcher getPatcher() {
+ return Patcher.getPatcher(result.getConfiguration());
+ }
+
}
diff --git a/bundles/org.eclipse.compare/compare/org/eclipse/compare/internal/patch/PatchProjectDiffNode.java b/bundles/org.eclipse.compare/compare/org/eclipse/compare/internal/patch/PatchProjectDiffNode.java
index abae2df0a..663a6466a 100644
--- a/bundles/org.eclipse.compare/compare/org/eclipse/compare/internal/patch/PatchProjectDiffNode.java
+++ b/bundles/org.eclipse.compare/compare/org/eclipse/compare/internal/patch/PatchProjectDiffNode.java
@@ -12,6 +12,7 @@ package org.eclipse.compare.internal.patch;
import org.eclipse.compare.CompareUI;
import org.eclipse.compare.ITypedElement;
+import org.eclipse.compare.patch.PatchConfiguration;
import org.eclipse.compare.structuremergeviewer.*;
import org.eclipse.jface.resource.LocalResourceManager;
import org.eclipse.swt.graphics.Image;
@@ -19,12 +20,12 @@ import org.eclipse.swt.graphics.Image;
public class PatchProjectDiffNode extends PatchDiffNode {
private final DiffProject project;
- private final Patcher patcher;
+ private final PatchConfiguration configuration;
- public PatchProjectDiffNode(IDiffContainer parent, DiffProject project, Patcher patcher) {
+ public PatchProjectDiffNode(IDiffContainer parent, DiffProject project, PatchConfiguration configuration) {
super(project, parent, Differencer.NO_CHANGE);
this.project = project;
- this.patcher = patcher;
+ this.configuration = configuration;
}
/* (non-Javadoc)
@@ -40,7 +41,7 @@ public class PatchProjectDiffNode extends PatchDiffNode {
public Image getImage() {
Image image = CompareUI.getImage(project.getProject());
if (containsProblems()) {
- LocalResourceManager imageCache = PatchCompareEditorInput.getImageCache(getPatcher());
+ LocalResourceManager imageCache = PatchCompareEditorInput.getImageCache(getConfiguration());
image = HunkTypedElement.getHunkErrorImage(image, imageCache, true);
}
return image;
@@ -65,9 +66,9 @@ public class PatchProjectDiffNode extends PatchDiffNode {
public String getType() {
return ITypedElement.FOLDER_TYPE;
}
-
- protected Patcher getPatcher() {
- return patcher;
+
+ protected PatchConfiguration getConfiguration() {
+ return configuration;
}
public DiffProject getDiffProject() {
diff --git a/bundles/org.eclipse.compare/compare/org/eclipse/compare/internal/patch/PatchReader.java b/bundles/org.eclipse.compare/compare/org/eclipse/compare/internal/patch/PatchReader.java
index 547b8a2a1..82747c62c 100644
--- a/bundles/org.eclipse.compare/compare/org/eclipse/compare/internal/patch/PatchReader.java
+++ b/bundles/org.eclipse.compare/compare/org/eclipse/compare/internal/patch/PatchReader.java
@@ -146,6 +146,7 @@ public class PatchReader {
boolean reread= false;
String diffArgs= null;
String fileName= null;
+ List headerLines = new ArrayList();
// read leading garbage
reread= line!=null;
@@ -155,28 +156,31 @@ public class PatchReader {
reread= false;
if (line == null)
break;
- if (line.length() < 4)
- continue; // too short
// remember some infos
if (line.startsWith("Index: ")) { //$NON-NLS-1$
fileName= line.substring(7).trim();
- continue;
- }
- if (line.startsWith("diff")) { //$NON-NLS-1$
+ } else if (line.startsWith("diff")) { //$NON-NLS-1$
diffArgs= line.substring(4).trim();
- continue;
- }
-
- if (line.startsWith("--- ")) { //$NON-NLS-1$
+ } else if (line.startsWith("--- ")) { //$NON-NLS-1$
line= readUnifiedDiff(diffs, lr, line, diffArgs, fileName);
+ if (!headerLines.isEmpty())
+ setHeader((FileDiff)diffs.get(diffs.size() - 1), headerLines);
diffArgs= fileName= null;
reread= true;
} else if (line.startsWith("*** ")) { //$NON-NLS-1$
line= readContextDiff(diffs, lr, line, diffArgs, fileName);
+ if (!headerLines.isEmpty())
+ setHeader((FileDiff)diffs.get(diffs.size() - 1), headerLines);
diffArgs= fileName= null;
reread= true;
}
+
+ // Any lines we read here are header lines.
+ // However, if reread is set, we will add them to the header on the next pass through
+ if (!reread) {
+ headerLines.add(line);
+ }
}
lr.close();
@@ -184,6 +188,12 @@ public class PatchReader {
fDiffs = (FileDiff[]) diffs.toArray(new FileDiff[diffs.size()]);
}
+ private void setHeader(FileDiff diff, List headerLines) {
+ String header = Patcher.createString(false, headerLines);
+ diff.setHeader(header);
+ headerLines.clear();
+ }
+
/*
* Returns the next line that does not belong to this diff
*/
@@ -617,4 +627,15 @@ public class PatchReader {
public FileDiff[] getDiffs() {
return fDiffs;
}
+
+ public FileDiff[] getAdjustedDiffs() {
+ if (!isWorkspacePatch() || fDiffs.length == 0)
+ return fDiffs;
+ List result = new ArrayList();
+ for (int i = 0; i < fDiffs.length; i++) {
+ FileDiff diff = fDiffs[i];
+ result.add(diff.asRelativeDiff());
+ }
+ return (FileDiff[]) result.toArray(new FileDiff[result.size()]);
+ }
}
diff --git a/bundles/org.eclipse.compare/compare/org/eclipse/compare/internal/patch/Patcher.java b/bundles/org.eclipse.compare/compare/org/eclipse/compare/internal/patch/Patcher.java
index 2ad531618..86f23e3db 100644
--- a/bundles/org.eclipse.compare/compare/org/eclipse/compare/internal/patch/Patcher.java
+++ b/bundles/org.eclipse.compare/compare/org/eclipse/compare/internal/patch/Patcher.java
@@ -16,6 +16,7 @@ import java.util.*;
import org.eclipse.compare.internal.CompareUIPlugin;
import org.eclipse.compare.internal.Utilities;
+import org.eclipse.compare.patch.PatchConfiguration;
import org.eclipse.compare.structuremergeviewer.Differencer;
import org.eclipse.core.resources.*;
import org.eclipse.core.runtime.*;
@@ -34,6 +35,11 @@ public class Patcher {
static protected final String MARKER_TYPE= "org.eclipse.compare.rejectedPatchMarker"; //$NON-NLS-1$
+ /**
+ * Property used to associate a patcher with a {@link PatchConfiguration}
+ */
+ public static final String PROP_PATCHER = "org.eclipse.compare.patcher"; //$NON-NLS-1$
+
// diff formats
// private static final int CONTEXT= 0;
// private static final int ED= 1;
@@ -43,22 +49,18 @@ public class Patcher {
private FileDiff[] fDiffs;
private IResource fTarget;
// patch options
- private int fStripPrefixSegments;
- private int fFuzz;
- private boolean fIgnoreWhitespace= false;
- private boolean fIgnoreLineDelimiter= true;
- private boolean fPreserveLineDelimiters= false;
- private boolean fReverse= false;
- private boolean fAdjustShift= true;
- private boolean fGenerateRejectFile = true;
private Set disabledElements = new HashSet();
private Map diffResults = new HashMap();
private final Map contentCache = new HashMap();
private final Map properties = new HashMap();
private Set mergedHunks = new HashSet();
+
+ private final PatchConfiguration configuration;
+ private boolean fGenerateRejectFile = true;
public Patcher() {
- // nothing to do
+ configuration = new PatchConfiguration();
+ configuration.setProperty(PROP_PATCHER, this);
}
/*
@@ -79,43 +81,55 @@ public class Patcher {
* Returns <code>true</code> if new value differs from old.
*/
boolean setStripPrefixSegments(int strip) {
- if (strip != fStripPrefixSegments) {
- fStripPrefixSegments= strip;
+ if (strip != getConfiguration().getPrefixSegmentStripCount()) {
+ getConfiguration().setPrefixSegmentStripCount(strip);
return true;
}
return false;
}
int getStripPrefixSegments() {
- return fStripPrefixSegments;
+ return getConfiguration().getPrefixSegmentStripCount();
}
/*
* Returns <code>true</code> if new value differs from old.
*/
boolean setFuzz(int fuzz) {
- if (fuzz != fFuzz) {
- fFuzz= fuzz;
+ if (fuzz != getConfiguration().getFuzz()) {
+ getConfiguration().setFuzz(fuzz);
return true;
}
return false;
}
int getFuzz(){
- return fFuzz;
+ return getConfiguration().getFuzz();
}
/*
* Returns <code>true</code> if new value differs from old.
*/
boolean setIgnoreWhitespace(boolean ignoreWhitespace) {
- if (ignoreWhitespace != fIgnoreWhitespace) {
- fIgnoreWhitespace= ignoreWhitespace;
+ if (ignoreWhitespace != getConfiguration().isIgnoreWhitespace()) {
+ getConfiguration().setIgnoreWhitespace(ignoreWhitespace);
return true;
}
return false;
}
-
+
+ boolean isIgnoreWhitespace() {
+ return getConfiguration().isIgnoreWhitespace();
+ }
+
+ public boolean isGenerateRejectFile() {
+ return fGenerateRejectFile;
+ }
+
+ public void setGenerateRejectFile(boolean generateRejectFile) {
+ fGenerateRejectFile = generateRejectFile;
+ }
+
//---- parsing patch files
public void parse(IStorage storage) throws IOException, CoreException {
@@ -210,7 +224,7 @@ public class Patcher {
// patch it and collect rejected hunks
List result= apply(diff, file, true, failed);
if (result != null)
- store(createString(result), file, new SubProgressMonitor(pm, workTicks));
+ store(createString(isPreserveLineDelimeters(), result), file, new SubProgressMonitor(pm, workTicks));
workTicks-= WORK_UNIT;
break;
case Differencer.DELETION:
@@ -221,12 +235,12 @@ public class Patcher {
// patch it and collect rejected hunks
result= apply(diff, file, false, failed);
if (result != null)
- store(createString(result), file, new SubProgressMonitor(pm, workTicks));
+ store(createString(isPreserveLineDelimeters(), result), file, new SubProgressMonitor(pm, workTicks));
workTicks-= WORK_UNIT;
break;
}
- if (fGenerateRejectFile && failed.size() > 0) {
+ if (isGenerateRejectFile() && failed.size() > 0) {
IPath pp = getRejectFilePath(path);
file= createPath(container, pp);
if (file != null) {
@@ -265,7 +279,7 @@ public class Patcher {
* Reads the contents from the given file and returns them as
* a List of lines.
*/
- List load(IFile file, boolean create) {
+ public static List load(IStorage file, boolean create) {
List lines= null;
if (!create && file != null) {
// read current contents
@@ -302,7 +316,7 @@ public class Patcher {
return lines;
}
- private List readLines(BufferedReader reader) {
+ private static List readLines(BufferedReader reader) {
List lines;
LineReader lr= new LineReader(reader);
if (!"carbon".equals(SWT.getPlatform())) //$NON-NLS-1$
@@ -313,12 +327,17 @@ public class Patcher {
List apply(FileDiff diff, IFile file, boolean create, List failedHunks) {
FileDiffResult result = getDiffResult(diff);
- List lines = result.apply(file, create);
+ List lines = Patcher.load(file, create);
+ result.patch(lines, null);
failedHunks.addAll(result.getFailedHunks());
- // Return null if there were no matches
- if (!result.hasMatches())
+ if (hasCachedContents(diff)) {
+ // Used the cached contents since they would have been provided by the user
+ return getCachedLines(diff);
+ } else if (!result.hasMatches()) {
+ // Return null if there were no matches
return null;
- return lines;
+ }
+ return result.getLines();
}
/*
@@ -360,10 +379,10 @@ public class Patcher {
/*
* Concatenates all strings found in the given List.
*/
- protected String createString(List lines) {
+ public static String createString(boolean preserveLineDelimeters, List lines) {
StringBuffer sb= new StringBuffer();
Iterator iter= lines.iterator();
- if (fPreserveLineDelimiters) {
+ if (preserveLineDelimeters) {
while (iter.hasNext())
sb.append((String)iter.next());
} else {
@@ -382,7 +401,11 @@ public class Patcher {
return sb.toString();
}
- String getRejected(List failedHunks) {
+ protected boolean isPreserveLineDelimeters() {
+ return false;
+ }
+
+ public static String getRejected(List failedHunks) {
if (failedHunks.size() <= 0)
return null;
@@ -502,10 +525,6 @@ public class Patcher {
return length;
}
- public void setGenerateRejects(boolean generateRejects){
- this.fGenerateRejectFile = generateRejects;
- }
-
public void addDiff(FileDiff newDiff){
FileDiff[] temp = new FileDiff[fDiffs.length + 1];
System.arraycopy(fDiffs,0, temp, 0, fDiffs.length);
@@ -548,10 +567,6 @@ public class Patcher {
}
return null;
}
-
- public boolean isGenerateRejectFile() {
- return fGenerateRejectFile;
- }
/**
* Calculate the fuzz factor that will allow the most hunks to be matched.
@@ -591,21 +606,21 @@ public class Patcher {
for (int i = 0; i < diffs.length; i++) {
FileDiff diff = diffs[i];
FileDiffResult result = getDiffResult(diff);
- result.refresh();
+ ((WorkspaceFileDiffResult)result).refresh();
}
}
public FileDiffResult getDiffResult(FileDiff diff) {
FileDiffResult result = (FileDiffResult)diffResults.get(diff);
if (result == null) {
- result = new FileDiffResult(diff, this);
+ result = new WorkspaceFileDiffResult(diff, getConfiguration());
diffResults.put(diff, result);
}
return result;
}
- public boolean isAdjustShift() {
- return fAdjustShift;
+ public PatchConfiguration getConfiguration() {
+ return configuration;
}
/**
@@ -622,8 +637,8 @@ public class Patcher {
* Returns <code>true</code> if new value differs from old.
*/
public boolean setReversed(boolean reverse) {
- if (fReverse != reverse) {
- fReverse= reverse;
+ if (getConfiguration().isReversed() != reverse) {
+ getConfiguration().setReversed(reverse);
refresh();
return true;
}
@@ -631,15 +646,7 @@ public class Patcher {
}
public boolean isReversed() {
- return fReverse;
- }
-
- public boolean isIgnoreWhitespace() {
- return fIgnoreWhitespace;
- }
-
- public boolean isIgnoreLineDelimiter() {
- return fIgnoreLineDelimiter;
+ return getConfiguration().isReversed();
}
/**
@@ -737,4 +744,8 @@ public class Patcher {
}
return tr.getProject();
}
+
+ public static Patcher getPatcher(PatchConfiguration configuration) {
+ return (Patcher)configuration.getProperty(PROP_PATCHER);
+ }
}
diff --git a/bundles/org.eclipse.compare/compare/org/eclipse/compare/internal/patch/PreviewPatchPage2.java b/bundles/org.eclipse.compare/compare/org/eclipse/compare/internal/patch/PreviewPatchPage2.java
index 0c5bbeac5..f1930ade3 100644
--- a/bundles/org.eclipse.compare/compare/org/eclipse/compare/internal/patch/PreviewPatchPage2.java
+++ b/bundles/org.eclipse.compare/compare/org/eclipse/compare/internal/patch/PreviewPatchPage2.java
@@ -404,7 +404,7 @@ public class PreviewPatchPage2 extends WizardPage {
| GridData.GRAB_HORIZONTAL);
generateRejects.addSelectionListener(new SelectionAdapter() {
public void widgetSelected(SelectionEvent e) {
- getPatcher().setGenerateRejects(
+ getPatcher().setGenerateRejectFile(
generateRejects.getSelection());
}
});
diff --git a/bundles/org.eclipse.compare/compare/org/eclipse/compare/internal/patch/UnmatchedHunkTypedElement.java b/bundles/org.eclipse.compare/compare/org/eclipse/compare/internal/patch/UnmatchedHunkTypedElement.java
index f22c12ec3..ed719b4fa 100644
--- a/bundles/org.eclipse.compare/compare/org/eclipse/compare/internal/patch/UnmatchedHunkTypedElement.java
+++ b/bundles/org.eclipse.compare/compare/org/eclipse/compare/internal/patch/UnmatchedHunkTypedElement.java
@@ -16,6 +16,7 @@ import java.util.List;
import org.eclipse.compare.*;
import org.eclipse.compare.internal.CompareUIPlugin;
import org.eclipse.compare.internal.ContentChangeNotifier;
+import org.eclipse.compare.patch.PatchConfiguration;
import org.eclipse.core.resources.IFile;
import org.eclipse.core.runtime.CoreException;
@@ -49,7 +50,7 @@ public class UnmatchedHunkTypedElement extends HunkTypedElement implements ICont
* @see org.eclipse.compare.IEditableContent#isEditable()
*/
public boolean isEditable() {
- IFile file = getHunkResult().getDiffResult().getTargetFile();
+ IFile file = ((WorkspaceFileDiffResult)getHunkResult().getDiffResult()).getTargetFile();
return file != null && file.isAccessible();
}
@@ -65,7 +66,7 @@ public class UnmatchedHunkTypedElement extends HunkTypedElement implements ICont
* @see org.eclipse.compare.IEditableContent#setContent(byte[])
*/
public void setContent(byte[] newContent) {
- getHunkResult().getDiffResult().getPatcher().setManuallyMerged(getHunkResult().getHunk(), true);
+ getPatcher().setManuallyMerged(getHunkResult().getHunk(), true);
getPatcher().cacheContents(getDiff(), newContent);
if (changeNotifier != null)
changeNotifier.fireContentChanged();
@@ -76,7 +77,7 @@ public class UnmatchedHunkTypedElement extends HunkTypedElement implements ICont
}
private Patcher getPatcher() {
- return getHunkResult().getDiffResult().getPatcher();
+ return Patcher.getPatcher(getConfiguration());
}
/* (non-Javadoc)
@@ -88,7 +89,7 @@ public class UnmatchedHunkTypedElement extends HunkTypedElement implements ICont
return new ByteArrayInputStream(getPatcher().getCachedContents(getDiff()));
// Otherwise return the after state of the diff result
List lines = getHunkResult().getDiffResult().getAfterLines();
- String content = getPatcher().createString(lines);
+ String content = Patcher.createString(getHunkResult().getDiffResult().isPreserveLineDelimeters(), lines);
byte[] bytes = null;
if (getCharset() != null)
try {
@@ -100,4 +101,8 @@ public class UnmatchedHunkTypedElement extends HunkTypedElement implements ICont
bytes = content.getBytes();
return new ByteArrayInputStream(bytes);
}
+
+ private PatchConfiguration getConfiguration() {
+ return getHunkResult().getDiffResult().getConfiguration();
+ }
}
diff --git a/bundles/org.eclipse.compare/compare/org/eclipse/compare/internal/patch/WorkspaceFileDiffResult.java b/bundles/org.eclipse.compare/compare/org/eclipse/compare/internal/patch/WorkspaceFileDiffResult.java
new file mode 100644
index 000000000..6a334213c
--- /dev/null
+++ b/bundles/org.eclipse.compare/compare/org/eclipse/compare/internal/patch/WorkspaceFileDiffResult.java
@@ -0,0 +1,53 @@
+/*******************************************************************************
+ * Copyright (c) 2007 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.compare.internal.patch;
+
+import java.util.List;
+
+import org.eclipse.compare.patch.PatchConfiguration;
+import org.eclipse.core.resources.*;
+
+public class WorkspaceFileDiffResult extends FileDiffResult {
+
+ public WorkspaceFileDiffResult(FileDiff diff,
+ PatchConfiguration configuration) {
+ super(diff, configuration);
+ }
+
+ protected boolean canCreateTarget(IStorage storage) {
+ IProject project = getPatcher().getTargetProject(getDiff());
+ return project != null && project.isAccessible();
+ }
+
+ protected boolean targetExists(IStorage storage) {
+ IFile file= (IFile)storage;
+ return file != null && file.isAccessible();
+ }
+
+ protected List getLines(IStorage storage, boolean create) {
+ IFile file= getTargetFile();
+ List lines = Patcher.load(file, create);
+ return lines;
+ }
+
+ protected Patcher getPatcher() {
+ return Patcher.getPatcher(getConfiguration());
+ }
+
+ protected IFile getTargetFile() {
+ return getPatcher().getTargetFile(getDiff());
+ }
+
+ public void refresh() {
+ refresh(getTargetFile(), null);
+ }
+
+}
diff --git a/bundles/org.eclipse.compare/compare/org/eclipse/compare/internal/patch/WorkspacePatcher.java b/bundles/org.eclipse.compare/compare/org/eclipse/compare/internal/patch/WorkspacePatcher.java
index 939aab00c..c92edbbee 100644
--- a/bundles/org.eclipse.compare/compare/org/eclipse/compare/internal/patch/WorkspacePatcher.java
+++ b/bundles/org.eclipse.compare/compare/org/eclipse/compare/internal/patch/WorkspacePatcher.java
@@ -99,7 +99,7 @@ public class WorkspacePatcher extends Patcher {
// patch it and collect rejected hunks
List result= apply(diff, file, true, failed);
if (result != null)
- store(createString(result), file, new SubProgressMonitor(pm, workTicks));
+ store(createString(isPreserveLineDelimeters(), result), file, new SubProgressMonitor(pm, workTicks));
workTicks -= WORK_UNIT;
break;
case Differencer.DELETION :
@@ -110,7 +110,7 @@ public class WorkspacePatcher extends Patcher {
// patch it and collect rejected hunks
result= apply(diff, file, false, failed);
if (result != null)
- store(createString(result), file, new SubProgressMonitor(pm, workTicks));
+ store(createString(isPreserveLineDelimeters(), result), file, new SubProgressMonitor(pm, workTicks));
workTicks -= WORK_UNIT;
break;
}
diff --git a/bundles/org.eclipse.compare/compare/org/eclipse/compare/patch/AbstractHunk.java b/bundles/org.eclipse.compare/compare/org/eclipse/compare/patch/AbstractHunk.java
deleted file mode 100644
index 552f3d574..000000000
--- a/bundles/org.eclipse.compare/compare/org/eclipse/compare/patch/AbstractHunk.java
+++ /dev/null
@@ -1,23 +0,0 @@
-/*******************************************************************************
- * Copyright (c) 2006 IBM Corporation and others.
- * All rights reserved. This program and the accompanying materials
- * are made available under the terms of the Eclipse Public License v1.0
- * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/epl-v10.html
- *
- * Contributors:
- * IBM Corporation - initial API and implementation
- *******************************************************************************/
-package org.eclipse.compare.patch;
-
-/**
- * An abstract implementation of {@link IHunk}.
- * <p>
- * Clients may subclass this class.
- *
- * @since 3.3
- *
- */
-public abstract class AbstractHunk implements IHunk {
- // No default implementation
-}
diff --git a/bundles/org.eclipse.compare/compare/org/eclipse/compare/patch/ApplyPatchOperation.java b/bundles/org.eclipse.compare/compare/org/eclipse/compare/patch/ApplyPatchOperation.java
index f9416e30a..bba79b64c 100644
--- a/bundles/org.eclipse.compare/compare/org/eclipse/compare/patch/ApplyPatchOperation.java
+++ b/bundles/org.eclipse.compare/compare/org/eclipse/compare/patch/ApplyPatchOperation.java
@@ -62,11 +62,21 @@ public class ApplyPatchOperation implements Runnable {
* @throws CoreException if an error occurs reading the contents from the storage
*/
public static boolean isPatch(IStorage storage) throws CoreException {
+ return parsePatch(storage).length > 0;
+ }
+
+ /**
+ * Parse the given patch and return the set of file patches that it contains.
+ * @param storage the storage that contains the patch
+ * @return the set of file patches that the storage contains
+ * @throws CoreException if an error occurs reading the contents from the storage
+ */
+ public static IFilePatch[] parsePatch(IStorage storage) throws CoreException {
BufferedReader reader = Patcher.createReader(storage);
try {
PatchReader patchReader= new PatchReader();
patchReader.parse(reader);
- return patchReader.getDiffs().length > 0;
+ return patchReader.getAdjustedDiffs();
} catch (IOException e) {
throw new CoreException(new Status(IStatus.ERROR, CompareUIPlugin.PLUGIN_ID, 0, e.getMessage(), e));
} finally {
diff --git a/bundles/org.eclipse.compare/compare/org/eclipse/compare/patch/IFilePatch.java b/bundles/org.eclipse.compare/compare/org/eclipse/compare/patch/IFilePatch.java
new file mode 100644
index 000000000..e1779bbf1
--- /dev/null
+++ b/bundles/org.eclipse.compare/compare/org/eclipse/compare/patch/IFilePatch.java
@@ -0,0 +1,62 @@
+/*******************************************************************************
+ * Copyright (c) 2007 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.compare.patch;
+
+import org.eclipse.core.resources.IStorage;
+import org.eclipse.core.runtime.IPath;
+import org.eclipse.core.runtime.IProgressMonitor;
+
+/**
+ * A representation of a file patch that can be applied to an input stream.
+ * <p>
+ * This interface is not intended to be implemented by clients. Clients can
+ * obtain file patches by calling
+ * {@link ApplyPatchOperation#parsePatch(org.eclipse.core.resources.IStorage)}.
+ * <p>
+ * This interface is still under development and is to be considered
+ * <strong>EXPERIMENTAL</strong>.
+ * @see ApplyPatchOperation#parsePatch(org.eclipse.core.resources.IStorage)
+ * @since 3.3
+ */
+public interface IFilePatch {
+
+ /**
+ * Return the target path for this patch. The target path may differ
+ * depending on whether the patch is being reversed or not.
+ *
+ * @param configuration the patch configuration
+ * @return the target path for this patch
+ * @see PatchConfiguration#isReversed()
+ */
+ public IPath getTargetPath(PatchConfiguration configuration);
+
+ /**
+ * Apply this patch to the given file contents. The result provides the
+ * original and patch contents and also indicates whether some portions of
+ * the patch (called hunks) failed to apply.
+ *
+ * @param contents the file contents
+ * @param configuration the patch configuration
+ * @param monitor a progress monitor
+ * @return the result of the patch application
+ */
+ public IFilePatchResult apply(IStorage contents,
+ PatchConfiguration configuration, IProgressMonitor monitor);
+
+ /**
+ * Return the header information of the patch or
+ * <code>null</code> if there was no header text.
+ * The header may be multi-line.
+ * @return the header information of the patch or
+ * <code>null</code>
+ */
+ public String getHeader();
+}
diff --git a/bundles/org.eclipse.compare/compare/org/eclipse/compare/patch/IFilePatchResult.java b/bundles/org.eclipse.compare/compare/org/eclipse/compare/patch/IFilePatchResult.java
new file mode 100644
index 000000000..424b58148
--- /dev/null
+++ b/bundles/org.eclipse.compare/compare/org/eclipse/compare/patch/IFilePatchResult.java
@@ -0,0 +1,76 @@
+/*******************************************************************************
+ * Copyright (c) 2007 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.compare.patch;
+
+import java.io.InputStream;
+
+/**
+ * A file patch result provides the results of an attempt to apply an
+ * {@link IFilePatch} to the contents of a file. *
+ * <p>
+ * This interface is not intended to be implemented by clients. Clients can
+ * obtain patch results from an {@link IFilePatch}.
+ * <p>
+ * This interface is still under development and is to be considered
+ * <strong>EXPERIMENTAL</strong>.
+ *
+ * @see IFilePatch
+ * @since 3.3
+ */
+public interface IFilePatchResult {
+
+ /**
+ * Return a stream the contains the original contents of the file before
+ * any portions of the patch have been applied.
+ * @return a stream to the original contents of the file before
+ * any portions of the patch have been applied
+ * @see #getPatchedContents()
+ */
+ public InputStream getOriginalContents();
+
+ /**
+ * Return a stream that contains the file with as much of the patch
+ * applied as possible. if {@link #hasMatches()} returns <code>false</code>
+ * then the patched contents will match the original contents. Otherwise,
+ * at least a portion of the patch could be successfully applied. if
+ * {@link #hasRejects()} returns <code>false</code>, then the entire patch was
+ * applied. Otherwise, portions could not be applied. The portions that could
+ * not be applied can be obtained by calling {@link #getRejects()}.
+ *
+ * @return a stream that contains the file with as much of the patch
+ * applied as possible.
+ */
+ public InputStream getPatchedContents();
+
+ /**
+ * Return whether the patch has portions that were successfully applied.
+ * @return whether the patch has portions that were successfully applied
+ * @see #getPatchedContents()
+ */
+ public boolean hasMatches();
+
+ /**
+ * Return whether the patch has portions that were not successfully applied.
+ * @return whether the patch has portions that were not successfully applied
+ * @see #getPatchedContents()
+ */
+ public boolean hasRejects();
+
+ /**
+ * Return the portions of the patch (referred to a hunks) that could not
+ * be applied.
+ * @return the portions of the patch (referred to a hunks) that could not
+ * be applied
+ * @see #getPatchedContents()
+ */
+ public IHunk[] getRejects();
+
+}
diff --git a/bundles/org.eclipse.compare/compare/org/eclipse/compare/patch/IHunk.java b/bundles/org.eclipse.compare/compare/org/eclipse/compare/patch/IHunk.java
index 4eb41f592..1f1840936 100644
--- a/bundles/org.eclipse.compare/compare/org/eclipse/compare/patch/IHunk.java
+++ b/bundles/org.eclipse.compare/compare/org/eclipse/compare/patch/IHunk.java
@@ -1,27 +1,55 @@
package org.eclipse.compare.patch;
+import java.io.InputStream;
+
import org.eclipse.core.runtime.IAdaptable;
/**
- * Interface that represents a hunk. A hunk is a portion of a patch.
- * It identifies where the hunk is to be located in the target file.
- * One use of this interface is a means to communicate to content merge viewers
- * that one of the sides of a compare input is a patch hunk. Clients can determine
- * which side it is by adapting the side to this interface (see {@link IAdaptable}.
+ * Interface that represents a hunk. A hunk is a portion of a patch. It
+ * identifies where the hunk is to be located in the target file. One use of
+ * this interface is a means to communicate to content merge viewers that one of
+ * the sides of a compare input is a patch hunk. Clients can determine which
+ * side it is by adapting the side to this interface (see {@link IAdaptable}.
* <p>
- * This interface is not intended to be implemented by clients but should instead
- * subclass {@link AbstractHunk}.
+ * This interface is not intended to be implemented by clients but can be
+ * obtained from an {@link IFilePatchResult}
* <p>
- * This interface is
- * still under development and is to be considered <strong>EXPERIMENTAL</strong>.
- * since 3.3
- *
+ * This interface is still under development and is to be considered
+ * <strong>EXPERIMENTAL</strong>.
+ *
+ * @since 3.3
+ *
*/
public interface IHunk {
+
+ /**
+ * Return a label that can be used to describe the hunk.
+ * @return a label that can be used to describe the hunk
+ */
+ public String getLabel();
/**
* Return the start position of the hunk in the target file.
+ *
* @return the start position of the hunk in the target file.
*/
- int getStartPosition();
+ public int getStartPosition();
+
+ /**
+ * Return the original contents from which the hunk was generated.
+ * The returned contents usually only represent a portion of the
+ * file from which the hunk was generated.
+ * @return the original contents from which the hunk was generated
+ */
+ public InputStream getOriginalContents();
+
+ /**
+ * Return the contents that contain the modifications for this hunk.
+ * The returned contents usually only represent a portion of the
+ * file that was modified.
+ * @return the contents that contain the modifications for this hunk
+ */
+ public InputStream getPatchedContents();
+
+
}
diff --git a/bundles/org.eclipse.compare/compare/org/eclipse/compare/patch/PatchConfiguration.java b/bundles/org.eclipse.compare/compare/org/eclipse/compare/patch/PatchConfiguration.java
new file mode 100644
index 000000000..71da43090
--- /dev/null
+++ b/bundles/org.eclipse.compare/compare/org/eclipse/compare/patch/PatchConfiguration.java
@@ -0,0 +1,124 @@
+/*******************************************************************************
+ * Copyright (c) 2007 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.compare.patch;
+
+import java.util.HashMap;
+
+/**
+ * A patch configuration allows clients to set parameters that control how a patch
+ * is applied.
+ * <p>
+ * This class may be instantiated by clients but is not intended to be subclassed.
+ * <p>
+ * This interface is still under development and is to be considered
+ * <strong>EXPERIMENTAL</strong>.
+ * @see IFilePatch
+ * @since 3.3
+ */
+public class PatchConfiguration {
+
+ private int fStripPrefixSegments;
+ private int fFuzz;
+ private boolean fIgnoreWhitespace= false;
+ private boolean fReverse= false;
+ private HashMap properties = new HashMap();
+
+ /**
+ * Return whether the patch should be reversed when applied.
+ * @return whether the patch should be reversed when applied
+ */
+ public boolean isReversed() {
+ return fReverse;
+ }
+
+ /**
+ * Set whether the patch should be reversed when applied.
+ * @param reversed whether the patch should be reversed when applied
+ */
+ public void setReversed(boolean reversed) {
+ this.fReverse = reversed;
+ }
+
+ /**
+ * Return the number of prefix segments to be stripped when attempting
+ * to apply a patch.
+ * @return the number of prefix segments to be stripped when attempting
+ * to apply a patch
+ */
+ public int getPrefixSegmentStripCount() {
+ return fStripPrefixSegments;
+ }
+
+ /**
+ * Set the number of prefix segments to be stripped when attempting
+ * to apply a patch.
+ * @param stripCount the number of prefix segments to be stripped when attempting
+ * to apply a patch.
+ */
+ public void setPrefixSegmentStripCount(int stripCount) {
+ this.fStripPrefixSegments = stripCount;
+ }
+
+ /**
+ * Return the fuzz factor to be used when applying a patch.
+ * If the fuzz factor is set to -1, then the patcher is to make a best
+ * effort to apply the patch by adjusting the fuzz factor
+ * accordingly.
+ * @return the fuzz factor to be used when applying a patch.
+ */
+ public int getFuzz() {
+ return fFuzz;
+ }
+
+ /**
+ * Set the fuzz factor to be used when applying a patch.
+ * @param fuzz the fuzz factor to be used when applying a patch.
+ */
+ public void setFuzz(int fuzz) {
+ fFuzz = fuzz;
+ }
+
+ /**
+ * Return whether whitespace should be ignored.
+ * @return whether whitespace should be ignored
+ */
+ public boolean isIgnoreWhitespace() {
+ return fIgnoreWhitespace;
+ }
+
+ /**
+ * Set whether whitespace should be ignored
+ * @param ignoreWhitespace whether whitespace should be ignored
+ */
+ public void setIgnoreWhitespace(boolean ignoreWhitespace) {
+ fIgnoreWhitespace = ignoreWhitespace;
+ }
+
+ /**
+ * Return the property associated with the given key or
+ * <code>null</code> if there is no property for the key.
+ * @param key the key
+ * @return the property associated with the given key or
+ * <code>null</code>
+ */
+ public Object getProperty(String key) {
+ return properties.get(key);
+ }
+
+ /**
+ * Set the property associated with the given key
+ * @param key the key
+ * @param value the value to be associated with the key
+ */
+ public void setProperty(String key, Object value) {
+ properties.put(key, value);
+ }
+}
diff --git a/bundles/org.eclipse.compare/plugins/org.eclipse.compare/compare/org/eclipse/compare/internal/Utilities.java b/bundles/org.eclipse.compare/plugins/org.eclipse.compare/compare/org/eclipse/compare/internal/Utilities.java
index 83831b7bf..3123eac35 100644
--- a/bundles/org.eclipse.compare/plugins/org.eclipse.compare/compare/org/eclipse/compare/internal/Utilities.java
+++ b/bundles/org.eclipse.compare/plugins/org.eclipse.compare/compare/org/eclipse/compare/internal/Utilities.java
@@ -623,7 +623,7 @@ public class Utilities {
}
}
- public static String getCharset(IResource resource) {
+ public static String getCharset(Object resource) {
if (resource instanceof IEncodedStorage) {
try {
return ((IEncodedStorage)resource).getCharset();
diff --git a/bundles/org.eclipse.compare/plugins/org.eclipse.compare/compare/org/eclipse/compare/internal/patch/FileDiff.java b/bundles/org.eclipse.compare/plugins/org.eclipse.compare/compare/org/eclipse/compare/internal/patch/FileDiff.java
index 90ed12228..8e0222752 100644
--- a/bundles/org.eclipse.compare/plugins/org.eclipse.compare/compare/org/eclipse/compare/internal/patch/FileDiff.java
+++ b/bundles/org.eclipse.compare/plugins/org.eclipse.compare/compare/org/eclipse/compare/internal/patch/FileDiff.java
@@ -12,18 +12,21 @@ package org.eclipse.compare.internal.patch;
import java.util.*;
+import org.eclipse.compare.patch.*;
import org.eclipse.compare.structuremergeviewer.Differencer;
-import org.eclipse.core.runtime.IPath;
+import org.eclipse.core.resources.IStorage;
+import org.eclipse.core.runtime.*;
/**
* A file diff represents a set of hunks that were associated with the
* same path in a patch file.
*/
-public class FileDiff {
+public class FileDiff implements IFilePatch {
private IPath fOldPath, fNewPath;
private List fHunks= new ArrayList();
private DiffProject fProject; //the project that contains this diff
+ private String header;
/**
* Create a file diff for the given path and date information.
@@ -168,4 +171,42 @@ public class FileDiff {
length= Math.min(length, fNewPath.segmentCount());
return length;
}
+
+ public IFilePatchResult apply(IStorage contents,
+ PatchConfiguration configuration, IProgressMonitor monitor) {
+ FileDiffResult result = new FileDiffResult(this, configuration);
+ result.refresh(contents, monitor);
+ return result;
+ }
+
+ public IPath getTargetPath(PatchConfiguration configuration) {
+ return getStrippedPath(configuration.getPrefixSegmentStripCount(), configuration.isReversed());
+ }
+
+ public FileDiff asRelativeDiff() {
+ if (fProject == null)
+ return this;
+ IPath adjustedOldPath = null;
+ if (fOldPath != null) {
+ adjustedOldPath = new Path(null, fProject.getName()).append(fOldPath);
+ }
+ IPath adjustedNewPath = null;
+ if (fNewPath != null) {
+ adjustedNewPath = new Path(null, fProject.getName()).append(fNewPath);
+ }
+ FileDiff diff = new FileDiff(adjustedOldPath, 0, adjustedNewPath, 0);
+ for (Iterator iterator = fHunks.iterator(); iterator.hasNext();) {
+ Hunk hunk = (Hunk) iterator.next();
+ diff.add(hunk);
+ }
+ return diff;
+ }
+
+ public void setHeader(String header) {
+ this.header = header;
+ }
+
+ public String getHeader() {
+ return header;
+ }
}
diff --git a/bundles/org.eclipse.compare/plugins/org.eclipse.compare/compare/org/eclipse/compare/internal/patch/FileDiffResult.java b/bundles/org.eclipse.compare/plugins/org.eclipse.compare/compare/org/eclipse/compare/internal/patch/FileDiffResult.java
index a2705ee27..c56ecddc1 100644
--- a/bundles/org.eclipse.compare/plugins/org.eclipse.compare/compare/org/eclipse/compare/internal/patch/FileDiffResult.java
+++ b/bundles/org.eclipse.compare/plugins/org.eclipse.compare/compare/org/eclipse/compare/internal/patch/FileDiffResult.java
@@ -10,30 +10,37 @@
*******************************************************************************/
package org.eclipse.compare.internal.patch;
+import java.io.*;
import java.util.*;
+import org.eclipse.compare.internal.CompareUIPlugin;
+import org.eclipse.compare.internal.Utilities;
+import org.eclipse.compare.patch.*;
import org.eclipse.compare.structuremergeviewer.Differencer;
-import org.eclipse.core.resources.IFile;
-import org.eclipse.core.resources.IProject;
-import org.eclipse.core.runtime.IProgressMonitor;
+import org.eclipse.core.resources.*;
+import org.eclipse.core.runtime.*;
import org.eclipse.osgi.util.NLS;
-public class FileDiffResult {
+public class FileDiffResult implements IFilePatchResult {
private FileDiff fDiff;
private boolean fMatches= false;
private boolean fDiffProblem;
private String fErrorMessage;
- private String fRejected;
- private Patcher fPatcher;
private Map fHunkResults = new HashMap();
private List fBeforeLines, fAfterLines;
+ private final PatchConfiguration configuration;
+ private String charset;
+ private int fuzz;
-
- public FileDiffResult(FileDiff diff, Patcher patcher) {
+ public FileDiffResult(FileDiff diff, PatchConfiguration configuration) {
super();
fDiff = diff;
- fPatcher = patcher;
+ this.configuration = configuration;
+ }
+
+ public PatchConfiguration getConfiguration() {
+ return configuration;
}
public boolean canApplyHunk(Hunk hunk) {
@@ -48,16 +55,18 @@ public class FileDiffResult {
* Checks to see:
* 1) if the target file specified in fNewPath exists and is patchable
* 2) which hunks contained by this diff can actually be applied to the file
+ * @param storage the contents being patched or <code>null</code> for an addition
+ * @param monitor a progress monitor or <code>null</code> if no progress monitoring is desired
*/
- public void refresh() {
+ public void refresh(IStorage storage, IProgressMonitor monitor) {
fMatches= false;
fDiffProblem= false;
- IFile file= getTargetFile();
boolean create= false;
+ charset = Utilities.getCharset(storage);
//If this diff is an addition, make sure that it doesn't already exist
- if (fDiff.getDiffType(getPatcher().isReversed()) == Differencer.ADDITION) {
- IProject project = fPatcher.getTargetProject(fDiff);
- if ((file == null || !file.exists() || isEmpty(file)) && project != null && project.isAccessible()) {
+ boolean exists = targetExists(storage);
+ if (fDiff.getDiffType(getConfiguration().isReversed()) == Differencer.ADDITION) {
+ if ((!exists || isEmpty(storage)) && canCreateTarget(storage)) {
fMatches= true;
} else {
// file already exists
@@ -67,7 +76,7 @@ public class FileDiffResult {
create= true;
} else { //This diff is not an addition, try to find a match for it
//Ensure that the file described by the path exists and is modifiable
- if (file != null && file.isAccessible()) {
+ if (exists) {
fMatches= true;
} else {
// file doesn't exist
@@ -89,11 +98,10 @@ public class FileDiffResult {
}
} else {
// If this diff has no problems discovered so far, try applying the patch
- apply(file, create);
+ patch(getLines(storage, create), monitor);
}
if (containsProblems()) {
- fRejected= fPatcher.getRejected(getFailedHunks());
if (fMatches) {
// Check to see if we have at least one hunk that matches
fMatches = false;
@@ -110,33 +118,35 @@ public class FileDiffResult {
}
}
- private boolean isEmpty(IFile file) {
- if (file == null || !file.exists())
- return true;
- return getPatcher().load(file, false).isEmpty();
+ protected boolean canCreateTarget(IStorage storage) {
+ return true;
}
- protected IFile getTargetFile() {
- return fPatcher.getTargetFile(fDiff);
+ protected boolean targetExists(IStorage storage) {
+ return storage != null;
}
- List apply(IFile file, boolean create) {
- List lines = fPatcher.load(file, create);
- patch(lines);
- if (fPatcher.hasCachedContents(fDiff)) {
- // TODO: We should reapply the patch to see if anything new matches
- return fPatcher.getCachedLines(fDiff);
- }
- return getLines();
+ protected List getLines(IStorage storage, boolean create) {
+ List lines = Patcher.load(storage, create);
+ return lines;
}
+ protected boolean isEmpty(IStorage storage) {
+ if (storage == null)
+ return true;
+ return Patcher.load(storage, false).isEmpty();
+ }
+
/*
* Tries to patch the given lines with the specified Diff.
* Any hunk that couldn't be applied is returned in the list failedHunks.
*/
- public void patch(List lines) {
+ public void patch(List lines, IProgressMonitor monitor) {
fBeforeLines = new ArrayList();
fBeforeLines.addAll(lines);
+ if (getConfiguration().getFuzz() == -1) {
+ fuzz = calculateFuzz(fBeforeLines, monitor);
+ }
int shift= 0;
Hunk[] hunks = fDiff.getHunks();
for (int i = 0; i < hunks.length; i++) {
@@ -170,15 +180,11 @@ public class FileDiffResult {
}
public String getLabel() {
- String label= fDiff.getStrippedPath(fPatcher.getStripPrefixSegments(), fPatcher.isReversed()).toString();
+ String label= getTargetPath().toString();
if (this.fDiffProblem)
return NLS.bind(PatchMessages.Diff_2Args, new String[] {label, fErrorMessage});
return label;
}
-
- public String isRejected() {
- return fRejected;
- }
public boolean hasMatches() {
return fMatches;
@@ -199,17 +205,19 @@ public class FileDiffResult {
* @return the fuzz factor or <code>-1</code> if no hunks could be matched
*/
public int calculateFuzz(List lines, IProgressMonitor monitor) {
+ if (monitor == null)
+ monitor = new NullProgressMonitor();
fBeforeLines = new ArrayList();
fBeforeLines.addAll(lines);
// TODO: What about deletions?
- if (fDiff.getDiffType(getPatcher().isReversed()) == Differencer.ADDITION) {
+ if (fDiff.getDiffType(getConfiguration().isReversed()) == Differencer.ADDITION) {
// Additions don't need to adjust the fuzz factor
// TODO: What about the after lines?
return -1;
}
int shift= 0;
int fuzz = 0;
- String name= fPatcher.getPath(fDiff).lastSegment();
+ String name= getTargetPath().lastSegment();
Hunk[] hunks = fDiff.getHunks();
for (int j = 0; j < hunks.length; j++) {
Hunk h = hunks[j];
@@ -227,6 +235,10 @@ public class FileDiffResult {
fAfterLines = lines;
return fuzz;
}
+
+ public IPath getTargetPath() {
+ return fDiff.getStrippedPath(getConfiguration().getPrefixSegmentStripCount(), getConfiguration().isReversed());
+ }
private HunkResult getHunkResult(Hunk hunk) {
HunkResult result = (HunkResult)fHunkResults.get(hunk);
@@ -251,10 +263,6 @@ public class FileDiffResult {
return fDiff;
}
- Patcher getPatcher() {
- return fPatcher;
- }
-
List getBeforeLines() {
return fBeforeLines;
}
@@ -266,5 +274,55 @@ public class FileDiffResult {
public HunkResult[] getHunkResults() {
return (HunkResult[]) fHunkResults.values().toArray(new HunkResult[fHunkResults.size()]);
}
+
+ public InputStream getOriginalContents() {
+ String contents = Patcher.createString(isPreserveLineDelimeters(), getBeforeLines());
+ return asInputStream(contents, getCharSet());
+ }
+
+ public InputStream getPatchedContents() {
+ String contents = Patcher.createString(isPreserveLineDelimeters(), getLines());
+ return asInputStream(contents, getCharSet());
+ }
+
+ protected String getCharSet() {
+ return charset;
+ }
+
+ protected boolean isPreserveLineDelimeters() {
+ return false;
+ }
+
+ public IHunk[] getRejects() {
+ List failedHunks = getFailedHunks();
+ return (IHunk[]) failedHunks.toArray(new IHunk[failedHunks.size()]);
+ }
+
+ public boolean hasRejects() {
+ return !getFailedHunks().isEmpty();
+ }
+
+ public static InputStream asInputStream(String contents, String charSet) {
+ byte[] bytes = null;
+ if (charSet != null) {
+ try {
+ bytes = contents.getBytes(charSet);
+ } catch (UnsupportedEncodingException e) {
+ CompareUIPlugin.log(e);
+ }
+ }
+ if (bytes == null) {
+ bytes = contents.getBytes();
+ }
+ return new ByteArrayInputStream(bytes);
+ }
+
+ public int getFuzz() {
+ int cf = configuration.getFuzz();
+ if (cf == -1) {
+ return fuzz;
+ }
+ return cf;
+ }
}
diff --git a/bundles/org.eclipse.compare/plugins/org.eclipse.compare/compare/org/eclipse/compare/internal/patch/Hunk.java b/bundles/org.eclipse.compare/plugins/org.eclipse.compare/compare/org/eclipse/compare/internal/patch/Hunk.java
index b47d71532..ad75da482 100644
--- a/bundles/org.eclipse.compare/plugins/org.eclipse.compare/compare/org/eclipse/compare/internal/patch/Hunk.java
+++ b/bundles/org.eclipse.compare/plugins/org.eclipse.compare/compare/org/eclipse/compare/internal/patch/Hunk.java
@@ -12,6 +12,7 @@ package org.eclipse.compare.internal.patch;
import java.util.List;
+import org.eclipse.compare.patch.PatchConfiguration;
import org.eclipse.core.runtime.Assert;
/**
@@ -152,8 +153,8 @@ public class Hunk {
* The parameter shift is added to the line numbers given
* in the hunk.
*/
- public boolean tryPatch(Patcher patcher, List lines, int shift) {
- boolean reverse = patcher.isReversed();
+ public boolean tryPatch(PatchConfiguration configuration, List lines, int shift) {
+ boolean reverse = configuration.isReversed();
int pos= getStart(reverse) + shift;
int deleteMatches= 0;
for (int i= 0; i < fLines.length; i++) {
@@ -165,7 +166,7 @@ public class Hunk {
while (true) {
if (pos < 0 || pos >= lines.size())
return false;
- if (linesMatch(patcher, line, (String) lines.get(pos))) {
+ if (linesMatch(configuration, line, (String) lines.get(pos))) {
pos++;
break;
}
@@ -176,7 +177,7 @@ public class Hunk {
while (true) {
if (pos < 0 || pos >= lines.size())
return false;
- if (linesMatch(patcher, line, (String) lines.get(pos))) {
+ if (linesMatch(configuration, line, (String) lines.get(pos))) {
deleteMatches++;
pos++;
break;
@@ -215,8 +216,8 @@ public class Hunk {
return fNewLength - fOldLength;
}
- int doPatch(Patcher patcher, List lines, int shift) {
- boolean reverse = patcher.isReversed();
+ int doPatch(PatchConfiguration configuration, List lines, int shift) {
+ boolean reverse = configuration.isReversed();
int pos = getStart(reverse) + shift;
for (int i= 0; i < fLines.length; i++) {
String s= fLines[i];
@@ -226,7 +227,7 @@ public class Hunk {
if (controlChar == ' ') { // context lines
while (true) {
Assert.isTrue(pos < lines.size(), "doPatch: inconsistency in context"); //$NON-NLS-1$
- if (linesMatch(patcher, line, (String) lines.get(pos))) {
+ if (linesMatch(configuration, line, (String) lines.get(pos))) {
pos++;
break;
}
@@ -236,7 +237,7 @@ public class Hunk {
// deleted lines
while (true) {
Assert.isTrue(pos < lines.size(), "doPatch: inconsistency in deleted lines"); //$NON-NLS-1$
- if (linesMatch(patcher, line, (String) lines.get(pos))) {
+ if (linesMatch(configuration, line, (String) lines.get(pos))) {
break;
}
pos++;
@@ -267,10 +268,10 @@ public class Hunk {
* Compares two strings.
* If fIgnoreWhitespace is true whitespace is ignored.
*/
- private boolean linesMatch(Patcher patcher, String line1, String line2) {
- if (patcher.isIgnoreWhitespace())
+ private boolean linesMatch(PatchConfiguration configuration, String line1, String line2) {
+ if (configuration.isIgnoreWhitespace())
return stripWhiteSpace(line1).equals(stripWhiteSpace(line2));
- if (patcher.isIgnoreLineDelimiter()) {
+ if (isIgnoreLineDelimiter()) {
int l1= Patcher.length(line1);
int l2= Patcher.length(line2);
if (l1 != l2)
@@ -280,6 +281,10 @@ public class Hunk {
return line1.equals(line2);
}
+ private boolean isIgnoreLineDelimiter() {
+ return true;
+ }
+
/*
* Returns the given string with all whitespace characters removed.
* Whitespace is defined by <code>Character.isWhitespace(...)</code>.
diff --git a/bundles/org.eclipse.compare/plugins/org.eclipse.compare/compare/org/eclipse/compare/internal/patch/HunkDiffNode.java b/bundles/org.eclipse.compare/plugins/org.eclipse.compare/compare/org/eclipse/compare/internal/patch/HunkDiffNode.java
index 178ae45ae..009efeeb6 100644
--- a/bundles/org.eclipse.compare/plugins/org.eclipse.compare/compare/org/eclipse/compare/internal/patch/HunkDiffNode.java
+++ b/bundles/org.eclipse.compare/plugins/org.eclipse.compare/compare/org/eclipse/compare/internal/patch/HunkDiffNode.java
@@ -11,6 +11,7 @@
package org.eclipse.compare.internal.patch;
import org.eclipse.compare.ITypedElement;
+import org.eclipse.compare.patch.PatchConfiguration;
import org.eclipse.compare.structuremergeviewer.Differencer;
public class HunkDiffNode extends PatchDiffNode {
@@ -50,8 +51,8 @@ public class HunkDiffNode extends PatchDiffNode {
return result;
}
- protected Patcher getPatcher() {
- return result.getDiffResult().getPatcher();
+ protected PatchConfiguration getConfiguration() {
+ return result.getDiffResult().getConfiguration();
}
public boolean isManuallyMerged() {
diff --git a/bundles/org.eclipse.compare/plugins/org.eclipse.compare/compare/org/eclipse/compare/internal/patch/HunkResult.java b/bundles/org.eclipse.compare/plugins/org.eclipse.compare/compare/org/eclipse/compare/internal/patch/HunkResult.java
index b478a006d..7124ff5cb 100644
--- a/bundles/org.eclipse.compare/plugins/org.eclipse.compare/compare/org/eclipse/compare/internal/patch/HunkResult.java
+++ b/bundles/org.eclipse.compare/plugins/org.eclipse.compare/compare/org/eclipse/compare/internal/patch/HunkResult.java
@@ -10,13 +10,15 @@
*******************************************************************************/
package org.eclipse.compare.internal.patch;
+import java.io.InputStream;
import java.util.List;
-import org.eclipse.compare.patch.AbstractHunk;
+import org.eclipse.compare.patch.IHunk;
+import org.eclipse.compare.patch.PatchConfiguration;
import org.eclipse.core.runtime.IProgressMonitor;
import org.eclipse.core.runtime.OperationCanceledException;
-public class HunkResult extends AbstractHunk {
+public class HunkResult implements IHunk {
private static final boolean DEBUG= false;
@@ -45,18 +47,18 @@ public class HunkResult extends AbstractHunk {
*/
public boolean patch(List lines) {
fMatches = false;
- Patcher patcher = getPatcher();
- if (patcher.isEnabled(fHunk)) {
- if (fHunk.tryPatch(patcher, lines, fShift)) {
- fShift+= fHunk.doPatch(patcher, lines, fShift);
+ PatchConfiguration configuration = getConfiguration();
+ if (isEnabled(configuration)) {
+ if (fHunk.tryPatch(configuration, lines, fShift)) {
+ fShift+= fHunk.doPatch(configuration, lines, fShift);
fMatches = true;
} else {
boolean found= false;
int oldShift= fShift;
- for (int i= 1; i <= patcher.getFuzz(); i++) {
- if (fHunk.tryPatch(patcher, lines, fShift-i)) {
- if (patcher.isAdjustShift())
+ for (int i= 1; i <= fDiffResult.getFuzz(); i++) {
+ if (fHunk.tryPatch(configuration, lines, fShift-i)) {
+ if (isAdjustShift())
fShift-= i;
found= true;
break;
@@ -64,9 +66,9 @@ public class HunkResult extends AbstractHunk {
}
if (! found) {
- for (int i= 1; i <= patcher.getFuzz(); i++) {
- if (fHunk.tryPatch(patcher, lines, fShift+i)) {
- if (patcher.isAdjustShift())
+ for (int i= 1; i <= fDiffResult.getFuzz(); i++) {
+ if (fHunk.tryPatch(configuration, lines, fShift+i)) {
+ if (isAdjustShift())
fShift+= i;
found= true;
break;
@@ -76,16 +78,20 @@ public class HunkResult extends AbstractHunk {
if (found) {
if (DEBUG) System.out.println("patched hunk at offset: " + (fShift-oldShift)); //$NON-NLS-1$
- fShift+= fHunk.doPatch(patcher, lines, fShift);
+ fShift+= fHunk.doPatch(configuration, lines, fShift);
fMatches = true;
}
}
}
return fMatches;
}
-
- private Patcher getPatcher() {
- return getDiffResult().getPatcher();
+
+ private boolean isAdjustShift() {
+ return true;
+ }
+
+ private PatchConfiguration getConfiguration() {
+ return getDiffResult().getConfiguration();
}
/**
@@ -98,9 +104,9 @@ public class HunkResult extends AbstractHunk {
fMatches= false;
int fuzz = 0;
- Patcher patcher = getPatcher();
- if (fHunk.tryPatch(patcher, lines, fShift)) {
- fShift+= fHunk.doPatch(patcher, lines, fShift);
+ PatchConfiguration configuration = getConfiguration();
+ if (fHunk.tryPatch(configuration, lines, fShift)) {
+ fShift+= fHunk.doPatch(configuration, lines, fShift);
fMatches = true;
} else {
int hugeFuzz= lines.size(); // the maximum we need for this file
@@ -110,9 +116,9 @@ public class HunkResult extends AbstractHunk {
if (monitor.isCanceled()) {
throw new OperationCanceledException();
}
- if (fHunk.tryPatch(patcher, lines, fShift-i)) {
+ if (fHunk.tryPatch(configuration, lines, fShift-i)) {
fuzz= i;
- if (patcher.isAdjustShift())
+ if (isAdjustShift())
fShift-= i;
fMatches= true;
break;
@@ -124,9 +130,9 @@ public class HunkResult extends AbstractHunk {
if (monitor.isCanceled()) {
throw new OperationCanceledException();
}
- if (fHunk.tryPatch(patcher, lines, fShift+i)) {
+ if (fHunk.tryPatch(configuration, lines, fShift+i)) {
fuzz= i;
- if (patcher.isAdjustShift())
+ if (isAdjustShift())
fShift+= i;
fMatches= true;
break;
@@ -135,7 +141,7 @@ public class HunkResult extends AbstractHunk {
}
if (fMatches)
- fShift+= fHunk.doPatch(patcher, lines, fShift);
+ fShift+= fHunk.doPatch(configuration, lines, fShift);
}
return fuzz;
}
@@ -210,9 +216,16 @@ public class HunkResult extends AbstractHunk {
}
// Only return the full context if we could apply the hunk
if (!problemFound)
- return getPatcher().createString(lines);
+ return Patcher.createString(fDiffResult.isPreserveLineDelimeters(), lines);
}
- return getHunk().getContents(afterState, getPatcher().isReversed());
+ return getHunk().getContents(afterState, getConfiguration().isReversed());
+ }
+
+ private boolean isEnabled(PatchConfiguration configuration) {
+ Patcher patcher = Patcher.getPatcher(configuration);
+ if (patcher != null)
+ return patcher.isEnabled(fHunk);
+ return true;
}
public void setMatches(boolean matches) {
@@ -220,6 +233,29 @@ public class HunkResult extends AbstractHunk {
}
public int getStartPosition() {
- return fHunk.getStart(getPatcher().isReversed()) + fShift;
+ return fHunk.getStart(getConfiguration().isReversed()) + fShift;
+ }
+
+ public String getLabel() {
+ return getHunk().getDescription();
+ }
+
+ public InputStream getOriginalContents() {
+ String contents = getContents(false, false);
+ return asInputStream(contents);
+ }
+
+ protected InputStream asInputStream(String contents) {
+ String charSet = getCharset();
+ return FileDiffResult.asInputStream(contents, charSet);
+ }
+
+ public InputStream getPatchedContents() {
+ String contents = getContents(true, false);
+ return asInputStream(contents);
+ }
+
+ public String getCharset() {
+ return fDiffResult.getCharSet();
}
}
diff --git a/bundles/org.eclipse.compare/plugins/org.eclipse.compare/compare/org/eclipse/compare/internal/patch/HunkTypedElement.java b/bundles/org.eclipse.compare/plugins/org.eclipse.compare/compare/org/eclipse/compare/internal/patch/HunkTypedElement.java
index a872ad884..cdc659b59 100644
--- a/bundles/org.eclipse.compare/plugins/org.eclipse.compare/compare/org/eclipse/compare/internal/patch/HunkTypedElement.java
+++ b/bundles/org.eclipse.compare/plugins/org.eclipse.compare/compare/org/eclipse/compare/internal/patch/HunkTypedElement.java
@@ -38,7 +38,7 @@ public class HunkTypedElement implements ITypedElement, IEncodedStreamContentAcc
*/
public Image getImage() {
if (!fHunkResult.isOK()) {
- LocalResourceManager imageCache = PatchCompareEditorInput.getImageCache(fHunkResult.getDiffResult().getPatcher());
+ LocalResourceManager imageCache = PatchCompareEditorInput.getImageCache(fHunkResult.getDiffResult().getConfiguration());
return getHunkErrorImage(null, imageCache, false);
}
return null;
@@ -51,21 +51,25 @@ public class HunkTypedElement implements ITypedElement, IEncodedStreamContentAcc
}
public boolean isManuallyMerged() {
- return getHunkResult().getDiffResult().getPatcher().isManuallyMerged(getHunkResult().getHunk());
+ return getPatcher().isManuallyMerged(getHunkResult().getHunk());
+ }
+
+ private Patcher getPatcher() {
+ return Patcher.getPatcher(fHunkResult.getDiffResult().getConfiguration());
}
/* (non-Javadoc)
* @see org.eclipse.compare.ITypedElement#getName()
*/
public String getName() {
- return fHunkResult.getHunk().getDescription();
+ return fHunkResult.getLabel();
}
/* (non-Javadoc)
* @see org.eclipse.compare.ITypedElement#getType()
*/
public String getType() {
- return fHunkResult.getDiffResult().getPatcher().getPath(fHunkResult.getDiffResult().getDiff()).getFileExtension();
+ return fHunkResult.getDiffResult().getDiff().getTargetPath(fHunkResult.getDiffResult().getConfiguration()).getFileExtension();
}
/* (non-Javadoc)
@@ -73,24 +77,11 @@ public class HunkTypedElement implements ITypedElement, IEncodedStreamContentAcc
*/
public InputStream getContents() throws CoreException {
String contents = fHunkResult.getContents(fIsAfterState, fFullContext);
- String charSet = getCharset();
- byte[] bytes = null;
- if (charSet != null) {
- try {
- bytes = contents.getBytes(charSet);
- } catch (UnsupportedEncodingException e) {
- CompareUIPlugin.log(e);
- }
- }
- if (bytes == null) {
- bytes = contents.getBytes();
- }
- return new ByteArrayInputStream(bytes);
+ return fHunkResult.asInputStream(contents);
}
public String getCharset() throws CoreException {
- // TODO Auto-generated method stub
- return null;
+ return fHunkResult.getCharset();
}
public HunkResult getHunkResult() {
diff --git a/bundles/org.eclipse.compare/plugins/org.eclipse.compare/compare/org/eclipse/compare/internal/patch/PatchCompareEditorInput.java b/bundles/org.eclipse.compare/plugins/org.eclipse.compare/compare/org/eclipse/compare/internal/patch/PatchCompareEditorInput.java
index 9712a7b7f..8cb2c35c1 100644
--- a/bundles/org.eclipse.compare/plugins/org.eclipse.compare/compare/org/eclipse/compare/internal/patch/PatchCompareEditorInput.java
+++ b/bundles/org.eclipse.compare/plugins/org.eclipse.compare/compare/org/eclipse/compare/internal/patch/PatchCompareEditorInput.java
@@ -4,6 +4,7 @@ import java.lang.reflect.InvocationTargetException;
import org.eclipse.compare.*;
import org.eclipse.compare.internal.*;
+import org.eclipse.compare.patch.PatchConfiguration;
import org.eclipse.compare.structuremergeviewer.*;
import org.eclipse.core.runtime.Assert;
import org.eclipse.core.runtime.IProgressMonitor;
@@ -77,14 +78,14 @@ public abstract class PatchCompareEditorInput extends CompareEditorInput {
if (element instanceof PatchDiffNode){
PatchDiffNode node = (PatchDiffNode) element;
if (!node.isEnabled() && image != null) {
- LocalResourceManager imageCache = PatchCompareEditorInput.getImageCache(getPatcher());
+ LocalResourceManager imageCache = PatchCompareEditorInput.getImageCache(getPatcher().getConfiguration());
return imageCache.createImage(createOverlay(image, CompareUIPlugin.getImageDescriptor(ICompareUIConstants.REMOVED_OVERLAY), IDecoration.TOP_LEFT));
}
}
if (element instanceof HunkDiffNode) {
HunkDiffNode node = (HunkDiffNode) element;
if (node.isManuallyMerged()) {
- LocalResourceManager imageCache = PatchCompareEditorInput.getImageCache(getPatcher());
+ LocalResourceManager imageCache = PatchCompareEditorInput.getImageCache(getPatcher().getConfiguration());
return imageCache.createImage(PatchCompareEditorInput.createOverlay(image, CompareUIPlugin.getImageDescriptor(ICompareUIConstants.IS_MERGED_OVERLAY), IDecoration.TOP_LEFT));
}
}
@@ -123,11 +124,11 @@ public abstract class PatchCompareEditorInput extends CompareEditorInput {
protected void handleDispose() {
super.handleDispose();
- getImageCache(patcher).dispose();
+ getImageCache(getPatcher().getConfiguration()).dispose();
}
- public static LocalResourceManager getImageCache(Patcher patcher) {
- return (LocalResourceManager)patcher.getProperty(IMAGE_CACHE_KEY);
+ public static LocalResourceManager getImageCache(PatchConfiguration patchConfiguration) {
+ return (LocalResourceManager)patchConfiguration.getProperty(IMAGE_CACHE_KEY);
}
protected Object prepareInput(IProgressMonitor monitor) throws InvocationTargetException, InterruptedException {
@@ -190,7 +191,7 @@ public abstract class PatchCompareEditorInput extends CompareEditorInput {
private void processProjects(DiffProject[] diffProjects) {
//create diffProject nodes
for (int i = 0; i < diffProjects.length; i++) {
- PatchProjectDiffNode projectNode = new PatchProjectDiffNode(getRoot(), diffProjects[i], getPatcher());
+ PatchProjectDiffNode projectNode = new PatchProjectDiffNode(getRoot(), diffProjects[i], getPatcher().getConfiguration());
FileDiff[] diffs = diffProjects[i].getFileDiffs();
for (int j = 0; j < diffs.length; j++) {
FileDiff fileDiff = diffs[j];
diff --git a/bundles/org.eclipse.compare/plugins/org.eclipse.compare/compare/org/eclipse/compare/internal/patch/PatchDiffNode.java b/bundles/org.eclipse.compare/plugins/org.eclipse.compare/compare/org/eclipse/compare/internal/patch/PatchDiffNode.java
index 38a83b25d..a957e4bc3 100644
--- a/bundles/org.eclipse.compare/plugins/org.eclipse.compare/compare/org/eclipse/compare/internal/patch/PatchDiffNode.java
+++ b/bundles/org.eclipse.compare/plugins/org.eclipse.compare/compare/org/eclipse/compare/internal/patch/PatchDiffNode.java
@@ -11,6 +11,7 @@
package org.eclipse.compare.internal.patch;
import org.eclipse.compare.ITypedElement;
+import org.eclipse.compare.patch.PatchConfiguration;
import org.eclipse.compare.structuremergeviewer.*;
public abstract class PatchDiffNode extends DiffNode {
@@ -36,11 +37,15 @@ public abstract class PatchDiffNode extends DiffNode {
getPatcher().setEnabled(getPatchElement(), enabled);
}
+ protected final Patcher getPatcher() {
+ return Patcher.getPatcher(getConfiguration());
+ }
+
public Object getPatchElement() {
return fElement;
}
- protected abstract Patcher getPatcher();
+ protected abstract PatchConfiguration getConfiguration();
public boolean equals(Object other) {
if (other instanceof PatchDiffNode) {
diff --git a/bundles/org.eclipse.compare/plugins/org.eclipse.compare/compare/org/eclipse/compare/internal/patch/PatchFileDiffNode.java b/bundles/org.eclipse.compare/plugins/org.eclipse.compare/compare/org/eclipse/compare/internal/patch/PatchFileDiffNode.java
index 4f3d75855..8b4b1a080 100644
--- a/bundles/org.eclipse.compare/plugins/org.eclipse.compare/compare/org/eclipse/compare/internal/patch/PatchFileDiffNode.java
+++ b/bundles/org.eclipse.compare/plugins/org.eclipse.compare/compare/org/eclipse/compare/internal/patch/PatchFileDiffNode.java
@@ -11,6 +11,7 @@
package org.eclipse.compare.internal.patch;
import org.eclipse.compare.*;
+import org.eclipse.compare.patch.PatchConfiguration;
import org.eclipse.compare.structuremergeviewer.*;
import org.eclipse.core.resources.IFile;
@@ -25,7 +26,7 @@ public class PatchFileDiffNode extends PatchDiffNode implements IContentChangeLi
private static int getKind(FileDiffResult result) {
if (!result.hasMatches())
return Differencer.NO_CHANGE;
- return result.getDiff().getDiffType(result.getPatcher().isReversed()) | Differencer.RIGHT;
+ return result.getDiff().getDiffType(result.getConfiguration().isReversed()) | Differencer.RIGHT;
}
private static ITypedElement getRightElement(FileDiffResult result) {
@@ -49,9 +50,9 @@ public class PatchFileDiffNode extends PatchDiffNode implements IContentChangeLi
public FileDiffResult getDiffResult() {
return result;
}
-
- protected Patcher getPatcher() {
- return result.getPatcher();
+
+ protected PatchConfiguration getConfiguration() {
+ return result.getConfiguration();
}
/* (non-Javadoc)
@@ -86,7 +87,7 @@ public class PatchFileDiffNode extends PatchDiffNode implements IContentChangeLi
}
public boolean fileExists() {
- IFile file = getDiffResult().getTargetFile();
+ IFile file = ((WorkspaceFileDiffResult)getDiffResult()).getTargetFile();
return file != null && file.isAccessible();
}
diff --git a/bundles/org.eclipse.compare/plugins/org.eclipse.compare/compare/org/eclipse/compare/internal/patch/PatchFileTypedElement.java b/bundles/org.eclipse.compare/plugins/org.eclipse.compare/compare/org/eclipse/compare/internal/patch/PatchFileTypedElement.java
index 3ed8ac6a7..4ea76e630 100644
--- a/bundles/org.eclipse.compare/plugins/org.eclipse.compare/compare/org/eclipse/compare/internal/patch/PatchFileTypedElement.java
+++ b/bundles/org.eclipse.compare/plugins/org.eclipse.compare/compare/org/eclipse/compare/internal/patch/PatchFileTypedElement.java
@@ -31,19 +31,19 @@ public class PatchFileTypedElement implements ITypedElement, IEncodedStreamConte
}
public Image getImage() {
- IFile file = result.getPatcher().getTargetFile(result.getDiff());
+ IFile file = getPatcher().getTargetFile(result.getDiff());
if (file == null) {
// We don't get a target file if the file doesn't exist
DiffProject project = result.getDiff().getProject();
if (project != null) {
- file = project.getFile(result.getDiff().getPath(result.getPatcher().isReversed()));
+ file = project.getFile(result.getDiff().getPath(result.getConfiguration().isReversed()));
} else {
- IResource target = result.getPatcher().getTarget();
+ IResource target = getPatcher().getTarget();
if (target instanceof IFile) {
file = (IFile) target;
} else if (target instanceof IContainer) {
IContainer container = (IContainer) target;
- file = container.getFile(result.getDiff().getStrippedPath(result.getPatcher().getStripPrefixSegments(), result.getPatcher().isReversed()));
+ file = container.getFile(result.getTargetPath());
}
}
}
@@ -52,7 +52,7 @@ public class PatchFileTypedElement implements ITypedElement, IEncodedStreamConte
image = CompareUI.getImage(file);
}
if (result.containsProblems()) {
- LocalResourceManager imageCache = PatchCompareEditorInput.getImageCache(result.getPatcher());
+ LocalResourceManager imageCache = PatchCompareEditorInput.getImageCache(result.getConfiguration());
image = HunkTypedElement.getHunkErrorImage(image, imageCache, true);
}
return image;
@@ -62,14 +62,14 @@ public class PatchFileTypedElement implements ITypedElement, IEncodedStreamConte
* @see org.eclipse.compare.ITypedElement#getName()
*/
public String getName() {
- return result.getDiff().getStrippedPath(result.getPatcher().getStripPrefixSegments(), result.getPatcher().isReversed()).toString();
+ return result.getTargetPath().toString();
}
/* (non-Javadoc)
* @see org.eclipse.compare.ITypedElement#getType()
*/
public String getType() {
- return result.getPatcher().getPath(result.getDiff()).getFileExtension();
+ return result.getTargetPath().getFileExtension();
}
public String getCharset() throws CoreException {
@@ -79,8 +79,8 @@ public class PatchFileTypedElement implements ITypedElement, IEncodedStreamConte
public InputStream getContents() throws CoreException {
// If there are cached contents, use them
- if (isAfterState && result.getPatcher().hasCachedContents(result.getDiff()))
- return new ByteArrayInputStream(result.getPatcher().getCachedContents(result.getDiff()));
+ if (isAfterState && getPatcher().hasCachedContents(result.getDiff()))
+ return new ByteArrayInputStream(getPatcher().getCachedContents(result.getDiff()));
// Otherwise, get the lines from the diff result
List lines;
if (isAfterState) {
@@ -88,7 +88,7 @@ public class PatchFileTypedElement implements ITypedElement, IEncodedStreamConte
} else {
lines = result.getBeforeLines();
}
- String contents = result.getPatcher().createString(lines);
+ String contents = Patcher.createString(getPatcher().isPreserveLineDelimeters(), lines);
String charSet = getCharset();
byte[] bytes = null;
if (charSet != null) {
@@ -104,4 +104,8 @@ public class PatchFileTypedElement implements ITypedElement, IEncodedStreamConte
return new ByteArrayInputStream(bytes);
}
+ private Patcher getPatcher() {
+ return Patcher.getPatcher(result.getConfiguration());
+ }
+
}
diff --git a/bundles/org.eclipse.compare/plugins/org.eclipse.compare/compare/org/eclipse/compare/internal/patch/PatchProjectDiffNode.java b/bundles/org.eclipse.compare/plugins/org.eclipse.compare/compare/org/eclipse/compare/internal/patch/PatchProjectDiffNode.java
index abae2df0a..663a6466a 100644
--- a/bundles/org.eclipse.compare/plugins/org.eclipse.compare/compare/org/eclipse/compare/internal/patch/PatchProjectDiffNode.java
+++ b/bundles/org.eclipse.compare/plugins/org.eclipse.compare/compare/org/eclipse/compare/internal/patch/PatchProjectDiffNode.java
@@ -12,6 +12,7 @@ package org.eclipse.compare.internal.patch;
import org.eclipse.compare.CompareUI;
import org.eclipse.compare.ITypedElement;
+import org.eclipse.compare.patch.PatchConfiguration;
import org.eclipse.compare.structuremergeviewer.*;
import org.eclipse.jface.resource.LocalResourceManager;
import org.eclipse.swt.graphics.Image;
@@ -19,12 +20,12 @@ import org.eclipse.swt.graphics.Image;
public class PatchProjectDiffNode extends PatchDiffNode {
private final DiffProject project;
- private final Patcher patcher;
+ private final PatchConfiguration configuration;
- public PatchProjectDiffNode(IDiffContainer parent, DiffProject project, Patcher patcher) {
+ public PatchProjectDiffNode(IDiffContainer parent, DiffProject project, PatchConfiguration configuration) {
super(project, parent, Differencer.NO_CHANGE);
this.project = project;
- this.patcher = patcher;
+ this.configuration = configuration;
}
/* (non-Javadoc)
@@ -40,7 +41,7 @@ public class PatchProjectDiffNode extends PatchDiffNode {
public Image getImage() {
Image image = CompareUI.getImage(project.getProject());
if (containsProblems()) {
- LocalResourceManager imageCache = PatchCompareEditorInput.getImageCache(getPatcher());
+ LocalResourceManager imageCache = PatchCompareEditorInput.getImageCache(getConfiguration());
image = HunkTypedElement.getHunkErrorImage(image, imageCache, true);
}
return image;
@@ -65,9 +66,9 @@ public class PatchProjectDiffNode extends PatchDiffNode {
public String getType() {
return ITypedElement.FOLDER_TYPE;
}
-
- protected Patcher getPatcher() {
- return patcher;
+
+ protected PatchConfiguration getConfiguration() {
+ return configuration;
}
public DiffProject getDiffProject() {
diff --git a/bundles/org.eclipse.compare/plugins/org.eclipse.compare/compare/org/eclipse/compare/internal/patch/PatchReader.java b/bundles/org.eclipse.compare/plugins/org.eclipse.compare/compare/org/eclipse/compare/internal/patch/PatchReader.java
index 547b8a2a1..82747c62c 100644
--- a/bundles/org.eclipse.compare/plugins/org.eclipse.compare/compare/org/eclipse/compare/internal/patch/PatchReader.java
+++ b/bundles/org.eclipse.compare/plugins/org.eclipse.compare/compare/org/eclipse/compare/internal/patch/PatchReader.java
@@ -146,6 +146,7 @@ public class PatchReader {
boolean reread= false;
String diffArgs= null;
String fileName= null;
+ List headerLines = new ArrayList();
// read leading garbage
reread= line!=null;
@@ -155,28 +156,31 @@ public class PatchReader {
reread= false;
if (line == null)
break;
- if (line.length() < 4)
- continue; // too short
// remember some infos
if (line.startsWith("Index: ")) { //$NON-NLS-1$
fileName= line.substring(7).trim();
- continue;
- }
- if (line.startsWith("diff")) { //$NON-NLS-1$
+ } else if (line.startsWith("diff")) { //$NON-NLS-1$
diffArgs= line.substring(4).trim();
- continue;
- }
-
- if (line.startsWith("--- ")) { //$NON-NLS-1$
+ } else if (line.startsWith("--- ")) { //$NON-NLS-1$
line= readUnifiedDiff(diffs, lr, line, diffArgs, fileName);
+ if (!headerLines.isEmpty())
+ setHeader((FileDiff)diffs.get(diffs.size() - 1), headerLines);
diffArgs= fileName= null;
reread= true;
} else if (line.startsWith("*** ")) { //$NON-NLS-1$
line= readContextDiff(diffs, lr, line, diffArgs, fileName);
+ if (!headerLines.isEmpty())
+ setHeader((FileDiff)diffs.get(diffs.size() - 1), headerLines);
diffArgs= fileName= null;
reread= true;
}
+
+ // Any lines we read here are header lines.
+ // However, if reread is set, we will add them to the header on the next pass through
+ if (!reread) {
+ headerLines.add(line);
+ }
}
lr.close();
@@ -184,6 +188,12 @@ public class PatchReader {
fDiffs = (FileDiff[]) diffs.toArray(new FileDiff[diffs.size()]);
}
+ private void setHeader(FileDiff diff, List headerLines) {
+ String header = Patcher.createString(false, headerLines);
+ diff.setHeader(header);
+ headerLines.clear();
+ }
+
/*
* Returns the next line that does not belong to this diff
*/
@@ -617,4 +627,15 @@ public class PatchReader {
public FileDiff[] getDiffs() {
return fDiffs;
}
+
+ public FileDiff[] getAdjustedDiffs() {
+ if (!isWorkspacePatch() || fDiffs.length == 0)
+ return fDiffs;
+ List result = new ArrayList();
+ for (int i = 0; i < fDiffs.length; i++) {
+ FileDiff diff = fDiffs[i];
+ result.add(diff.asRelativeDiff());
+ }
+ return (FileDiff[]) result.toArray(new FileDiff[result.size()]);
+ }
}
diff --git a/bundles/org.eclipse.compare/plugins/org.eclipse.compare/compare/org/eclipse/compare/internal/patch/Patcher.java b/bundles/org.eclipse.compare/plugins/org.eclipse.compare/compare/org/eclipse/compare/internal/patch/Patcher.java
index 2ad531618..86f23e3db 100644
--- a/bundles/org.eclipse.compare/plugins/org.eclipse.compare/compare/org/eclipse/compare/internal/patch/Patcher.java
+++ b/bundles/org.eclipse.compare/plugins/org.eclipse.compare/compare/org/eclipse/compare/internal/patch/Patcher.java
@@ -16,6 +16,7 @@ import java.util.*;
import org.eclipse.compare.internal.CompareUIPlugin;
import org.eclipse.compare.internal.Utilities;
+import org.eclipse.compare.patch.PatchConfiguration;
import org.eclipse.compare.structuremergeviewer.Differencer;
import org.eclipse.core.resources.*;
import org.eclipse.core.runtime.*;
@@ -34,6 +35,11 @@ public class Patcher {
static protected final String MARKER_TYPE= "org.eclipse.compare.rejectedPatchMarker"; //$NON-NLS-1$
+ /**
+ * Property used to associate a patcher with a {@link PatchConfiguration}
+ */
+ public static final String PROP_PATCHER = "org.eclipse.compare.patcher"; //$NON-NLS-1$
+
// diff formats
// private static final int CONTEXT= 0;
// private static final int ED= 1;
@@ -43,22 +49,18 @@ public class Patcher {
private FileDiff[] fDiffs;
private IResource fTarget;
// patch options
- private int fStripPrefixSegments;
- private int fFuzz;
- private boolean fIgnoreWhitespace= false;
- private boolean fIgnoreLineDelimiter= true;
- private boolean fPreserveLineDelimiters= false;
- private boolean fReverse= false;
- private boolean fAdjustShift= true;
- private boolean fGenerateRejectFile = true;
private Set disabledElements = new HashSet();
private Map diffResults = new HashMap();
private final Map contentCache = new HashMap();
private final Map properties = new HashMap();
private Set mergedHunks = new HashSet();
+
+ private final PatchConfiguration configuration;
+ private boolean fGenerateRejectFile = true;
public Patcher() {
- // nothing to do
+ configuration = new PatchConfiguration();
+ configuration.setProperty(PROP_PATCHER, this);
}
/*
@@ -79,43 +81,55 @@ public class Patcher {
* Returns <code>true</code> if new value differs from old.
*/
boolean setStripPrefixSegments(int strip) {
- if (strip != fStripPrefixSegments) {
- fStripPrefixSegments= strip;
+ if (strip != getConfiguration().getPrefixSegmentStripCount()) {
+ getConfiguration().setPrefixSegmentStripCount(strip);
return true;
}
return false;
}
int getStripPrefixSegments() {
- return fStripPrefixSegments;
+ return getConfiguration().getPrefixSegmentStripCount();
}
/*
* Returns <code>true</code> if new value differs from old.
*/
boolean setFuzz(int fuzz) {
- if (fuzz != fFuzz) {
- fFuzz= fuzz;
+ if (fuzz != getConfiguration().getFuzz()) {
+ getConfiguration().setFuzz(fuzz);
return true;
}
return false;
}
int getFuzz(){
- return fFuzz;
+ return getConfiguration().getFuzz();
}
/*
* Returns <code>true</code> if new value differs from old.
*/
boolean setIgnoreWhitespace(boolean ignoreWhitespace) {
- if (ignoreWhitespace != fIgnoreWhitespace) {
- fIgnoreWhitespace= ignoreWhitespace;
+ if (ignoreWhitespace != getConfiguration().isIgnoreWhitespace()) {
+ getConfiguration().setIgnoreWhitespace(ignoreWhitespace);
return true;
}
return false;
}
-
+
+ boolean isIgnoreWhitespace() {
+ return getConfiguration().isIgnoreWhitespace();
+ }
+
+ public boolean isGenerateRejectFile() {
+ return fGenerateRejectFile;
+ }
+
+ public void setGenerateRejectFile(boolean generateRejectFile) {
+ fGenerateRejectFile = generateRejectFile;
+ }
+
//---- parsing patch files
public void parse(IStorage storage) throws IOException, CoreException {
@@ -210,7 +224,7 @@ public class Patcher {
// patch it and collect rejected hunks
List result= apply(diff, file, true, failed);
if (result != null)
- store(createString(result), file, new SubProgressMonitor(pm, workTicks));
+ store(createString(isPreserveLineDelimeters(), result), file, new SubProgressMonitor(pm, workTicks));
workTicks-= WORK_UNIT;
break;
case Differencer.DELETION:
@@ -221,12 +235,12 @@ public class Patcher {
// patch it and collect rejected hunks
result= apply(diff, file, false, failed);
if (result != null)
- store(createString(result), file, new SubProgressMonitor(pm, workTicks));
+ store(createString(isPreserveLineDelimeters(), result), file, new SubProgressMonitor(pm, workTicks));
workTicks-= WORK_UNIT;
break;
}
- if (fGenerateRejectFile && failed.size() > 0) {
+ if (isGenerateRejectFile() && failed.size() > 0) {
IPath pp = getRejectFilePath(path);
file= createPath(container, pp);
if (file != null) {
@@ -265,7 +279,7 @@ public class Patcher {
* Reads the contents from the given file and returns them as
* a List of lines.
*/
- List load(IFile file, boolean create) {
+ public static List load(IStorage file, boolean create) {
List lines= null;
if (!create && file != null) {
// read current contents
@@ -302,7 +316,7 @@ public class Patcher {
return lines;
}
- private List readLines(BufferedReader reader) {
+ private static List readLines(BufferedReader reader) {
List lines;
LineReader lr= new LineReader(reader);
if (!"carbon".equals(SWT.getPlatform())) //$NON-NLS-1$
@@ -313,12 +327,17 @@ public class Patcher {
List apply(FileDiff diff, IFile file, boolean create, List failedHunks) {
FileDiffResult result = getDiffResult(diff);
- List lines = result.apply(file, create);
+ List lines = Patcher.load(file, create);
+ result.patch(lines, null);
failedHunks.addAll(result.getFailedHunks());
- // Return null if there were no matches
- if (!result.hasMatches())
+ if (hasCachedContents(diff)) {
+ // Used the cached contents since they would have been provided by the user
+ return getCachedLines(diff);
+ } else if (!result.hasMatches()) {
+ // Return null if there were no matches
return null;
- return lines;
+ }
+ return result.getLines();
}
/*
@@ -360,10 +379,10 @@ public class Patcher {
/*
* Concatenates all strings found in the given List.
*/
- protected String createString(List lines) {
+ public static String createString(boolean preserveLineDelimeters, List lines) {
StringBuffer sb= new StringBuffer();
Iterator iter= lines.iterator();
- if (fPreserveLineDelimiters) {
+ if (preserveLineDelimeters) {
while (iter.hasNext())
sb.append((String)iter.next());
} else {
@@ -382,7 +401,11 @@ public class Patcher {
return sb.toString();
}
- String getRejected(List failedHunks) {
+ protected boolean isPreserveLineDelimeters() {
+ return false;
+ }
+
+ public static String getRejected(List failedHunks) {
if (failedHunks.size() <= 0)
return null;
@@ -502,10 +525,6 @@ public class Patcher {
return length;
}
- public void setGenerateRejects(boolean generateRejects){
- this.fGenerateRejectFile = generateRejects;
- }
-
public void addDiff(FileDiff newDiff){
FileDiff[] temp = new FileDiff[fDiffs.length + 1];
System.arraycopy(fDiffs,0, temp, 0, fDiffs.length);
@@ -548,10 +567,6 @@ public class Patcher {
}
return null;
}
-
- public boolean isGenerateRejectFile() {
- return fGenerateRejectFile;
- }
/**
* Calculate the fuzz factor that will allow the most hunks to be matched.
@@ -591,21 +606,21 @@ public class Patcher {
for (int i = 0; i < diffs.length; i++) {
FileDiff diff = diffs[i];
FileDiffResult result = getDiffResult(diff);
- result.refresh();
+ ((WorkspaceFileDiffResult)result).refresh();
}
}
public FileDiffResult getDiffResult(FileDiff diff) {
FileDiffResult result = (FileDiffResult)diffResults.get(diff);
if (result == null) {
- result = new FileDiffResult(diff, this);
+ result = new WorkspaceFileDiffResult(diff, getConfiguration());
diffResults.put(diff, result);
}
return result;
}
- public boolean isAdjustShift() {
- return fAdjustShift;
+ public PatchConfiguration getConfiguration() {
+ return configuration;
}
/**
@@ -622,8 +637,8 @@ public class Patcher {
* Returns <code>true</code> if new value differs from old.
*/
public boolean setReversed(boolean reverse) {
- if (fReverse != reverse) {
- fReverse= reverse;
+ if (getConfiguration().isReversed() != reverse) {
+ getConfiguration().setReversed(reverse);
refresh();
return true;
}
@@ -631,15 +646,7 @@ public class Patcher {
}
public boolean isReversed() {
- return fReverse;
- }
-
- public boolean isIgnoreWhitespace() {
- return fIgnoreWhitespace;
- }
-
- public boolean isIgnoreLineDelimiter() {
- return fIgnoreLineDelimiter;
+ return getConfiguration().isReversed();
}
/**
@@ -737,4 +744,8 @@ public class Patcher {
}
return tr.getProject();
}
+
+ public static Patcher getPatcher(PatchConfiguration configuration) {
+ return (Patcher)configuration.getProperty(PROP_PATCHER);
+ }
}
diff --git a/bundles/org.eclipse.compare/plugins/org.eclipse.compare/compare/org/eclipse/compare/internal/patch/PreviewPatchPage2.java b/bundles/org.eclipse.compare/plugins/org.eclipse.compare/compare/org/eclipse/compare/internal/patch/PreviewPatchPage2.java
index 0c5bbeac5..f1930ade3 100644
--- a/bundles/org.eclipse.compare/plugins/org.eclipse.compare/compare/org/eclipse/compare/internal/patch/PreviewPatchPage2.java
+++ b/bundles/org.eclipse.compare/plugins/org.eclipse.compare/compare/org/eclipse/compare/internal/patch/PreviewPatchPage2.java
@@ -404,7 +404,7 @@ public class PreviewPatchPage2 extends WizardPage {
| GridData.GRAB_HORIZONTAL);
generateRejects.addSelectionListener(new SelectionAdapter() {
public void widgetSelected(SelectionEvent e) {
- getPatcher().setGenerateRejects(
+ getPatcher().setGenerateRejectFile(
generateRejects.getSelection());
}
});
diff --git a/bundles/org.eclipse.compare/plugins/org.eclipse.compare/compare/org/eclipse/compare/internal/patch/UnmatchedHunkTypedElement.java b/bundles/org.eclipse.compare/plugins/org.eclipse.compare/compare/org/eclipse/compare/internal/patch/UnmatchedHunkTypedElement.java
index f22c12ec3..ed719b4fa 100644
--- a/bundles/org.eclipse.compare/plugins/org.eclipse.compare/compare/org/eclipse/compare/internal/patch/UnmatchedHunkTypedElement.java
+++ b/bundles/org.eclipse.compare/plugins/org.eclipse.compare/compare/org/eclipse/compare/internal/patch/UnmatchedHunkTypedElement.java
@@ -16,6 +16,7 @@ import java.util.List;
import org.eclipse.compare.*;
import org.eclipse.compare.internal.CompareUIPlugin;
import org.eclipse.compare.internal.ContentChangeNotifier;
+import org.eclipse.compare.patch.PatchConfiguration;
import org.eclipse.core.resources.IFile;
import org.eclipse.core.runtime.CoreException;
@@ -49,7 +50,7 @@ public class UnmatchedHunkTypedElement extends HunkTypedElement implements ICont
* @see org.eclipse.compare.IEditableContent#isEditable()
*/
public boolean isEditable() {
- IFile file = getHunkResult().getDiffResult().getTargetFile();
+ IFile file = ((WorkspaceFileDiffResult)getHunkResult().getDiffResult()).getTargetFile();
return file != null && file.isAccessible();
}
@@ -65,7 +66,7 @@ public class UnmatchedHunkTypedElement extends HunkTypedElement implements ICont
* @see org.eclipse.compare.IEditableContent#setContent(byte[])
*/
public void setContent(byte[] newContent) {
- getHunkResult().getDiffResult().getPatcher().setManuallyMerged(getHunkResult().getHunk(), true);
+ getPatcher().setManuallyMerged(getHunkResult().getHunk(), true);
getPatcher().cacheContents(getDiff(), newContent);
if (changeNotifier != null)
changeNotifier.fireContentChanged();
@@ -76,7 +77,7 @@ public class UnmatchedHunkTypedElement extends HunkTypedElement implements ICont
}
private Patcher getPatcher() {
- return getHunkResult().getDiffResult().getPatcher();
+ return Patcher.getPatcher(getConfiguration());
}
/* (non-Javadoc)
@@ -88,7 +89,7 @@ public class UnmatchedHunkTypedElement extends HunkTypedElement implements ICont
return new ByteArrayInputStream(getPatcher().getCachedContents(getDiff()));
// Otherwise return the after state of the diff result
List lines = getHunkResult().getDiffResult().getAfterLines();
- String content = getPatcher().createString(lines);
+ String content = Patcher.createString(getHunkResult().getDiffResult().isPreserveLineDelimeters(), lines);
byte[] bytes = null;
if (getCharset() != null)
try {
@@ -100,4 +101,8 @@ public class UnmatchedHunkTypedElement extends HunkTypedElement implements ICont
bytes = content.getBytes();
return new ByteArrayInputStream(bytes);
}
+
+ private PatchConfiguration getConfiguration() {
+ return getHunkResult().getDiffResult().getConfiguration();
+ }
}
diff --git a/bundles/org.eclipse.compare/plugins/org.eclipse.compare/compare/org/eclipse/compare/internal/patch/WorkspaceFileDiffResult.java b/bundles/org.eclipse.compare/plugins/org.eclipse.compare/compare/org/eclipse/compare/internal/patch/WorkspaceFileDiffResult.java
new file mode 100644
index 000000000..6a334213c
--- /dev/null
+++ b/bundles/org.eclipse.compare/plugins/org.eclipse.compare/compare/org/eclipse/compare/internal/patch/WorkspaceFileDiffResult.java
@@ -0,0 +1,53 @@
+/*******************************************************************************
+ * Copyright (c) 2007 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.compare.internal.patch;
+
+import java.util.List;
+
+import org.eclipse.compare.patch.PatchConfiguration;
+import org.eclipse.core.resources.*;
+
+public class WorkspaceFileDiffResult extends FileDiffResult {
+
+ public WorkspaceFileDiffResult(FileDiff diff,
+ PatchConfiguration configuration) {
+ super(diff, configuration);
+ }
+
+ protected boolean canCreateTarget(IStorage storage) {
+ IProject project = getPatcher().getTargetProject(getDiff());
+ return project != null && project.isAccessible();
+ }
+
+ protected boolean targetExists(IStorage storage) {
+ IFile file= (IFile)storage;
+ return file != null && file.isAccessible();
+ }
+
+ protected List getLines(IStorage storage, boolean create) {
+ IFile file= getTargetFile();
+ List lines = Patcher.load(file, create);
+ return lines;
+ }
+
+ protected Patcher getPatcher() {
+ return Patcher.getPatcher(getConfiguration());
+ }
+
+ protected IFile getTargetFile() {
+ return getPatcher().getTargetFile(getDiff());
+ }
+
+ public void refresh() {
+ refresh(getTargetFile(), null);
+ }
+
+}
diff --git a/bundles/org.eclipse.compare/plugins/org.eclipse.compare/compare/org/eclipse/compare/internal/patch/WorkspacePatcher.java b/bundles/org.eclipse.compare/plugins/org.eclipse.compare/compare/org/eclipse/compare/internal/patch/WorkspacePatcher.java
index 939aab00c..c92edbbee 100644
--- a/bundles/org.eclipse.compare/plugins/org.eclipse.compare/compare/org/eclipse/compare/internal/patch/WorkspacePatcher.java
+++ b/bundles/org.eclipse.compare/plugins/org.eclipse.compare/compare/org/eclipse/compare/internal/patch/WorkspacePatcher.java
@@ -99,7 +99,7 @@ public class WorkspacePatcher extends Patcher {
// patch it and collect rejected hunks
List result= apply(diff, file, true, failed);
if (result != null)
- store(createString(result), file, new SubProgressMonitor(pm, workTicks));
+ store(createString(isPreserveLineDelimeters(), result), file, new SubProgressMonitor(pm, workTicks));
workTicks -= WORK_UNIT;
break;
case Differencer.DELETION :
@@ -110,7 +110,7 @@ public class WorkspacePatcher extends Patcher {
// patch it and collect rejected hunks
result= apply(diff, file, false, failed);
if (result != null)
- store(createString(result), file, new SubProgressMonitor(pm, workTicks));
+ store(createString(isPreserveLineDelimeters(), result), file, new SubProgressMonitor(pm, workTicks));
workTicks -= WORK_UNIT;
break;
}
diff --git a/bundles/org.eclipse.compare/plugins/org.eclipse.compare/compare/org/eclipse/compare/patch/AbstractHunk.java b/bundles/org.eclipse.compare/plugins/org.eclipse.compare/compare/org/eclipse/compare/patch/AbstractHunk.java
deleted file mode 100644
index 552f3d574..000000000
--- a/bundles/org.eclipse.compare/plugins/org.eclipse.compare/compare/org/eclipse/compare/patch/AbstractHunk.java
+++ /dev/null
@@ -1,23 +0,0 @@
-/*******************************************************************************
- * Copyright (c) 2006 IBM Corporation and others.
- * All rights reserved. This program and the accompanying materials
- * are made available under the terms of the Eclipse Public License v1.0
- * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/epl-v10.html
- *
- * Contributors:
- * IBM Corporation - initial API and implementation
- *******************************************************************************/
-package org.eclipse.compare.patch;
-
-/**
- * An abstract implementation of {@link IHunk}.
- * <p>
- * Clients may subclass this class.
- *
- * @since 3.3
- *
- */
-public abstract class AbstractHunk implements IHunk {
- // No default implementation
-}
diff --git a/bundles/org.eclipse.compare/plugins/org.eclipse.compare/compare/org/eclipse/compare/patch/ApplyPatchOperation.java b/bundles/org.eclipse.compare/plugins/org.eclipse.compare/compare/org/eclipse/compare/patch/ApplyPatchOperation.java
index f9416e30a..bba79b64c 100644
--- a/bundles/org.eclipse.compare/plugins/org.eclipse.compare/compare/org/eclipse/compare/patch/ApplyPatchOperation.java
+++ b/bundles/org.eclipse.compare/plugins/org.eclipse.compare/compare/org/eclipse/compare/patch/ApplyPatchOperation.java
@@ -62,11 +62,21 @@ public class ApplyPatchOperation implements Runnable {
* @throws CoreException if an error occurs reading the contents from the storage
*/
public static boolean isPatch(IStorage storage) throws CoreException {
+ return parsePatch(storage).length > 0;
+ }
+
+ /**
+ * Parse the given patch and return the set of file patches that it contains.
+ * @param storage the storage that contains the patch
+ * @return the set of file patches that the storage contains
+ * @throws CoreException if an error occurs reading the contents from the storage
+ */
+ public static IFilePatch[] parsePatch(IStorage storage) throws CoreException {
BufferedReader reader = Patcher.createReader(storage);
try {
PatchReader patchReader= new PatchReader();
patchReader.parse(reader);
- return patchReader.getDiffs().length > 0;
+ return patchReader.getAdjustedDiffs();
} catch (IOException e) {
throw new CoreException(new Status(IStatus.ERROR, CompareUIPlugin.PLUGIN_ID, 0, e.getMessage(), e));
} finally {
diff --git a/bundles/org.eclipse.compare/plugins/org.eclipse.compare/compare/org/eclipse/compare/patch/Attic/IFilePatch.java b/bundles/org.eclipse.compare/plugins/org.eclipse.compare/compare/org/eclipse/compare/patch/Attic/IFilePatch.java
new file mode 100644
index 000000000..e1779bbf1
--- /dev/null
+++ b/bundles/org.eclipse.compare/plugins/org.eclipse.compare/compare/org/eclipse/compare/patch/Attic/IFilePatch.java
@@ -0,0 +1,62 @@
+/*******************************************************************************
+ * Copyright (c) 2007 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.compare.patch;
+
+import org.eclipse.core.resources.IStorage;
+import org.eclipse.core.runtime.IPath;
+import org.eclipse.core.runtime.IProgressMonitor;
+
+/**
+ * A representation of a file patch that can be applied to an input stream.
+ * <p>
+ * This interface is not intended to be implemented by clients. Clients can
+ * obtain file patches by calling
+ * {@link ApplyPatchOperation#parsePatch(org.eclipse.core.resources.IStorage)}.
+ * <p>
+ * This interface is still under development and is to be considered
+ * <strong>EXPERIMENTAL</strong>.
+ * @see ApplyPatchOperation#parsePatch(org.eclipse.core.resources.IStorage)
+ * @since 3.3
+ */
+public interface IFilePatch {
+
+ /**
+ * Return the target path for this patch. The target path may differ
+ * depending on whether the patch is being reversed or not.
+ *
+ * @param configuration the patch configuration
+ * @return the target path for this patch
+ * @see PatchConfiguration#isReversed()
+ */
+ public IPath getTargetPath(PatchConfiguration configuration);
+
+ /**
+ * Apply this patch to the given file contents. The result provides the
+ * original and patch contents and also indicates whether some portions of
+ * the patch (called hunks) failed to apply.
+ *
+ * @param contents the file contents
+ * @param configuration the patch configuration
+ * @param monitor a progress monitor
+ * @return the result of the patch application
+ */
+ public IFilePatchResult apply(IStorage contents,
+ PatchConfiguration configuration, IProgressMonitor monitor);
+
+ /**
+ * Return the header information of the patch or
+ * <code>null</code> if there was no header text.
+ * The header may be multi-line.
+ * @return the header information of the patch or
+ * <code>null</code>
+ */
+ public String getHeader();
+}
diff --git a/bundles/org.eclipse.compare/plugins/org.eclipse.compare/compare/org/eclipse/compare/patch/IFilePatch.java b/bundles/org.eclipse.compare/plugins/org.eclipse.compare/compare/org/eclipse/compare/patch/IFilePatch.java
new file mode 100644
index 000000000..e1779bbf1
--- /dev/null
+++ b/bundles/org.eclipse.compare/plugins/org.eclipse.compare/compare/org/eclipse/compare/patch/IFilePatch.java
@@ -0,0 +1,62 @@
+/*******************************************************************************
+ * Copyright (c) 2007 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.compare.patch;
+
+import org.eclipse.core.resources.IStorage;
+import org.eclipse.core.runtime.IPath;
+import org.eclipse.core.runtime.IProgressMonitor;
+
+/**
+ * A representation of a file patch that can be applied to an input stream.
+ * <p>
+ * This interface is not intended to be implemented by clients. Clients can
+ * obtain file patches by calling
+ * {@link ApplyPatchOperation#parsePatch(org.eclipse.core.resources.IStorage)}.
+ * <p>
+ * This interface is still under development and is to be considered
+ * <strong>EXPERIMENTAL</strong>.
+ * @see ApplyPatchOperation#parsePatch(org.eclipse.core.resources.IStorage)
+ * @since 3.3
+ */
+public interface IFilePatch {
+
+ /**
+ * Return the target path for this patch. The target path may differ
+ * depending on whether the patch is being reversed or not.
+ *
+ * @param configuration the patch configuration
+ * @return the target path for this patch
+ * @see PatchConfiguration#isReversed()
+ */
+ public IPath getTargetPath(PatchConfiguration configuration);
+
+ /**
+ * Apply this patch to the given file contents. The result provides the
+ * original and patch contents and also indicates whether some portions of
+ * the patch (called hunks) failed to apply.
+ *
+ * @param contents the file contents
+ * @param configuration the patch configuration
+ * @param monitor a progress monitor
+ * @return the result of the patch application
+ */
+ public IFilePatchResult apply(IStorage contents,
+ PatchConfiguration configuration, IProgressMonitor monitor);
+
+ /**
+ * Return the header information of the patch or
+ * <code>null</code> if there was no header text.
+ * The header may be multi-line.
+ * @return the header information of the patch or
+ * <code>null</code>
+ */
+ public String getHeader();
+}
diff --git a/bundles/org.eclipse.compare/plugins/org.eclipse.compare/compare/org/eclipse/compare/patch/IFilePatchResult.java b/bundles/org.eclipse.compare/plugins/org.eclipse.compare/compare/org/eclipse/compare/patch/IFilePatchResult.java
new file mode 100644
index 000000000..424b58148
--- /dev/null
+++ b/bundles/org.eclipse.compare/plugins/org.eclipse.compare/compare/org/eclipse/compare/patch/IFilePatchResult.java
@@ -0,0 +1,76 @@
+/*******************************************************************************
+ * Copyright (c) 2007 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.compare.patch;
+
+import java.io.InputStream;
+
+/**
+ * A file patch result provides the results of an attempt to apply an
+ * {@link IFilePatch} to the contents of a file. *
+ * <p>
+ * This interface is not intended to be implemented by clients. Clients can
+ * obtain patch results from an {@link IFilePatch}.
+ * <p>
+ * This interface is still under development and is to be considered
+ * <strong>EXPERIMENTAL</strong>.
+ *
+ * @see IFilePatch
+ * @since 3.3
+ */
+public interface IFilePatchResult {
+
+ /**
+ * Return a stream the contains the original contents of the file before
+ * any portions of the patch have been applied.
+ * @return a stream to the original contents of the file before
+ * any portions of the patch have been applied
+ * @see #getPatchedContents()
+ */
+ public InputStream getOriginalContents();
+
+ /**
+ * Return a stream that contains the file with as much of the patch
+ * applied as possible. if {@link #hasMatches()} returns <code>false</code>
+ * then the patched contents will match the original contents. Otherwise,
+ * at least a portion of the patch could be successfully applied. if
+ * {@link #hasRejects()} returns <code>false</code>, then the entire patch was
+ * applied. Otherwise, portions could not be applied. The portions that could
+ * not be applied can be obtained by calling {@link #getRejects()}.
+ *
+ * @return a stream that contains the file with as much of the patch
+ * applied as possible.
+ */
+ public InputStream getPatchedContents();
+
+ /**
+ * Return whether the patch has portions that were successfully applied.
+ * @return whether the patch has portions that were successfully applied
+ * @see #getPatchedContents()
+ */
+ public boolean hasMatches();
+
+ /**
+ * Return whether the patch has portions that were not successfully applied.
+ * @return whether the patch has portions that were not successfully applied
+ * @see #getPatchedContents()
+ */
+ public boolean hasRejects();
+
+ /**
+ * Return the portions of the patch (referred to a hunks) that could not
+ * be applied.
+ * @return the portions of the patch (referred to a hunks) that could not
+ * be applied
+ * @see #getPatchedContents()
+ */
+ public IHunk[] getRejects();
+
+}
diff --git a/bundles/org.eclipse.compare/plugins/org.eclipse.compare/compare/org/eclipse/compare/patch/IHunk.java b/bundles/org.eclipse.compare/plugins/org.eclipse.compare/compare/org/eclipse/compare/patch/IHunk.java
index 4eb41f592..1f1840936 100644
--- a/bundles/org.eclipse.compare/plugins/org.eclipse.compare/compare/org/eclipse/compare/patch/IHunk.java
+++ b/bundles/org.eclipse.compare/plugins/org.eclipse.compare/compare/org/eclipse/compare/patch/IHunk.java
@@ -1,27 +1,55 @@
package org.eclipse.compare.patch;
+import java.io.InputStream;
+
import org.eclipse.core.runtime.IAdaptable;
/**
- * Interface that represents a hunk. A hunk is a portion of a patch.
- * It identifies where the hunk is to be located in the target file.
- * One use of this interface is a means to communicate to content merge viewers
- * that one of the sides of a compare input is a patch hunk. Clients can determine
- * which side it is by adapting the side to this interface (see {@link IAdaptable}.
+ * Interface that represents a hunk. A hunk is a portion of a patch. It
+ * identifies where the hunk is to be located in the target file. One use of
+ * this interface is a means to communicate to content merge viewers that one of
+ * the sides of a compare input is a patch hunk. Clients can determine which
+ * side it is by adapting the side to this interface (see {@link IAdaptable}.
* <p>
- * This interface is not intended to be implemented by clients but should instead
- * subclass {@link AbstractHunk}.
+ * This interface is not intended to be implemented by clients but can be
+ * obtained from an {@link IFilePatchResult}
* <p>
- * This interface is
- * still under development and is to be considered <strong>EXPERIMENTAL</strong>.
- * since 3.3
- *
+ * This interface is still under development and is to be considered
+ * <strong>EXPERIMENTAL</strong>.
+ *
+ * @since 3.3
+ *
*/
public interface IHunk {
+
+ /**
+ * Return a label that can be used to describe the hunk.
+ * @return a label that can be used to describe the hunk
+ */
+ public String getLabel();
/**
* Return the start position of the hunk in the target file.
+ *
* @return the start position of the hunk in the target file.
*/
- int getStartPosition();
+ public int getStartPosition();
+
+ /**
+ * Return the original contents from which the hunk was generated.
+ * The returned contents usually only represent a portion of the
+ * file from which the hunk was generated.
+ * @return the original contents from which the hunk was generated
+ */
+ public InputStream getOriginalContents();
+
+ /**
+ * Return the contents that contain the modifications for this hunk.
+ * The returned contents usually only represent a portion of the
+ * file that was modified.
+ * @return the contents that contain the modifications for this hunk
+ */
+ public InputStream getPatchedContents();
+
+
}
diff --git a/bundles/org.eclipse.compare/plugins/org.eclipse.compare/compare/org/eclipse/compare/patch/PatchConfiguration.java b/bundles/org.eclipse.compare/plugins/org.eclipse.compare/compare/org/eclipse/compare/patch/PatchConfiguration.java
new file mode 100644
index 000000000..71da43090
--- /dev/null
+++ b/bundles/org.eclipse.compare/plugins/org.eclipse.compare/compare/org/eclipse/compare/patch/PatchConfiguration.java
@@ -0,0 +1,124 @@
+/*******************************************************************************
+ * Copyright (c) 2007 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.compare.patch;
+
+import java.util.HashMap;
+
+/**
+ * A patch configuration allows clients to set parameters that control how a patch
+ * is applied.
+ * <p>
+ * This class may be instantiated by clients but is not intended to be subclassed.
+ * <p>
+ * This interface is still under development and is to be considered
+ * <strong>EXPERIMENTAL</strong>.
+ * @see IFilePatch
+ * @since 3.3
+ */
+public class PatchConfiguration {
+
+ private int fStripPrefixSegments;
+ private int fFuzz;
+ private boolean fIgnoreWhitespace= false;
+ private boolean fReverse= false;
+ private HashMap properties = new HashMap();
+
+ /**
+ * Return whether the patch should be reversed when applied.
+ * @return whether the patch should be reversed when applied
+ */
+ public boolean isReversed() {
+ return fReverse;
+ }
+
+ /**
+ * Set whether the patch should be reversed when applied.
+ * @param reversed whether the patch should be reversed when applied
+ */
+ public void setReversed(boolean reversed) {
+ this.fReverse = reversed;
+ }
+
+ /**
+ * Return the number of prefix segments to be stripped when attempting
+ * to apply a patch.
+ * @return the number of prefix segments to be stripped when attempting
+ * to apply a patch
+ */
+ public int getPrefixSegmentStripCount() {
+ return fStripPrefixSegments;
+ }
+
+ /**
+ * Set the number of prefix segments to be stripped when attempting
+ * to apply a patch.
+ * @param stripCount the number of prefix segments to be stripped when attempting
+ * to apply a patch.
+ */
+ public void setPrefixSegmentStripCount(int stripCount) {
+ this.fStripPrefixSegments = stripCount;
+ }
+
+ /**
+ * Return the fuzz factor to be used when applying a patch.
+ * If the fuzz factor is set to -1, then the patcher is to make a best
+ * effort to apply the patch by adjusting the fuzz factor
+ * accordingly.
+ * @return the fuzz factor to be used when applying a patch.
+ */
+ public int getFuzz() {
+ return fFuzz;
+ }
+
+ /**
+ * Set the fuzz factor to be used when applying a patch.
+ * @param fuzz the fuzz factor to be used when applying a patch.
+ */
+ public void setFuzz(int fuzz) {
+ fFuzz = fuzz;
+ }
+
+ /**
+ * Return whether whitespace should be ignored.
+ * @return whether whitespace should be ignored
+ */
+ public boolean isIgnoreWhitespace() {
+ return fIgnoreWhitespace;
+ }
+
+ /**
+ * Set whether whitespace should be ignored
+ * @param ignoreWhitespace whether whitespace should be ignored
+ */
+ public void setIgnoreWhitespace(boolean ignoreWhitespace) {
+ fIgnoreWhitespace = ignoreWhitespace;
+ }
+
+ /**
+ * Return the property associated with the given key or
+ * <code>null</code> if there is no property for the key.
+ * @param key the key
+ * @return the property associated with the given key or
+ * <code>null</code>
+ */
+ public Object getProperty(String key) {
+ return properties.get(key);
+ }
+
+ /**
+ * Set the property associated with the given key
+ * @param key the key
+ * @param value the value to be associated with the key
+ */
+ public void setProperty(String key, Object value) {
+ properties.put(key, value);
+ }
+}

Back to the top