InlineEdit: Add support for diff web links

For plugin integration (most notably x-docs plugin) edit screen must
support diff web links. When edit doesn't exst yet, retrieve the links
from GET diff REST endpoint.

Change-Id: Ic41091854754e8a25c30de0e4bd4d8958d5fb32b
This commit is contained in:
David Ostrovsky 2015-01-25 00:12:38 +01:00 committed by Edwin Kempin
parent ee91571183
commit 9ea9c1163a
6 changed files with 192 additions and 4 deletions

View File

@ -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.

View File

@ -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<EditFileInfo> 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<VoidResult> 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();

View File

@ -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<DiffWebLinkInfo> web_links() /*-{ return this.web_links; }-*/;
protected EditFileInfo() {
}
}

View File

@ -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<NativeString> 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<EditFileInfo>() {
@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<DiffInfo>() {
@Override
public void onSuccess(DiffInfo diffInfo) {
patchSetDiffInfo = diffInfo;
}
});
}
ChangeEditApi.get(revision, path,
group2.add(new HttpCallback<NativeString>() {
final AsyncCallback<Void> modeCallback = group3.addEmpty();
@ -182,8 +215,10 @@ public class EditScreen extends Screen {
group3.addListener(new ScreenLoadCallback<Void>(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<NativeString> file) {
private void initEditor(HttpResponse<NativeString> 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<DiffWebLinkInfo> links) {
if (links != null) {
for (DiffWebLinkInfo webLink : links) {
linkPanel.add(webLink.toAnchor());
}
}
}
private List<InlineHyperlink> getLinks() {

View File

@ -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<ChangeEditResource> {
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<DiffWebLinkInfo> 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<DiffWebLinkInfo> webLinks;
}
}
@Singleton
public static class EditMessage implements
RestModifyView<ChangeResource, EditMessage.Input> {

View File

@ -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