diff --git a/Documentation/rest-api-changes.txt b/Documentation/rest-api-changes.txt index c7bcd86334..576cec6da4 100644 --- a/Documentation/rest-api-changes.txt +++ b/Documentation/rest-api-changes.txt @@ -1445,6 +1445,50 @@ avoid downloading the encoded file contents. RnJvbSA3ZGFkY2MxNTNmZGVhMTdhYTg0ZmYzMmE2ZTI0NWRiYjY... ---- +[[get-edit-meta-data]] +=== Retrieve meta data of a file from Change Edit +-- +'GET /changes/link:#change-id[\{change-id\}]/edit/path%2fto%2ffile/meta +-- + +Retrieves meta data of a file from a change edit. Currently only +web links are returned. + +.Request +---- + GET /changes/myProject~master~I8473b95934b5732ac55d26311a706c9c2bde9940/edit/foo/meta HTTP/1.0 +---- + +This REST endpoint retrieves additional information for a file in a +change edit. As result an link:#edit-file-info[EditFileInfo] entity is +returned. + +.Response +---- + HTTP/1.1 200 OK + Content-Disposition: attachment + Content-Type: application/json; charset=UTF-8 + + )]}' + { + "web_links":[ + { + "show_on_side_by_side_diff_view": true, + "name": "side-by-side preview diff", + "image_url": "plugins/xdocs/static/sideBySideDiffPreview.png", + "url": "#/x/xdocs/c/42/1..0/README.md", + "target": "_self" + }, + { + "show_on_unified_diff_view": true, + "name": "unified preview diff", + "image_url": "plugins/xdocs/static/unifiedDiffPreview.png", + "url": "#/x/xdocs/c/42/1..0/README.md,unified", + "target": "_self" + } + ]} +---- + [[get-edit-message]] === Retrieve commit message from Change Edit or current patch set of the change -- @@ -3558,6 +3602,19 @@ Whether the web link should be shown on the side-by-side diff screen. Whether the web link should be shown on the unified diff screen. |======================= +[[edit-file-info]] +=== EditFileInfo +The `EditFileInfo` entity contains additional information +of a file within a change edit. + +[options="header",cols="1,^1,5"] +|=========================== +|Field Name ||Description +|`web_links` |optional| +Links to the diff info in external sites as a list of +link:#web-link-info[WebLinkInfo] entities. +|=========================== + [[edit-info]] === EditInfo The `EditInfo` entity contains information about a change edit. diff --git a/gerrit-gwtui/src/main/java/com/google/gerrit/client/changes/ChangeEditApi.java b/gerrit-gwtui/src/main/java/com/google/gerrit/client/changes/ChangeEditApi.java index ca5d4343f6..dd02cb1c2a 100644 --- a/gerrit-gwtui/src/main/java/com/google/gerrit/client/changes/ChangeEditApi.java +++ b/gerrit-gwtui/src/main/java/com/google/gerrit/client/changes/ChangeEditApi.java @@ -15,6 +15,7 @@ package com.google.gerrit.client.changes; import com.google.gerrit.client.VoidResult; +import com.google.gerrit.client.editor.EditFileInfo; import com.google.gerrit.client.rpc.GerritCallback; import com.google.gerrit.client.rpc.HttpCallback; import com.google.gerrit.client.rpc.NativeString; @@ -42,6 +43,20 @@ public class ChangeEditApi { api.get(cb); } + /** Get meta info for change edit. */ + public static void getMeta(PatchSet.Id id, String path, + AsyncCallback cb) { + RestApi api; + if (id.get() != 0) { + throw new IllegalStateException("only supported for edits"); + } else if (Patch.COMMIT_MSG.equals(path)) { + api = metaFile(id.getParentKey().get(), Patch.COMMIT_MSG); + } else { + api = metaFile(id.getParentKey().get(), path); + } + api.get(cb); + } + /** Put message into a change edit. */ public static void putMessage(int id, String m, GerritCallback cb) { editMessage(id).put(m, cb); @@ -77,6 +92,10 @@ public class ChangeEditApi { return ChangeApi.edit(id).id(path); } + private static RestApi metaFile(int id, String path) { + return ChangeApi.edit(id).id(path).view("meta"); + } + private static class Input extends JavaScriptObject { static Input create() { return createObject().cast(); diff --git a/gerrit-gwtui/src/main/java/com/google/gerrit/client/editor/EditFileInfo.java b/gerrit-gwtui/src/main/java/com/google/gerrit/client/editor/EditFileInfo.java new file mode 100644 index 0000000000..c833c5d999 --- /dev/null +++ b/gerrit-gwtui/src/main/java/com/google/gerrit/client/editor/EditFileInfo.java @@ -0,0 +1,26 @@ +// Copyright (C) 2015 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.editor; + +import com.google.gerrit.client.DiffWebLinkInfo; +import com.google.gwt.core.client.JavaScriptObject; +import com.google.gwt.core.client.JsArray; + +public class EditFileInfo extends JavaScriptObject { + public final native JsArray web_links() /*-{ return this.web_links; }-*/; + + protected EditFileInfo() { + } +} diff --git a/gerrit-gwtui/src/main/java/com/google/gerrit/client/editor/EditScreen.java b/gerrit-gwtui/src/main/java/com/google/gerrit/client/editor/EditScreen.java index a945bd23b4..47afb0a6d9 100644 --- a/gerrit-gwtui/src/main/java/com/google/gerrit/client/editor/EditScreen.java +++ b/gerrit-gwtui/src/main/java/com/google/gerrit/client/editor/EditScreen.java @@ -17,6 +17,7 @@ package com.google.gerrit.client.editor; import static com.google.gwt.dom.client.Style.Visibility.HIDDEN; import static com.google.gwt.dom.client.Style.Visibility.VISIBLE; +import com.google.gerrit.client.DiffWebLinkInfo; import com.google.gerrit.client.Gerrit; import com.google.gerrit.client.JumpKeys; import com.google.gerrit.client.VoidResult; @@ -24,6 +25,8 @@ import com.google.gerrit.client.account.DiffPreferences; import com.google.gerrit.client.changes.ChangeApi; import com.google.gerrit.client.changes.ChangeEditApi; import com.google.gerrit.client.changes.ChangeInfo; +import com.google.gerrit.client.diff.DiffApi; +import com.google.gerrit.client.diff.DiffInfo; import com.google.gerrit.client.diff.FileInfo; import com.google.gerrit.client.diff.Header; import com.google.gerrit.client.patches.PatchUtil; @@ -32,6 +35,7 @@ import com.google.gerrit.client.rpc.GerritCallback; import com.google.gerrit.client.rpc.HttpCallback; import com.google.gerrit.client.rpc.HttpResponse; import com.google.gerrit.client.rpc.NativeString; +import com.google.gerrit.client.rpc.Natives; import com.google.gerrit.client.rpc.RestApi; import com.google.gerrit.client.rpc.ScreenLoadCallback; import com.google.gerrit.client.ui.InlineHyperlink; @@ -85,6 +89,8 @@ public class EditScreen extends Screen { private DiffPreferences prefs; private CodeMirror cm; private HttpResponse content; + private EditFileInfo editFileInfo; + private DiffInfo patchSetDiffInfo; @UiField Element header; @UiField Element project; @@ -153,6 +159,33 @@ public class EditScreen extends Screen { } })); + + if (revision.get() == 0) { + ChangeEditApi.getMeta(revision, path, + group1.add(new AsyncCallback() { + @Override + public void onSuccess(EditFileInfo editInfo) { + editFileInfo = editInfo; + } + + @Override + public void onFailure(Throwable e) { + } + })); + } else { + // TODO(davido): We probably want to create dedicated GET EditScreenMeta + // REST endpoint. Abuse GET diff for now, as it retrieves links we need. + DiffApi.diff(revision, path) + .base(base) + .webLinksOnly() + .get(new GerritCallback() { + @Override + public void onSuccess(DiffInfo diffInfo) { + patchSetDiffInfo = diffInfo; + } + }); + } + ChangeEditApi.get(revision, path, group2.add(new HttpCallback() { final AsyncCallback modeCallback = group3.addEmpty(); @@ -182,8 +215,10 @@ public class EditScreen extends Screen { group3.addListener(new ScreenLoadCallback(this) { @Override protected void preDisplay(Void result) { - initEditor(content); + initEditor(content, editFileInfo, patchSetDiffInfo); content = null; + editFileInfo = null; + patchSetDiffInfo = null; } }); group1.done(); @@ -301,7 +336,8 @@ public class EditScreen extends Screen { Gerrit.display(PageLinks.toChangeInEditMode(revision.getParentKey())); } - private void initEditor(HttpResponse file) { + private void initEditor(HttpResponse file, + EditFileInfo info, DiffInfo diffInfo) { ModeInfo mode = null; String content = ""; if (file != null) { @@ -310,7 +346,7 @@ public class EditScreen extends Screen { mode = ModeInfo.findMode(file.getContentType(), path); } } - renderLinks(); + renderLinks(info, diffInfo); cm = CodeMirror.create(editor, Configuration.create() .set("value", content) .set("readOnly", false) @@ -330,10 +366,23 @@ public class EditScreen extends Screen { .on("Ctrl-S", save())); } - private void renderLinks() { + private void renderLinks(EditFileInfo info, DiffInfo diffInfo) { for (InlineHyperlink link : getLinks()) { linkPanel.add(link); } + if (info != null) { + renderPluginLinks(Natives.asList(info.web_links())); + } else if (diffInfo != null) { + renderPluginLinks(Natives.asList(diffInfo.web_links())); + } + } + + private void renderPluginLinks(List links) { + if (links != null) { + for (DiffWebLinkInfo webLink : links) { + linkPanel.add(webLink.toAnchor()); + } + } } private List getLinks() { diff --git a/gerrit-server/src/main/java/com/google/gerrit/server/change/ChangeEdits.java b/gerrit-server/src/main/java/com/google/gerrit/server/change/ChangeEdits.java index 0759370578..e5f5381f79 100644 --- a/gerrit-server/src/main/java/com/google/gerrit/server/change/ChangeEdits.java +++ b/gerrit-server/src/main/java/com/google/gerrit/server/change/ChangeEdits.java @@ -16,7 +16,9 @@ package com.google.gerrit.server.change; import com.google.common.base.Optional; import com.google.common.base.Strings; +import com.google.common.collect.FluentIterable; import com.google.gerrit.common.Nullable; +import com.google.gerrit.extensions.common.DiffWebLinkInfo; import com.google.gerrit.extensions.common.EditInfo; import com.google.gerrit.extensions.registration.DynamicMap; import com.google.gerrit.extensions.restapi.AcceptsCreate; @@ -39,6 +41,7 @@ import com.google.gerrit.extensions.restapi.RestView; import com.google.gerrit.reviewdb.client.Change; import com.google.gerrit.reviewdb.client.PatchSet; import com.google.gerrit.reviewdb.server.ReviewDb; +import com.google.gerrit.server.WebLinks; import com.google.gerrit.server.edit.ChangeEdit; import com.google.gerrit.server.edit.ChangeEditJson; import com.google.gerrit.server.edit.ChangeEditModifier; @@ -56,6 +59,7 @@ import org.eclipse.jgit.lib.ObjectId; import org.kohsuke.args4j.Option; import java.io.IOException; +import java.util.List; @Singleton public class ChangeEdits implements @@ -450,6 +454,38 @@ public class ChangeEdits implements } } + @Singleton + static class GetMeta implements RestReadView { + private final WebLinks webLinks; + + @Inject + GetMeta(WebLinks webLinks) { + this.webLinks = webLinks; + } + + @Override + public FileInfo apply(ChangeEditResource rsrc) { + FileInfo r = new FileInfo(); + ChangeEdit edit = rsrc.getChangeEdit(); + Change change = edit.getChange(); + FluentIterable links = + webLinks.getDiffLinks(change.getProject().get(), + change.getChangeId(), + edit.getBasePatchSet().getPatchSetId(), + edit.getBasePatchSet().getRefName(), + rsrc.getPath(), + 0, + edit.getRefName(), + rsrc.getPath()); + r.webLinks = links.isEmpty() ? null : links.toList(); + return r; + } + + static class FileInfo { + List webLinks; + } + } + @Singleton public static class EditMessage implements RestModifyView { diff --git a/gerrit-server/src/main/java/com/google/gerrit/server/change/Module.java b/gerrit-server/src/main/java/com/google/gerrit/server/change/Module.java index 3645f367ec..ac4489ee0f 100644 --- a/gerrit-server/src/main/java/com/google/gerrit/server/change/Module.java +++ b/gerrit-server/src/main/java/com/google/gerrit/server/change/Module.java @@ -113,6 +113,7 @@ public class Module extends RestApiModule { put(CHANGE_EDIT_KIND, "/").to(ChangeEdits.Put.class); delete(CHANGE_EDIT_KIND).to(ChangeEdits.DeleteContent.class); get(CHANGE_EDIT_KIND, "/").to(ChangeEdits.Get.class); + get(CHANGE_EDIT_KIND, "meta").to(ChangeEdits.GetMeta.class); install(new FactoryModule() { @Override