Java tutorial
// Copyright 2012 Google Inc. All Rights Reserved. // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. package com.google.gitiles; import static com.google.common.base.Preconditions.checkNotNull; import com.google.common.base.Charsets; import com.google.common.collect.ImmutableMap; import org.apache.commons.lang3.StringEscapeUtils; import org.eclipse.jgit.diff.DiffEntry; import org.eclipse.jgit.diff.DiffFormatter; import org.eclipse.jgit.diff.RawText; import org.eclipse.jgit.patch.FileHeader; import org.eclipse.jgit.patch.FileHeader.PatchType; import org.eclipse.jgit.util.RawParseUtils; import java.io.IOException; import java.io.OutputStream; import java.util.List; /** Formats a unified format patch as UTF-8 encoded HTML. */ final class HtmlDiffFormatter extends DiffFormatter { private static final byte[] DIFF_BEGIN = "<pre class=\"diff-unified\">".getBytes(Charsets.UTF_8); private static final byte[] DIFF_END = "</pre>".getBytes(Charsets.UTF_8); private static final byte[] HUNK_BEGIN = "<span class=\"h\">".getBytes(Charsets.UTF_8); private static final byte[] HUNK_END = "</span>".getBytes(Charsets.UTF_8); private static final byte[] LINE_INSERT_BEGIN = "<span class=\"i\">".getBytes(Charsets.UTF_8); private static final byte[] LINE_DELETE_BEGIN = "<span class=\"d\">".getBytes(Charsets.UTF_8); private static final byte[] LINE_CHANGE_BEGIN = "<span class=\"c\">".getBytes(Charsets.UTF_8); private static final byte[] LINE_END = "</span>\n".getBytes(Charsets.UTF_8); private final Renderer renderer; private int fileIndex; HtmlDiffFormatter(Renderer renderer, OutputStream out) { super(out); this.renderer = checkNotNull(renderer, "renderer"); } @Override public void format(List<? extends DiffEntry> entries) throws IOException { for (fileIndex = 0; fileIndex < entries.size(); fileIndex++) { format(entries.get(fileIndex)); } } @Override public void format(FileHeader hdr, RawText a, RawText b) throws IOException { int start = hdr.getStartOffset(); int end = hdr.getEndOffset(); if (!hdr.getHunks().isEmpty()) { end = hdr.getHunks().get(0).getStartOffset(); } renderHeader(RawParseUtils.decode(hdr.getBuffer(), start, end)); if (hdr.getPatchType() == PatchType.UNIFIED) { getOutputStream().write(DIFF_BEGIN); format(hdr.toEditList(), a, b); getOutputStream().write(DIFF_END); } } private void renderHeader(String header) throws IOException { int lf = header.indexOf('\n'); String first; String rest; if (0 <= lf) { first = header.substring(0, lf); rest = header.substring(lf + 1); } else { first = header; rest = ""; } getOutputStream().write(renderer.newRenderer("gitiles.diffHeader") .setData(ImmutableMap.of("first", first, "rest", rest, "fileIndex", fileIndex)).render() .getBytes(Charsets.UTF_8)); } @Override protected void writeHunkHeader(int aStartLine, int aEndLine, int bStartLine, int bEndLine) throws IOException { getOutputStream().write(HUNK_BEGIN); // TODO(sop): If hunk header starts including method names, escape it. super.writeHunkHeader(aStartLine, aEndLine, bStartLine, bEndLine); getOutputStream().write(HUNK_END); } @Override protected void writeLine(char prefix, RawText text, int cur) throws IOException { // Manually render each line, rather than invoke a Soy template. This method // can be called thousands of times in a single request. Avoid unnecessary // overheads by formatting as-is. OutputStream out = getOutputStream(); switch (prefix) { case '+': out.write(LINE_INSERT_BEGIN); break; case '-': out.write(LINE_DELETE_BEGIN); break; case ' ': default: out.write(LINE_CHANGE_BEGIN); break; } out.write(StringEscapeUtils.escapeHtml4(text.getString(cur)).getBytes(Charsets.UTF_8)); out.write(LINE_END); } }