Merge "Add support for file web links"

This commit is contained in:
Edwin Kempin 2014-09-11 12:52:34 +00:00 committed by Gerrit Code Review
commit f466383995
10 changed files with 129 additions and 9 deletions

View File

@ -1778,6 +1778,9 @@ public class MyWeblinkPlugin implements PatchSetWebLink {
}
----
FileWebLinks will appear in the side-by-side diff screen on the right
side of the patch selection on each side.
ProjectWebLinks will appear in the project list in the
`Repository Browser` column.

View File

@ -3389,6 +3389,12 @@ Intraline status (`OK`, `ERROR`, `TIMEOUT`).
|`diff_header` ||A list of strings representing the patch set diff header.
|`content` ||The content differences in the file as a list of
link:#diff-content[DiffContent] entities.
|'web_links_a' |optional|
Links to the side A file in external sites as a list of
link:rest-api-changes.html#web-link-info[WebLinkInfo] entries.
|'web_links_b' |optional|
Links to the side B file in external sites as a list of
link:rest-api-changes.html#web-link-info[WebLinkInfo] entries.
|==========================
[[diff-intraline-info]]

View File

@ -0,0 +1,31 @@
// Copyright (C) 2014 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.extensions.webui;
import com.google.gerrit.extensions.annotations.ExtensionPoint;
@ExtensionPoint
public interface FileWebLink extends WebLink {
/**
* URL to file in external service.
*
* @param projectName Name of the project
* @param revision Name of the revision (e.g. branch or commit ID)
* @param fileName Name of the file
* @return url to project in external service.
*/
String getFileUrl(String projectName, String revision, String fileName);
}

View File

@ -14,6 +14,7 @@
package com.google.gerrit.client.diff;
import com.google.gerrit.client.WebLinkInfo;
import com.google.gerrit.reviewdb.client.Patch.ChangeType;
import com.google.gwt.core.client.JavaScriptObject;
import com.google.gwt.core.client.JsArray;
@ -27,6 +28,8 @@ public class DiffInfo extends JavaScriptObject {
public final native FileMeta meta_b() /*-{ return this.meta_b; }-*/;
public final native JsArrayString diff_header() /*-{ return this.diff_header; }-*/;
public final native JsArray<Region> content() /*-{ return this.content; }-*/;
public final native JsArray<WebLinkInfo> web_links_a() /*-{ return this.web_links_a; }-*/;
public final native JsArray<WebLinkInfo> web_links_b() /*-{ return this.web_links_b; }-*/;
public final ChangeType change_type() {
return ChangeType.valueOf(change_typeRaw());

View File

@ -16,6 +16,7 @@ package com.google.gerrit.client.diff;
import com.google.gerrit.client.account.DiffPreferences;
import com.google.gerrit.client.changes.ChangeInfo.RevisionInfo;
import com.google.gerrit.client.rpc.Natives;
import com.google.gerrit.reviewdb.client.Patch.ChangeType;
import com.google.gerrit.reviewdb.client.PatchSet;
import com.google.gwt.core.client.GWT;
@ -158,8 +159,10 @@ class DiffTable extends Composite {
void set(DiffPreferences prefs, JsArray<RevisionInfo> list, DiffInfo info) {
this.changeType = info.change_type();
patchSetSelectBoxA.setUpPatchSetNav(list, info.meta_a());
patchSetSelectBoxB.setUpPatchSetNav(list, info.meta_b());
patchSetSelectBoxA.setUpPatchSetNav(list, info.meta_a(),
Natives.asList(info.web_links_a()));
patchSetSelectBoxB.setUpPatchSetNav(list, info.meta_b(),
Natives.asList(info.web_links_b()));
JsArrayString hdr = info.diff_header();
if (hdr != null) {

View File

@ -16,6 +16,7 @@ package com.google.gerrit.client.diff;
import com.google.gerrit.client.Dispatcher;
import com.google.gerrit.client.Gerrit;
import com.google.gerrit.client.WebLinkInfo;
import com.google.gerrit.client.changes.ChangeInfo.RevisionInfo;
import com.google.gerrit.client.patches.PatchUtil;
import com.google.gerrit.client.ui.InlineHyperlink;
@ -36,6 +37,8 @@ import com.google.gwt.user.client.ui.Image;
import com.google.gwt.user.client.ui.ImageResourceRenderer;
import com.google.gwtorm.client.KeyUtil;
import java.util.List;
/** HTMLPanel to select among patch sets */
class PatchSetSelectBox2 extends Composite {
interface Binder extends UiBinder<HTMLPanel, PatchSetSelectBox2> {}
@ -76,7 +79,8 @@ class PatchSetSelectBox2 extends Composite {
this.path = path;
}
void setUpPatchSetNav(JsArray<RevisionInfo> list, DiffInfo.FileMeta meta) {
void setUpPatchSetNav(JsArray<RevisionInfo> list, DiffInfo.FileMeta meta,
List<WebLinkInfo> webLinks) {
InlineHyperlink baseLink = null;
InlineHyperlink selectedLink = null;
if (sideA) {
@ -100,6 +104,22 @@ class PatchSetSelectBox2 extends Composite {
if (meta != null && !Patch.COMMIT_MSG.equals(path)) {
linkPanel.add(createDownloadLink());
}
if (webLinks != null) {
for (WebLinkInfo weblink : webLinks) {
Anchor a = new Anchor();
a.setHref(weblink.url());
if (weblink.imageUrl() != null && !weblink.imageUrl().isEmpty()) {
Image img = new Image();
img.setAltText(weblink.name());
img.setUrl(weblink.imageUrl());
img.setTitle(weblink.name());
a.getElement().appendChild(img.getElement());
} else {
a.setText("(" + weblink.name() + ")");
}
linkPanel.add(a);
}
}
}
static void link(PatchSetSelectBox2 a, PatchSetSelectBox2 b) {

View File

@ -19,6 +19,7 @@ import com.google.gerrit.extensions.common.WebLinkInfo;
import com.google.gerrit.extensions.registration.DynamicSet;
import com.google.gerrit.extensions.webui.BranchWebLink;
import com.google.gerrit.extensions.webui.PatchSetWebLink;
import com.google.gerrit.extensions.webui.FileWebLink;
import com.google.gerrit.extensions.webui.ProjectWebLink;
import java.util.List;
@ -26,13 +27,16 @@ import java.util.List;
public class WebLinks {
private final DynamicSet<PatchSetWebLink> patchSetLinks;
private final DynamicSet<FileWebLink> fileLinks;
private final DynamicSet<ProjectWebLink> projectLinks;
private final DynamicSet<BranchWebLink> branchLinks;
public WebLinks(DynamicSet<PatchSetWebLink> patchSetLinks,
DynamicSet<FileWebLink> fileLinks,
DynamicSet<ProjectWebLink> projectLinks,
DynamicSet<BranchWebLink> branchLinks) {
this.patchSetLinks = patchSetLinks;
this.fileLinks = fileLinks;
this.projectLinks = projectLinks;
this.branchLinks = branchLinks;
}
@ -47,6 +51,17 @@ public class WebLinks {
return links;
}
public Iterable<WebLinkInfo> getPatchLinks(String project, String revision,
String file) {
List<WebLinkInfo> links = Lists.newArrayList();
for (FileWebLink webLink : fileLinks) {
links.add(new WebLinkInfo(webLink.getLinkName(),
webLink.getImageUrl(),
webLink.getFileUrl(project, revision, file)));
}
return links;
}
public Iterable<WebLinkInfo> getProjectLinks(String project) {
List<WebLinkInfo> links = Lists.newArrayList();
for (ProjectWebLink webLink : projectLinks) {

View File

@ -17,6 +17,7 @@ package com.google.gerrit.server;
import com.google.gerrit.extensions.registration.DynamicSet;
import com.google.gerrit.extensions.webui.BranchWebLink;
import com.google.gerrit.extensions.webui.PatchSetWebLink;
import com.google.gerrit.extensions.webui.FileWebLink;
import com.google.gerrit.extensions.webui.ProjectWebLink;
import com.google.inject.Inject;
import com.google.inject.Provider;
@ -24,21 +25,23 @@ import com.google.inject.Provider;
public class WebLinksProvider implements Provider<WebLinks> {
private final DynamicSet<PatchSetWebLink> patchSetLinks;
private final DynamicSet<FileWebLink> fileLinks;
private final DynamicSet<ProjectWebLink> projectLinks;
private final DynamicSet<BranchWebLink> branchLinks;
@Inject
public WebLinksProvider(DynamicSet<PatchSetWebLink> patchSetLinks,
DynamicSet<FileWebLink> fileLinks,
DynamicSet<ProjectWebLink> projectLinks,
DynamicSet<BranchWebLink> branchLinks) {
this.patchSetLinks = patchSetLinks;
this.fileLinks = fileLinks;
this.projectLinks = projectLinks;
this.branchLinks = branchLinks;
}
@Override
public WebLinks get() {
WebLinks webLinks = new WebLinks(patchSetLinks, projectLinks, branchLinks);
return webLinks;
return new WebLinks(patchSetLinks, fileLinks, projectLinks, branchLinks);
}
}

View File

@ -17,11 +17,13 @@ package com.google.gerrit.server.change;
import static com.google.common.base.Preconditions.checkState;
import com.google.common.base.MoreObjects;
import com.google.common.base.Strings;
import com.google.common.collect.ImmutableList;
import com.google.common.collect.Lists;
import com.google.gerrit.common.data.PatchScript;
import com.google.gerrit.common.data.PatchScript.DisplayMethod;
import com.google.gerrit.common.data.PatchScript.FileMode;
import com.google.gerrit.extensions.common.WebLinkInfo;
import com.google.gerrit.extensions.restapi.AuthException;
import com.google.gerrit.extensions.restapi.CacheControl;
import com.google.gerrit.extensions.restapi.IdString;
@ -35,6 +37,8 @@ import com.google.gerrit.reviewdb.client.AccountDiffPreference;
import com.google.gerrit.reviewdb.client.Patch;
import com.google.gerrit.reviewdb.client.Patch.ChangeType;
import com.google.gerrit.reviewdb.client.PatchSet;
import com.google.gerrit.reviewdb.client.Project;
import com.google.gerrit.server.WebLinks;
import com.google.gerrit.server.git.LargeObjectException;
import com.google.gerrit.server.patch.PatchScriptFactory;
import com.google.gerrit.server.project.InvalidChangeOperationException;
@ -43,6 +47,7 @@ import com.google.gerrit.server.project.ProjectCache;
import com.google.gerrit.server.project.ProjectState;
import com.google.gwtorm.server.OrmException;
import com.google.inject.Inject;
import com.google.inject.Provider;
import org.eclipse.jgit.diff.Edit;
import org.eclipse.jgit.diff.ReplaceEdit;
@ -56,6 +61,7 @@ import org.kohsuke.args4j.spi.Parameters;
import org.kohsuke.args4j.spi.Setter;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.TimeUnit;
@ -63,6 +69,7 @@ public class GetDiff implements RestReadView<FileResource> {
private final ProjectCache projectCache;
private final PatchScriptFactory.Factory patchScriptFactoryFactory;
private final Revisions revisions;
private final Provider<WebLinks> webLinks;
@Option(name = "--base", metaVar = "REVISION")
String base;
@ -79,21 +86,23 @@ public class GetDiff implements RestReadView<FileResource> {
@Inject
GetDiff(ProjectCache projectCache,
PatchScriptFactory.Factory patchScriptFactoryFactory,
Revisions revisions) {
Revisions revisions,
Provider<WebLinks> webLinks) {
this.projectCache = projectCache;
this.patchScriptFactoryFactory = patchScriptFactoryFactory;
this.revisions = revisions;
this.webLinks = webLinks;
}
@Override
public Response<Result> apply(FileResource resource)
throws ResourceConflictException, ResourceNotFoundException,
OrmException, AuthException, InvalidChangeOperationException, IOException {
PatchSet.Id basePatchSet = null;
PatchSet basePatchSet = null;
if (base != null) {
RevisionResource baseResource = revisions.parse(
resource.getRevision().getChangeResource(), IdString.fromDecoded(base));
basePatchSet = baseResource.getPatchSet().getId();
basePatchSet = baseResource.getPatchSet();
}
AccountDiffPreference prefs = new AccountDiffPreference(new Account.Id(0));
prefs.setIgnoreWhitespace(ignoreWhitespace.whitespace);
@ -104,7 +113,7 @@ public class GetDiff implements RestReadView<FileResource> {
PatchScriptFactory psf = patchScriptFactoryFactory.create(
resource.getRevision().getControl(),
resource.getPatchKey().getFileName(),
basePatchSet,
basePatchSet != null ? basePatchSet.getId() : null,
resource.getPatchKey().getParentKey(),
prefs);
psf.setLoadHistory(false);
@ -147,6 +156,14 @@ public class GetDiff implements RestReadView<FileResource> {
ps.getNewName());
setContentType(result.metaA, state, ps.getFileModeA(), ps.getMimeTypeA());
result.metaA.lines = ps.getA().size();
// TODO referring to the parent commit by refs/changes/12/60012/1^1
// will likely not work for inline edits
String rev = basePatchSet != null
? basePatchSet.getRefName()
: resource.getRevision().getPatchSet().getRefName() + "^1";
result.webLinksA =
getFileWebLinks(state.getProject(), rev, result.metaA.name);
}
if (ps.getDisplayMethodB() != DisplayMethod.NONE) {
@ -154,6 +171,9 @@ public class GetDiff implements RestReadView<FileResource> {
result.metaB.name = ps.getNewName();
setContentType(result.metaB, state, ps.getFileModeB(), ps.getMimeTypeB());
result.metaB.lines = ps.getB().size();
result.webLinksB = getFileWebLinks(state.getProject(),
resource.getRevision().getPatchSet().getRefName(),
result.metaB.name);
}
if (intraline) {
@ -183,6 +203,18 @@ public class GetDiff implements RestReadView<FileResource> {
}
}
private List<WebLinkInfo> getFileWebLinks(Project project, String rev,
String file) {
List<WebLinkInfo> fileWebLinks = new ArrayList<>();
for (WebLinkInfo link : webLinks.get().getPatchLinks(project.getName(),
rev, file)) {
if (!Strings.isNullOrEmpty(link.name) && !Strings.isNullOrEmpty(link.url)) {
fileWebLinks.add(link);
}
}
return fileWebLinks;
}
static class Result {
FileMeta metaA;
FileMeta metaB;
@ -190,6 +222,8 @@ public class GetDiff implements RestReadView<FileResource> {
ChangeType changeType;
List<String> diffHeader;
List<ContentEntry> content;
List<WebLinkInfo> webLinksA;
List<WebLinkInfo> webLinksB;
}
static class FileMeta {

View File

@ -34,6 +34,7 @@ import com.google.gerrit.extensions.registration.DynamicSet;
import com.google.gerrit.extensions.systemstatus.MessageOfTheDay;
import com.google.gerrit.extensions.webui.BranchWebLink;
import com.google.gerrit.extensions.webui.PatchSetWebLink;
import com.google.gerrit.extensions.webui.FileWebLink;
import com.google.gerrit.extensions.webui.ProjectWebLink;
import com.google.gerrit.extensions.webui.TopMenu;
import com.google.gerrit.reviewdb.client.AccountGroup;
@ -281,6 +282,7 @@ public class GerritGlobalModule extends FactoryModule {
DynamicMap.mapOf(binder(), DownloadCommand.class);
DynamicMap.mapOf(binder(), ProjectConfigEntry.class);
DynamicSet.setOf(binder(), PatchSetWebLink.class);
DynamicSet.setOf(binder(), FileWebLink.class);
DynamicSet.setOf(binder(), ProjectWebLink.class);
DynamicSet.setOf(binder(), BranchWebLink.class);