summaryrefslogtreecommitdiffstatsabout
diff options
context:
space:
mode:
authorKevin Sawicki2011-04-23 13:25:28 (EDT)
committer Chris Aniszczyk2011-04-28 13:07:30 (EDT)
commit27e3836c26d61419880be117e3a6131a034c3d44 (patch)
tree71c966a87685ad6e9fa8b091ec5f71b9ea4511da
parentbfc867ee6ee0ae1c9b9c6fa24db09eec141919eb (diff)
downloadegit-27e3836c26d61419880be117e3a6131a034c3d44.zip
egit-27e3836c26d61419880be117e3a6131a034c3d44.tar.gz
egit-27e3836c26d61419880be117e3a6131a034c3d44.tar.bz2
Add diff formatter that generates a list of style rangesrefs/changes/48/3148/7
This class will be used for a general purpose diff viewer available as a tab in the commit viewer. Bug: 343000 Change-Id: Ic2eb3e178f5a049154bd5744da3010fa791a9933 Signed-off-by: Kevin Sawicki <kevin@github.com> Signed-off-by: Chris Aniszczyk <caniszczyk@gmail.com>
-rw-r--r--org.eclipse.egit.ui.test/src/org/eclipse/egit/ui/test/commit/DiffStyleRangeFormatterTest.java79
-rw-r--r--org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/commit/DiffStyleRangeFormatter.java208
2 files changed, 287 insertions, 0 deletions
diff --git a/org.eclipse.egit.ui.test/src/org/eclipse/egit/ui/test/commit/DiffStyleRangeFormatterTest.java b/org.eclipse.egit.ui.test/src/org/eclipse/egit/ui/test/commit/DiffStyleRangeFormatterTest.java
new file mode 100644
index 0000000..64cc3ba
--- /dev/null
+++ b/org.eclipse.egit.ui.test/src/org/eclipse/egit/ui/test/commit/DiffStyleRangeFormatterTest.java
@@ -0,0 +1,79 @@
+/*******************************************************************************
+ * Copyright (c) 2011 GitHub Inc.
+ * 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:
+ * Kevin Sawicki (GitHub Inc.) - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.egit.ui.test.commit;
+
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertTrue;
+
+import java.io.File;
+
+import org.eclipse.egit.core.Activator;
+import org.eclipse.egit.ui.common.LocalRepositoryTestCase;
+import org.eclipse.egit.ui.internal.commit.DiffStyleRangeFormatter;
+import org.eclipse.egit.ui.internal.commit.DiffStyleRangeFormatter.DiffStyleRange;
+import org.eclipse.jface.text.Document;
+import org.eclipse.jface.text.IDocument;
+import org.eclipse.jgit.lib.Constants;
+import org.eclipse.jgit.lib.Repository;
+import org.eclipse.jgit.revwalk.RevCommit;
+import org.eclipse.jgit.revwalk.RevWalk;
+import org.junit.BeforeClass;
+import org.junit.Test;
+
+/**
+ * Unit tests for {@link DiffStyleRangeFormatter}
+ */
+public class DiffStyleRangeFormatterTest extends LocalRepositoryTestCase {
+
+ private static Repository repository;
+
+ private static RevCommit commit;
+
+ @BeforeClass
+ public static void setup() throws Exception {
+ File repoFile = createProjectAndCommitToRepository();
+ assertNotNull(repoFile);
+ repository = Activator.getDefault().getRepositoryCache()
+ .lookupRepository(repoFile);
+ assertNotNull(repository);
+
+ RevWalk walk = new RevWalk(repository);
+ try {
+ commit = walk.parseCommit(repository.resolve(Constants.HEAD));
+ assertNotNull(commit);
+ walk.parseBody(commit.getParent(0));
+ } finally {
+ walk.release();
+ }
+ }
+
+ @Test
+ public void testRanges() throws Exception {
+ IDocument document = new Document();
+ DiffStyleRangeFormatter formatter = new DiffStyleRangeFormatter(
+ document);
+ formatter.setRepository(repository);
+ formatter.format(commit.getTree(), commit.getParent(0).getTree());
+ assertTrue(document.getLength() > 0);
+ DiffStyleRange[] ranges = formatter.getRanges();
+ assertNotNull(ranges);
+ assertTrue(ranges.length > 0);
+ for (DiffStyleRange range : ranges) {
+ assertNotNull(range);
+ assertNotNull(range.diffType);
+ assertTrue(range.start >= 0);
+ assertTrue(range.length >= 0);
+ assertTrue(range.start < document.getLength());
+ }
+
+ }
+
+}
diff --git a/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/commit/DiffStyleRangeFormatter.java b/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/commit/DiffStyleRangeFormatter.java
new file mode 100644
index 0000000..98559e1
--- /dev/null
+++ b/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/commit/DiffStyleRangeFormatter.java
@@ -0,0 +1,208 @@
+/*******************************************************************************
+ * Copyright (c) 2011 GitHub Inc.
+ * 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:
+ * Kevin Sawicki (GitHub Inc.) - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.egit.ui.internal.commit;
+
+import java.io.IOException;
+import java.io.OutputStream;
+import java.util.ArrayList;
+import java.util.List;
+
+import org.eclipse.egit.ui.internal.CompareUtils;
+import org.eclipse.egit.ui.internal.commit.DiffStyleRangeFormatter.DiffStyleRange.Type;
+import org.eclipse.egit.ui.internal.history.FileDiff;
+import org.eclipse.jface.text.BadLocationException;
+import org.eclipse.jface.text.IDocument;
+import org.eclipse.jgit.diff.DiffFormatter;
+import org.eclipse.jgit.diff.RawText;
+import org.eclipse.jgit.lib.Repository;
+import org.eclipse.swt.custom.StyleRange;
+import org.eclipse.swt.graphics.Color;
+
+/**
+ * Diff style range formatter class that builds up a list of
+ * {@link DiffStyleRange} instances as each {@link FileDiff} is being written to
+ * an {@link IDocument}.
+ */
+public class DiffStyleRangeFormatter extends DiffFormatter {
+
+ /**
+ * Diff style range
+ */
+ public static class DiffStyleRange extends StyleRange {
+
+ /**
+ * Diff type
+ */
+ public enum Type {
+
+ /**
+ * Added line
+ */
+ ADD,
+
+ /**
+ * Removed line
+ */
+ REMOVE,
+
+ /**
+ * Hunk line
+ */
+ HUNK,
+
+ /**
+ * Other line
+ */
+ OTHER,
+
+ }
+
+ /**
+ * Diff type
+ */
+ public Type diffType = Type.OTHER;
+
+ /**
+ * Line background
+ */
+ public Color lineBackground = null;
+
+ public boolean similarTo(StyleRange style) {
+ return super.similarTo(style) && style instanceof DiffStyleRange
+ && diffType == ((DiffStyleRange) style).diffType;
+ }
+ }
+
+ private static class DocumentOutputStream extends OutputStream {
+
+ private String charset;
+
+ private IDocument document;
+
+ private int offset;
+
+ public DocumentOutputStream(IDocument document, int offset) {
+ this.document = document;
+ this.offset = offset;
+ }
+
+ private void write(String content) throws IOException {
+ try {
+ this.document.replace(this.offset, 0, content);
+ this.offset += content.length();
+ } catch (BadLocationException e) {
+ throw new IOException(e);
+ }
+ }
+
+ public void write(byte[] b, int off, int len) throws IOException {
+ if (charset == null)
+ write(new String(b, off, len));
+ else
+ write(new String(b, off, len, charset));
+ }
+
+ public void write(byte[] b) throws IOException {
+ write(b, 0, b.length);
+ }
+
+ public void write(int b) throws IOException {
+ write(new byte[] { (byte) b });
+ }
+ }
+
+ private DocumentOutputStream stream;
+
+ private List<DiffStyleRange> ranges = new ArrayList<DiffStyleRange>();
+
+ /**
+ * @param document
+ * @param offset
+ */
+ public DiffStyleRangeFormatter(IDocument document, int offset) {
+ super(new DocumentOutputStream(document, offset));
+ this.stream = (DocumentOutputStream) getOutputStream();
+ }
+
+ /**
+ * @param document
+ */
+ public DiffStyleRangeFormatter(IDocument document) {
+ this(document, document.getLength());
+ }
+
+ /**
+ * Write diff
+ *
+ * @param repository
+ * @param diff
+ * @return this formatter
+ * @throws IOException
+ */
+ public DiffStyleRangeFormatter write(Repository repository, FileDiff diff)
+ throws IOException {
+ this.stream.charset = CompareUtils.getResourceEncoding(repository,
+ diff.getPath());
+ diff.outputDiff(null, repository, this, true);
+ flush();
+ return this;
+ }
+
+ /**
+ * Get diff style ranges
+ *
+ * @return non-null but possibly empty array
+ */
+ public DiffStyleRange[] getRanges() {
+ return this.ranges.toArray(new DiffStyleRange[this.ranges.size()]);
+ }
+
+ /**
+ * Create and add diff style range
+ *
+ * @param type
+ * @return added range
+ */
+ protected DiffStyleRange addRange(Type type) {
+ DiffStyleRange range = new DiffStyleRange();
+ range.start = stream.offset;
+ range.diffType = type;
+ ranges.add(range);
+ return range;
+ }
+
+ /**
+ * @see org.eclipse.jgit.diff.DiffFormatter#writeHunkHeader(int, int, int,
+ * int)
+ */
+ protected void writeHunkHeader(int aStartLine, int aEndLine,
+ int bStartLine, int bEndLine) throws IOException {
+ DiffStyleRange range = addRange(Type.HUNK);
+ super.writeHunkHeader(aStartLine, aEndLine, bStartLine, bEndLine);
+ range.length = stream.offset - range.start;
+ }
+
+ /**
+ * @see org.eclipse.jgit.diff.DiffFormatter#writeLine(char,
+ * org.eclipse.jgit.diff.RawText, int)
+ */
+ protected void writeLine(char prefix, RawText text, int cur)
+ throws IOException {
+ if (prefix == ' ')
+ super.writeLine(prefix, text, cur);
+ else {
+ DiffStyleRange range = addRange(prefix == '+' ? Type.ADD
+ : Type.REMOVE);
+ super.writeLine(prefix, text, cur);
+ range.length = stream.offset - range.start;
+ }
+ }
+}