Copyright (c) 2006, 2011 IBM Corporation and others. This program and the accompanying materials are made available under the terms of the Eclipse Public License 2.0 which accompanies this distribution, and is available at https://www.eclipse.org/legal/epl-2.0/ SPDX-License-Identifier: EPL-2.0 Contributors: IBM Corporation - initial API and implementation
/******************************************************************************* * Copyright (c) 2006, 2011 IBM Corporation and others. * * This program and the accompanying materials * are made available under the terms of the Eclipse Public License 2.0 * which accompanies this distribution, and is available at * https://www.eclipse.org/legal/epl-2.0/ * * SPDX-License-Identifier: EPL-2.0 * * Contributors: * IBM Corporation - initial API and implementation *******************************************************************************/
package org.eclipse.compare.internal.core.patch; import java.util.ArrayList; import java.util.Iterator; import java.util.List; import org.eclipse.compare.patch.IFilePatch2; import org.eclipse.compare.patch.IFilePatchResult; import org.eclipse.compare.patch.IHunk; import org.eclipse.compare.patch.PatchConfiguration; import org.eclipse.compare.patch.ReaderCreator; import org.eclipse.core.runtime.IPath; import org.eclipse.core.runtime.IProgressMonitor; import org.eclipse.core.runtime.Path;
A file diff represents a set of hunks that were associated with the same path in a patch file.
/** * A file diff represents a set of hunks that were associated with the * same path in a patch file. */
public class FilePatch2 implements IFilePatch2 {
Difference constant (value 1) indicating one side was added.
/** * Difference constant (value 1) indicating one side was added. */
public static final int ADDITION= 1;
Difference constant (value 2) indicating one side was removed.
/** * Difference constant (value 2) indicating one side was removed. */
public static final int DELETION= 2;
Difference constant (value 3) indicating side changed.
/** * Difference constant (value 3) indicating side changed. */
public static final int CHANGE= 3; private IPath fOldPath, fNewPath; private long oldDate, newDate; private List<Hunk> fHunks= new ArrayList<>(); private DiffProject fProject; //the project that contains this diff private String header; private int addedLines, removedLines;
Create a file diff for the given path and date information.
Params:
  • oldPath – the path of the before state of the file
  • oldDate – the timestamp of the before state
  • newPath – the path of the after state
  • newDate – the timestamp of the after state
/** * Create a file diff for the given path and date information. * @param oldPath the path of the before state of the file * @param oldDate the timestamp of the before state * @param newPath the path of the after state * @param newDate the timestamp of the after state */
public FilePatch2(IPath oldPath, long oldDate, IPath newPath, long newDate) { this.fOldPath= oldPath; this.oldDate = oldDate; this.fNewPath= newPath; this.newDate = newDate; }
Return the parent project or null if there isn't one.
Returns:the parent project or null
/** * Return the parent project or <code>null</code> if there isn't one. * @return the parent project or <code>null</code> */
public DiffProject getProject() { return this.fProject; }
Set the project of this diff to the given project. This method should only be called from DiffProject.add(FilePatch2)
Params:
  • diffProject – the parent project
/** * Set the project of this diff to the given project. * This method should only be called from * {@link DiffProject#add(FilePatch2)} * @param diffProject the parent project */
void setProject(DiffProject diffProject) { if (this.fProject == diffProject) return; if (this.fProject != null) this.fProject.remove(this); this.fProject= diffProject; }
Get the path of the file diff.
Params:
  • reverse – whether the path of the before state or after state should be used
Returns:the path of the file diff
/** * Get the path of the file diff. * @param reverse whether the path of the before state or after state * should be used * @return the path of the file diff */
public IPath getPath(boolean reverse) { if (getDiffType(reverse) == ADDITION) { if (reverse) return this.fOldPath; return this.fNewPath; } if (reverse && this.fNewPath != null) return this.fNewPath; if (this.fOldPath != null) return this.fOldPath; return this.fNewPath; }
Add the hunk to this file diff.
Params:
  • hunk – the hunk
/** * Add the hunk to this file diff. * @param hunk the hunk */
public void add(Hunk hunk) { this.fHunks.add(hunk); hunk.setParent(this); }
Remove the hunk from this file diff
Params:
  • hunk – the hunk
/** * Remove the hunk from this file diff * @param hunk the hunk */
protected void remove(Hunk hunk) { this.fHunks.remove(hunk); }
Returns the hunks associated with this file diff.
Returns:the hunks associated with this file diff
/** * Returns the hunks associated with this file diff. * @return the hunks associated with this file diff */
@Override public IHunk[] getHunks() { return this.fHunks.toArray(new IHunk[this.fHunks.size()]); }
Returns the number of hunks associated with this file diff.
Returns:the number of hunks associated with this file diff
/** * Returns the number of hunks associated with this file diff. * @return the number of hunks associated with this file diff */
public int getHunkCount() { return this.fHunks.size(); }
Returns the difference type of this file diff.
Params:
  • reverse – whether the patch is being reversed
Returns:the type of this file diff
/** * Returns the difference type of this file diff. * @param reverse whether the patch is being reversed * @return the type of this file diff */
public int getDiffType(boolean reverse) { if (this.fHunks.size() == 1) { boolean add = false; boolean delete = false; Iterator<Hunk> iter = this.fHunks.iterator(); while (iter.hasNext()){ Hunk hunk = iter.next(); int type =hunk.getHunkType(reverse); if (type == ADDITION){ add = true; } else if (type == DELETION ){ delete = true; } } if (add && !delete){ return ADDITION; } else if (!add && delete){ return DELETION; } } return CHANGE; }
Return the path of this file diff with the specified number of leading segments striped.
Params:
  • strip – the number of leading segments to strip from the path
  • reverse – whether the patch is being reversed
Returns:the path of this file diff with the specified number of leading segments striped
/** * Return the path of this file diff with the specified number * of leading segments striped. * @param strip the number of leading segments to strip from the path * @param reverse whether the patch is being reversed * @return the path of this file diff with the specified number * of leading segments striped */
public IPath getStrippedPath(int strip, boolean reverse) { IPath path= getPath(reverse); if (strip > 0 && strip < path.segmentCount()) path= path.removeFirstSegments(strip); return path; }
Return the segment count of the path of this file diff.
Returns:the segment count of the path of this file diff
/** * Return the segment count of the path of this file diff. * @return the segment count of the path of this file diff */
public int segmentCount() { //Update prefix count - go through all of the diffs and find the smallest //path segment contained in all diffs. int length= 99; if (this.fOldPath != null) length= Math.min(length, this.fOldPath.segmentCount()); if (this.fNewPath != null) length= Math.min(length, this.fNewPath.segmentCount()); return length; } @Override public IFilePatchResult apply(ReaderCreator content, PatchConfiguration configuration, IProgressMonitor monitor) { FileDiffResult result = new FileDiffResult(this, configuration); result.refresh(content, monitor); return result; } @Override public IPath getTargetPath(PatchConfiguration configuration) { return getStrippedPath(configuration.getPrefixSegmentStripCount(), configuration.isReversed()); } public FilePatch2 asRelativeDiff() { if (this.fProject == null) return this; IPath adjustedOldPath = null; if (this.fOldPath != null) { adjustedOldPath = new Path(null, this.fProject.getName()).append(this.fOldPath); } IPath adjustedNewPath = null; if (this.fNewPath != null) { adjustedNewPath = new Path(null, this.fProject.getName()).append(this.fNewPath); } FilePatch2 diff = create(adjustedOldPath, 0, adjustedNewPath, 0); for (Hunk hunk : this.fHunks) { // Creating the hunk adds it to the parent diff new Hunk(diff, hunk); } return diff; } protected FilePatch2 create(IPath oldPath, long oldDate, IPath newPath, long newDate) { return new FilePatch2(oldPath, oldDate, newPath, newDate); } public void setHeader(String header) { this.header = header; } @Override public String getHeader() { return this.header; } @Override public long getBeforeDate() { return this.oldDate; } @Override public long getAfterDate() { return this.newDate; } public void setAddedLines(int addedLines) { this.addedLines = addedLines; } public void setRemovedLines(int removedLines) { this.removedLines = removedLines; } public int getAddedLines() { return this.addedLines; } public int getRemovedLines() { return this.removedLines; } }