Merge "Use Diffy as avatar for the Gerrit server itself"
diff --git a/gerrit-gwtui/src/main/java/com/google/gerrit/client/patches/SideBySideTable.java b/gerrit-gwtui/src/main/java/com/google/gerrit/client/patches/SideBySideTable.java
index b10637a..55fb55b 100644
--- a/gerrit-gwtui/src/main/java/com/google/gerrit/client/patches/SideBySideTable.java
+++ b/gerrit-gwtui/src/main/java/com/google/gerrit/client/patches/SideBySideTable.java
@@ -187,7 +187,7 @@
lines.add(new SkippedLine(lastA, lastB, b.size() - lastB));
}
}
- }else{
+ } else {
// Display the patch header for binary
for (final String line : script.getPatchHeader()) {
appendFileHeader(nc, line);
diff --git a/gerrit-gwtui/src/main/java/com/google/gerrit/client/patches/UnifiedDiffTable.java b/gerrit-gwtui/src/main/java/com/google/gerrit/client/patches/UnifiedDiffTable.java
index a4a089e..be1846f 100644
--- a/gerrit-gwtui/src/main/java/com/google/gerrit/client/patches/UnifiedDiffTable.java
+++ b/gerrit-gwtui/src/main/java/com/google/gerrit/client/patches/UnifiedDiffTable.java
@@ -226,94 +226,18 @@
appendFileHeader(nc, line);
}
final ArrayList<PatchLine> lines = new ArrayList<PatchLine>();
- if (!isDisplayBinary) {
- final SparseHtmlFile a = getSparseHtmlFileA(script);
- final SparseHtmlFile b = getSparseHtmlFileB(script);
+
+ if (hasDifferences(script)) {
if (script.getDisplayMethodA() == DisplayMethod.IMG
|| script.getDisplayMethodB() == DisplayMethod.IMG) {
- final String rawBase = GWT.getHostPageBaseURL() + "cat/";
-
- nc.openTr();
- nc.setAttribute("valign", "center");
- nc.setAttribute("align", "center");
-
- nc.openTd();
- nc.nbsp();
- nc.closeTd();
-
- nc.openTd();
- nc.nbsp();
- nc.closeTd();
-
- nc.openTd();
- nc.nbsp();
- nc.closeTd();
-
- nc.openTd();
- if (script.getDisplayMethodA() == DisplayMethod.IMG) {
- if (idSideA == null) {
- appendImgTag(nc, rawBase + KeyUtil.encode(patchKey.toString()) + "^1");
- } else {
- Patch.Key k = new Patch.Key(idSideA, patchKey.get());
- appendImgTag(nc, rawBase + KeyUtil.encode(k.toString()) + "^0");
- }
- }
- if (script.getDisplayMethodB() == DisplayMethod.IMG) {
- appendImgTag(nc, rawBase + KeyUtil.encode(patchKey.toString()) + "^0");
- }
- nc.closeTd();
-
- nc.closeTr();
+ appendImageDifferences(script, nc);
+ } else if (!isDisplayBinary) {
+ appendTextDifferences(script, nc, lines);
}
-
- if (hasDifferences(script)) {
- final boolean syntaxHighlighting =
- script.getDiffPrefs().isSyntaxHighlighting();
- for (final EditList.Hunk hunk : script.getHunks()) {
- appendHunkHeader(nc, hunk);
- while (hunk.next()) {
- if (hunk.isContextLine()) {
- openLine(nc);
- appendLineNumberForSideA(nc, hunk.getCurA());
- appendLineNumberForSideB(nc, hunk.getCurB());
- appendLineText(nc, false, CONTEXT, a, hunk.getCurA());
- closeLine(nc);
- hunk.incBoth();
- lines.add(new PatchLine(CONTEXT, hunk.getCurA(), hunk.getCurB()));
-
- } else if (hunk.isDeletedA()) {
- openLine(nc);
- appendLineNumberForSideA(nc, hunk.getCurA());
- padLineNumberForSideB(nc);
- appendLineText(nc, syntaxHighlighting, DELETE, a, hunk.getCurA());
- closeLine(nc);
- hunk.incA();
- lines.add(new PatchLine(DELETE, hunk.getCurA(), -1));
- if (a.size() == hunk.getCurA()
- && script.getA().isMissingNewlineAtEnd()) {
- appendNoLF(nc);
- }
-
- } else if (hunk.isInsertedB()) {
- openLine(nc);
- padLineNumberForSideA(nc);
- appendLineNumberForSideB(nc, hunk.getCurB());
- appendLineText(nc, syntaxHighlighting, INSERT, b, hunk.getCurB());
- closeLine(nc);
- hunk.incB();
- lines.add(new PatchLine(INSERT, -1, hunk.getCurB()));
- if (b.size() == hunk.getCurB()
- && script.getB().isMissingNewlineAtEnd()) {
- appendNoLF(nc);
- }
- }
- }
- }
- }
- }
- if (!hasDifferences(script)) {
+ } else {
appendNoDifferences(nc);
}
+
resetHtml(nc);
populateTableHeader(script, detail);
if (hasDifferences(script)) {
@@ -347,6 +271,102 @@
}
}
+ private void appendImageLine(final SafeHtmlBuilder nc, final String url,
+ final boolean syntaxHighlighting, final boolean isInsert) {
+ nc.openTr();
+ nc.setAttribute("valign", "center");
+ nc.setAttribute("align", "center");
+
+ nc.openTd();
+ nc.setStyleName(Gerrit.RESOURCES.css().iconCell());
+ nc.closeTd();
+
+ padLineNumberForSideA(nc);
+ padLineNumberForSideB(nc);
+
+ nc.openTd();
+ nc.setStyleName(Gerrit.RESOURCES.css().fileLine());
+ if (isInsert) {
+ setStyleInsert(nc, syntaxHighlighting);
+ } else {
+ setStyleDelete(nc, syntaxHighlighting);
+ }
+ appendImgTag(nc, url);
+ nc.closeTd();
+
+ nc.closeTr();
+ }
+
+ private void appendImageDifferences(final PatchScript script,
+ final SafeHtmlBuilder nc) {
+ final boolean syntaxHighlighting =
+ script.getDiffPrefs().isSyntaxHighlighting();
+ final String rawBase = GWT.getHostPageBaseURL() + "cat/";
+
+ if (script.getDisplayMethodA() == DisplayMethod.IMG) {
+ final String url;
+ if (idSideA == null) {
+ url = rawBase + KeyUtil.encode(patchKey.toString()) + "^1";
+ } else {
+ Patch.Key k = new Patch.Key(idSideA, patchKey.get());
+ url = rawBase + KeyUtil.encode(k.toString()) + "^0";
+ }
+ appendImageLine(nc, url, syntaxHighlighting, false);
+ }
+ if (script.getDisplayMethodB() == DisplayMethod.IMG) {
+ final String url = rawBase + KeyUtil.encode(patchKey.toString()) + "^0";
+ appendImageLine(nc, url, syntaxHighlighting, true);
+ }
+ }
+
+ private void appendTextDifferences(final PatchScript script,
+ final SafeHtmlBuilder nc, final ArrayList<PatchLine> lines) {
+ final SparseHtmlFile a = getSparseHtmlFileA(script);
+ final SparseHtmlFile b = getSparseHtmlFileB(script);
+ final boolean syntaxHighlighting =
+ script.getDiffPrefs().isSyntaxHighlighting();
+ for (final EditList.Hunk hunk : script.getHunks()) {
+ appendHunkHeader(nc, hunk);
+ while (hunk.next()) {
+ if (hunk.isContextLine()) {
+ openLine(nc);
+ appendLineNumberForSideA(nc, hunk.getCurA());
+ appendLineNumberForSideB(nc, hunk.getCurB());
+ appendLineText(nc, false, CONTEXT, a, hunk.getCurA());
+ closeLine(nc);
+ hunk.incBoth();
+ lines.add(new PatchLine(CONTEXT, hunk.getCurA(), hunk.getCurB()));
+
+ } else if (hunk.isDeletedA()) {
+ openLine(nc);
+ appendLineNumberForSideA(nc, hunk.getCurA());
+ padLineNumberForSideB(nc);
+ appendLineText(nc, syntaxHighlighting, DELETE, a, hunk.getCurA());
+ closeLine(nc);
+ hunk.incA();
+ lines.add(new PatchLine(DELETE, hunk.getCurA(), -1));
+ if (a.size() == hunk.getCurA()
+ && script.getA().isMissingNewlineAtEnd()) {
+ appendNoLF(nc);
+ }
+
+ } else if (hunk.isInsertedB()) {
+ openLine(nc);
+ padLineNumberForSideA(nc);
+ appendLineNumberForSideB(nc, hunk.getCurB());
+ appendLineText(nc, syntaxHighlighting, INSERT, b, hunk.getCurB());
+ closeLine(nc);
+ hunk.incB();
+ lines.add(new PatchLine(INSERT, -1, hunk.getCurB()));
+ if (b.size() == hunk.getCurB()
+ && script.getB().isMissingNewlineAtEnd()) {
+ appendNoLF(nc);
+ }
+ }
+ }
+ }
+ }
+
@Override
public void display(final CommentDetail cd, boolean expandComments) {
if (cd.isEmpty()) {
@@ -519,6 +539,22 @@
}
}
+ private void setStyleDelete(final SafeHtmlBuilder m,
+ boolean syntaxHighlighting) {
+ m.addStyleName(Gerrit.RESOURCES.css().diffTextDELETE());
+ if (syntaxHighlighting) {
+ m.addStyleName(Gerrit.RESOURCES.css().fileLineDELETE());
+ }
+ }
+
+ private void setStyleInsert(final SafeHtmlBuilder m,
+ boolean syntaxHighlighting) {
+ m.addStyleName(Gerrit.RESOURCES.css().diffTextINSERT());
+ if (syntaxHighlighting) {
+ m.addStyleName(Gerrit.RESOURCES.css().fileLineINSERT());
+ }
+ }
+
private void appendLineText(final SafeHtmlBuilder m,
boolean syntaxHighlighting, final PatchLine.Type type,
final SparseHtmlFile src, final int i) {
@@ -533,18 +569,12 @@
m.append(text);
break;
case DELETE:
- m.addStyleName(Gerrit.RESOURCES.css().diffTextDELETE());
- if (syntaxHighlighting) {
- m.addStyleName(Gerrit.RESOURCES.css().fileLineDELETE());
- }
+ setStyleDelete(m, syntaxHighlighting);
m.append("-");
m.append(text);
break;
case INSERT:
- m.addStyleName(Gerrit.RESOURCES.css().diffTextINSERT());
- if (syntaxHighlighting) {
- m.addStyleName(Gerrit.RESOURCES.css().fileLineINSERT());
- }
+ setStyleInsert(m, syntaxHighlighting);
m.append("+");
m.append(text);
break;
diff --git a/gerrit-server/src/main/java/com/google/gerrit/server/MimeUtilFileTypeRegistry.java b/gerrit-server/src/main/java/com/google/gerrit/server/MimeUtilFileTypeRegistry.java
index 792c1e7..b271d6a 100644
--- a/gerrit-server/src/main/java/com/google/gerrit/server/MimeUtilFileTypeRegistry.java
+++ b/gerrit-server/src/main/java/com/google/gerrit/server/MimeUtilFileTypeRegistry.java
@@ -60,6 +60,38 @@
mimeUtil.registerMimeDetector(name);
}
+
+ /**
+ * Get specificity of mime types with generic types forced to low values
+ *
+ * "application/octet-stream" is forced to -1.
+ * "text/plain" is forced to 0.
+ * All other mime types return the specificity reported by mimeType itself.
+ *
+ * @param mimeType The mimeType to get the corrected specificity for.
+ * @return The corrected specificity.
+ */
+ private int getCorrectedMimeSpecificity(MimeType mimeType) {
+ // Although the documentation of MimeType's getSpecificity claims that for
+ // example "application/octet-stream" always has a specificity of 0, it
+ // effectively returns 1 for us. This causes problems when trying to get
+ // the correct mime type via sorting. For example in
+ // [application/octet-stream, image/x-icon] both mime types come with
+ // specificity 1 for us. Hence, getMimeType below may end up using
+ // application/octet-stream instead of the more specific image/x-icon.
+ // Therefore, we have to force the specificity of generic types below the
+ // default of 1.
+ //
+ final String mimeTypeStr = mimeType.toString();
+ if (mimeTypeStr.equals("application/octet-stream")) {
+ return -1;
+ }
+ if (mimeTypeStr.equals("text/plain")) {
+ return 0;
+ }
+ return mimeType.getSpecificity();
+ }
+
@SuppressWarnings("unchecked")
public MimeType getMimeType(final String path, final byte[] content) {
Set<MimeType> mimeTypes = new HashSet<MimeType>();
@@ -84,7 +116,7 @@
Collections.sort(types, new Comparator<MimeType>() {
@Override
public int compare(MimeType a, MimeType b) {
- return b.getSpecificity() - a.getSpecificity();
+ return getCorrectedMimeSpecificity(b) - getCorrectedMimeSpecificity(a);
}
});
return types.get(0);