From 3b9db59093a3f08c9103c36a79b0cac1dca7313e Mon Sep 17 00:00:00 2001 From: Shawn Pearce Date: Sat, 18 May 2013 19:38:30 -0700 Subject: [PATCH] Map /diff REST API result with JSNI Define all members of the /diff API as JSNI glue so the result can be trivially accepted within the GWT UI. This change includes a DiffApi helper to build the request. has_skip() can be used to identify files where there is missing context and syntax highlighting might not work correctly. text_a() and text_b() are example placeholders to recreate a file from available lines. Performing layout with CodeMirror or another UI system may be more complex than these functions. Change-Id: Ie519a24725576e73b6a5ffec0326ceb30b090add --- .../google/gerrit/client/diff/DiffApi.java | 69 ++++++++++ .../google/gerrit/client/diff/DiffInfo.java | 128 ++++++++++++++++++ 2 files changed, 197 insertions(+) create mode 100644 gerrit-gwtui/src/main/java/com/google/gerrit/client/diff/DiffApi.java create mode 100644 gerrit-gwtui/src/main/java/com/google/gerrit/client/diff/DiffInfo.java diff --git a/gerrit-gwtui/src/main/java/com/google/gerrit/client/diff/DiffApi.java b/gerrit-gwtui/src/main/java/com/google/gerrit/client/diff/DiffApi.java new file mode 100644 index 0000000000..b82ddee8ef --- /dev/null +++ b/gerrit-gwtui/src/main/java/com/google/gerrit/client/diff/DiffApi.java @@ -0,0 +1,69 @@ +// Copyright (C) 2013 The Android Open Source Project +// +// 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.gerrit.client.diff; + +import com.google.gerrit.client.changes.ChangeApi; +import com.google.gerrit.client.rpc.RestApi; +import com.google.gerrit.reviewdb.client.PatchSet; +import com.google.gwt.user.client.rpc.AsyncCallback; + +public class DiffApi { + public enum IgnoreWhitespace { + NONE, TRAILING, CHANGED, ALL; + }; + + public static DiffApi diff(PatchSet.Id id, String path) { + return new DiffApi(ChangeApi.revision(id) + .view("files").id(path) + .view("diff")); + } + + private final RestApi call; + + private DiffApi(RestApi call) { + this.call = call; + } + + public DiffApi base(PatchSet.Id id) { + call.addParameter("base", id.get()); + return this; + } + + public DiffApi ignoreWhitespace(IgnoreWhitespace w) { + if (w != null && w != IgnoreWhitespace.NONE) { + call.addParameter("ignore-whitespace", w); + } + return this; + } + + public DiffApi intraline() { + call.addParameterTrue("intraline"); + return this; + } + + public DiffApi wholeFile() { + call.addParameter("context", "ALL"); + return this; + } + + public DiffApi context(int lines) { + call.addParameter("context", lines); + return this; + } + + public void get(AsyncCallback cb) { + call.get(cb); + } +} diff --git a/gerrit-gwtui/src/main/java/com/google/gerrit/client/diff/DiffInfo.java b/gerrit-gwtui/src/main/java/com/google/gerrit/client/diff/DiffInfo.java new file mode 100644 index 0000000000..229f023ca7 --- /dev/null +++ b/gerrit-gwtui/src/main/java/com/google/gerrit/client/diff/DiffInfo.java @@ -0,0 +1,128 @@ +// Copyright (C) 2013 The Android Open Source Project +// +// 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.gerrit.client.diff; + +import com.google.gerrit.reviewdb.client.Patch.ChangeType; +import com.google.gwt.core.client.JavaScriptObject; +import com.google.gwt.core.client.JsArray; +import com.google.gwt.core.client.JsArrayString; + +public class DiffInfo extends JavaScriptObject { + public static final String GITLINK = "x-git/gitlink"; + public static final String SYMLINK = "x-git/symlink"; + + public final native FileMeta meta_a() /*-{ return this.meta_a; }-*/; + public final native FileMeta meta_b() /*-{ return this.meta_b; }-*/; + public final native JsArrayString diff_header() /*-{ return this.diff_header; }-*/; + public final native JsArray content() /*-{ return this.content; }-*/; + + public final ChangeType change_type() { + return ChangeType.valueOf(change_typeRaw()); + } + private final native String change_typeRaw() + /*-{ return this.change_type }-*/; + + public final IntraLineStatus intraline_status() { + String s = intraline_statusRaw(); + return s != null + ? IntraLineStatus.valueOf(s) + : IntraLineStatus.OFF; + } + private final native String intraline_statusRaw() + /*-{ return this.intraline_status }-*/; + + public final boolean has_skip() { + JsArray c = content(); + for (int i = 0; i < c.length(); i++) { + if (c.get(i).skip() != 0) { + return true; + } + } + return false; + } + + public final String text_a() { + StringBuilder s = new StringBuilder(); + JsArray c = content(); + for (int i = 0; i < c.length(); i++) { + Region r = c.get(i); + if (r.ab() != null) { + append(s, r.ab()); + } else if (r.a() != null) { + append(s, r.a()); + } + // TODO skip may need to be handled + } + return s.toString(); + } + + public final String text_b() { + StringBuilder s = new StringBuilder(); + JsArray c = content(); + for (int i = 0; i < c.length(); i++) { + Region r = c.get(i); + if (r.ab() != null) { + append(s, r.ab()); + } else if (r.b() != null) { + append(s, r.b()); + } + // TODO skip may need to be handled + } + return s.toString(); + } + + private static void append(StringBuilder s, JsArrayString lines) { + for (int i = 0; i < lines.length(); i++) { + s.append(lines.get(i)).append('\n'); + } + } + + protected DiffInfo() { + } + + public enum IntraLineStatus { + OFF, OK, TIMEOUT, FAILURE; + } + + public static class FileMeta extends JavaScriptObject { + public final native String name() /*-{ return this.name; }-*/; + public final native String content_type() /*-{ return this.content_type; }-*/; + + protected FileMeta() { + } + } + + public static class Region extends JavaScriptObject { + public final native JsArrayString ab() /*-{ return this.ab; }-*/; + public final native JsArrayString a() /*-{ return this.a; }-*/; + public final native JsArrayString b() /*-{ return this.b; }-*/; + public final native int skip() /*-{ return this.skip || 0; }-*/; + + public final native JsArray edit_a() /*-{ return this.edit_a }-*/; + public final native JsArray edit_b() /*-{ return this.edit_b }-*/; + + protected Region() { + } + } + + public static class Span extends JavaScriptObject { + public final native int begin() /*-{ return this[0]; }-*/; + public final native int length() /*-{ return this[1]; }-*/; + public final int end() { return begin() + length(); } + + protected Span() { + } + } +}