Merge "Rewrite GWT UI to use project name in addition to numeric change ID"

This commit is contained in:
Alice Kober-Sotzek
2017-07-26 07:42:44 +00:00
committed by Gerrit Code Review
81 changed files with 1055 additions and 415 deletions

View File

@@ -22,6 +22,8 @@ import com.google.gerrit.reviewdb.client.Project;
import com.google.gwtorm.client.KeyUtil;
public class PageLinks {
public static final String PROJECT_CHANGE_DELIMITER = "/+/";
public static final String SETTINGS = "/settings/";
public static final String SETTINGS_PREFERENCES = "/settings/preferences";
public static final String SETTINGS_DIFF_PREFERENCES = "/settings/diff-preferences";
@@ -51,20 +53,21 @@ public class PageLinks {
public static final String MY_GROUPS = "/groups/self";
public static final String DOCUMENTATION = "/Documentation/";
public static String toChangeInEditMode(Change.Id c) {
return "/c/" + c + ",edit/";
public static String toChangeInEditMode(@Nullable Project.NameKey project, Change.Id c) {
return toChangeNoSlash(project, c) + ",edit/";
}
public static String toChange(Change.Id c) {
return "/c/" + c + "/";
public static String toChange(@Nullable Project.NameKey project, Change.Id c) {
return toChangeNoSlash(project, c) + "/";
}
public static String toChange(Change.Id c, String p) {
return "/c/" + c + "/" + p;
public static String toChange(@Nullable Project.NameKey project, Change.Id c, String p) {
return toChange(project, c) + p;
}
public static String toChange(Change.Id c, String b, String p) {
String u = "/c/" + c + "/";
public static String toChange(
@Nullable Project.NameKey project, Change.Id c, String b, String p) {
String u = toChange(project, c);
if (b != null) {
u += b + "..";
}
@@ -72,8 +75,15 @@ public class PageLinks {
return u;
}
public static String toChange(PatchSet.Id ps) {
return "/c/" + ps.getParentKey() + "/" + ps.getId();
public static String toChangeId(@Nullable Project.NameKey project, Change.Id c) {
if (project == null) {
return String.valueOf(c.get());
}
return project.get() + PROJECT_CHANGE_DELIMITER + c.get();
}
public static String toChange(@Nullable Project.NameKey project, PatchSet.Id ps) {
return toChange(project, ps.getParentKey()) + ps.getId();
}
public static String toProject(Project.NameKey p) {
@@ -166,6 +176,13 @@ public class PageLinks {
}
}
private static String toChangeNoSlash(@Nullable Project.NameKey project, Change.Id c) {
if (project != null) {
return "/c/" + project.get() + PROJECT_CHANGE_DELIMITER + c;
}
return "/c/" + c;
}
public static String op(String op, int value) {
return op + ":" + value;
}

View File

@@ -34,6 +34,7 @@ junit_tests(
"//gerrit-common:client",
"//gerrit-extension-api:client",
"//lib:junit",
"//lib:truth",
"//lib/gwt:dev",
"//lib/gwt:user",
],

View File

@@ -40,7 +40,6 @@ import static com.google.gerrit.common.PageLinks.SETTINGS_PREFERENCES;
import static com.google.gerrit.common.PageLinks.SETTINGS_PROJECTS;
import static com.google.gerrit.common.PageLinks.SETTINGS_SSHKEYS;
import static com.google.gerrit.common.PageLinks.SETTINGS_WEBIDENT;
import static com.google.gerrit.common.PageLinks.toChangeQuery;
import com.google.gerrit.client.account.MyAgreementsScreen;
import com.google.gerrit.client.account.MyContactInformationScreen;
@@ -77,6 +76,7 @@ import com.google.gerrit.client.api.ExtensionScreen;
import com.google.gerrit.client.api.ExtensionSettingsScreen;
import com.google.gerrit.client.change.ChangeScreen;
import com.google.gerrit.client.change.FileTable;
import com.google.gerrit.client.change.ProjectChangeId;
import com.google.gerrit.client.changes.AccountDashboardScreen;
import com.google.gerrit.client.changes.CustomDashboardScreen;
import com.google.gerrit.client.changes.ProjectDashboardScreen;
@@ -93,6 +93,7 @@ import com.google.gerrit.client.info.GroupInfo;
import com.google.gerrit.client.rpc.GerritCallback;
import com.google.gerrit.client.rpc.RestApi;
import com.google.gerrit.client.ui.Screen;
import com.google.gerrit.common.Nullable;
import com.google.gerrit.common.PageLinks;
import com.google.gerrit.extensions.client.GeneralPreferencesInfo.DiffView;
import com.google.gerrit.reviewdb.client.Account;
@@ -108,53 +109,65 @@ import com.google.gwtexpui.user.client.UserAgent;
import com.google.gwtorm.client.KeyUtil;
public class Dispatcher {
public static String toPatch(DiffObject diffBase, PatchSet.Id revision, String fileName) {
return toPatch("", diffBase, revision, fileName, null, 0);
public static String toPatch(
@Nullable Project.NameKey project,
DiffObject diffBase,
PatchSet.Id revision,
String fileName) {
return toPatch("", project, diffBase, revision, fileName, null, 0);
}
public static String toPatch(
DiffObject diffBase, PatchSet.Id revision, String fileName, DisplaySide side, int line) {
return toPatch("", diffBase, revision, fileName, side, line);
@Nullable Project.NameKey project,
DiffObject diffBase,
PatchSet.Id revision,
String fileName,
DisplaySide side,
int line) {
return toPatch("", project, diffBase, revision, fileName, side, line);
}
public static String toSideBySide(DiffObject diffBase, Patch.Key id) {
return toPatch("sidebyside", diffBase, id);
public static String toSideBySide(
@Nullable Project.NameKey project,
DiffObject diffBase,
PatchSet.Id revision,
String fileName) {
return toPatch("sidebyside", project, diffBase, revision, fileName, null, 0);
}
public static String toSideBySide(DiffObject diffBase, PatchSet.Id revision, String fileName) {
return toPatch("sidebyside", diffBase, revision, fileName, null, 0);
public static String toUnified(
@Nullable Project.NameKey project,
DiffObject diffBase,
PatchSet.Id revision,
String fileName) {
return toPatch("unified", project, diffBase, revision, fileName, null, 0);
}
public static String toUnified(DiffObject diffBase, PatchSet.Id revision, String fileName) {
return toPatch("unified", diffBase, revision, fileName, null, 0);
public static String toPatch(
@Nullable Project.NameKey project, String type, DiffObject diffBase, Patch.Key id) {
return toPatch(type, project, diffBase, id.getParentKey(), id.get(), null, 0);
}
public static String toUnified(DiffObject diffBase, Patch.Key id) {
return toPatch("unified", diffBase, id);
public static String toEditScreen(
@Nullable Project.NameKey project, PatchSet.Id revision, String fileName) {
return toEditScreen(project, revision, fileName, 0);
}
public static String toPatch(String type, DiffObject diffBase, Patch.Key id) {
return toPatch(type, diffBase, id.getParentKey(), id.get(), null, 0);
}
public static String toEditScreen(PatchSet.Id revision, String fileName) {
return toEditScreen(revision, fileName, 0);
}
public static String toEditScreen(PatchSet.Id revision, String fileName, int line) {
return toPatch("edit", DiffObject.base(), revision, fileName, null, line);
public static String toEditScreen(
@Nullable Project.NameKey project, PatchSet.Id revision, String fileName, int line) {
return toPatch("edit", project, DiffObject.base(), revision, fileName, null, line);
}
private static String toPatch(
String type,
@Nullable Project.NameKey project,
DiffObject diffBase,
PatchSet.Id revision,
String fileName,
DisplaySide side,
int line) {
Change.Id c = revision.getParentKey();
StringBuilder p = new StringBuilder();
p.append("/c/").append(c).append("/");
StringBuilder p = new StringBuilder(PageLinks.toChange(project, c));
if (diffBase != null && diffBase.asString() != null) {
p.append(diffBase.asString()).append("..");
}
@@ -343,7 +356,8 @@ public class Dispatcher {
public void onFailure(Throwable caught) {
if ("default".equals(dashboardId) && RestApi.isNotFound(caught)) {
Gerrit.display(
toChangeQuery(PageLinks.projectQuery(new Project.NameKey(project))));
PageLinks.toChangeQuery(
PageLinks.projectQuery(new Project.NameKey(project))));
} else {
super.onFailure(caught);
}
@@ -380,15 +394,8 @@ public class Dispatcher {
}
}
Change.Id id;
int s = rest.indexOf('/');
if (0 <= s) {
id = Change.Id.parse(rest.substring(0, s));
rest = rest.substring(s + 1);
} else {
id = Change.Id.parse(rest);
rest = "";
}
ProjectChangeId id = ProjectChangeId.create(rest);
rest = rest.length() > id.identifierLength() ? rest.substring(id.identifierLength() + 1) : "";
if (rest.isEmpty()) {
FileTable.Mode mode = FileTable.Mode.REVIEW;
@@ -399,13 +406,14 @@ public class Dispatcher {
Gerrit.display(
token,
panel == null
? new ChangeScreen(id, DiffObject.base(), null, false, mode)
? new ChangeScreen(
id.getProject(), id.getChangeId(), DiffObject.base(), null, false, mode)
: new NotFoundScreen());
return;
}
String psIdStr;
s = rest.indexOf('/');
int s = rest.indexOf('/');
if (0 <= s) {
psIdStr = rest.substring(0, s);
rest = rest.substring(s + 1);
@@ -418,13 +426,13 @@ public class Dispatcher {
PatchSet.Id ps;
int dotdot = psIdStr.indexOf("..");
if (1 <= dotdot) {
base = DiffObject.parse(id, psIdStr.substring(0, dotdot));
base = DiffObject.parse(id.getChangeId(), psIdStr.substring(0, dotdot));
if (base == null) {
Gerrit.display(token, new NotFoundScreen());
}
psIdStr = psIdStr.substring(dotdot + 2);
}
ps = toPsId(id, psIdStr);
ps = toPsId(id.getChangeId(), psIdStr);
if (!rest.isEmpty()) {
DisplaySide side = DisplaySide.B;
@@ -440,12 +448,18 @@ public class Dispatcher {
rest = rest.substring(0, at);
}
Patch.Key p = new Patch.Key(ps, KeyUtil.decode(rest));
patch(token, base, p, side, line, panel);
patch(token, id.getProject(), base, p, side, line, panel);
} else {
if (panel == null) {
Gerrit.display(
token,
new ChangeScreen(id, base, String.valueOf(ps.get()), false, FileTable.Mode.REVIEW));
new ChangeScreen(
id.getProject(),
id.getChangeId(),
base,
String.valueOf(ps.get()),
false,
FileTable.Mode.REVIEW));
} else {
Gerrit.display(token, new NotFoundScreen());
}
@@ -466,7 +480,13 @@ public class Dispatcher {
}
private static void patch(
String token, DiffObject base, Patch.Key id, DisplaySide side, int line, String panelType) {
String token,
@Nullable Project.NameKey project,
DiffObject base,
Patch.Key id,
DisplaySide side,
int line,
String panelType) {
String panel = panelType;
if (panel == null) {
int c = token.lastIndexOf(',');
@@ -475,17 +495,17 @@ public class Dispatcher {
if ("".equals(panel) || /* DEPRECATED URL */ "cm".equals(panel)) {
if (preferUnified()) {
unified(token, base, id, side, line);
unified(token, project, base, id, side, line);
} else {
codemirror(token, base, id, side, line);
codemirror(token, base, project, id, side, line);
}
} else if ("sidebyside".equals(panel)) {
codemirror(token, base, id, side, line);
codemirror(token, base, project, id, side, line);
} else if ("unified".equals(panel)) {
unified(token, base, id, side, line);
unified(token, project, base, id, side, line);
} else if ("edit".equals(panel)) {
if (!Patch.isMagic(id.get()) || Patch.COMMIT_MSG.equals(id.get())) {
codemirrorForEdit(token, id, line);
codemirrorForEdit(token, project, id, line);
} else {
Gerrit.display(token, new NotFoundScreen());
}
@@ -501,6 +521,7 @@ public class Dispatcher {
private static void unified(
final String token,
final Project.NameKey project,
final DiffObject base,
final Patch.Key id,
final DisplaySide side,
@@ -511,7 +532,8 @@ public class Dispatcher {
public void onSuccess() {
Gerrit.display(
token,
new Unified(base, DiffObject.patchSet(id.getParentKey()), id.get(), side, line));
new Unified(
project, base, DiffObject.patchSet(id.getParentKey()), id.get(), side, line));
}
});
}
@@ -519,6 +541,7 @@ public class Dispatcher {
private static void codemirror(
final String token,
final DiffObject base,
@Nullable final Project.NameKey project,
final Patch.Key id,
final DisplaySide side,
final int line) {
@@ -528,17 +551,22 @@ public class Dispatcher {
public void onSuccess() {
Gerrit.display(
token,
new SideBySide(base, DiffObject.patchSet(id.getParentKey()), id.get(), side, line));
new SideBySide(
project, base, DiffObject.patchSet(id.getParentKey()), id.get(), side, line));
}
});
}
private static void codemirrorForEdit(String token, Patch.Key id, int line) {
private static void codemirrorForEdit(
final String token,
@Nullable final Project.NameKey project,
final Patch.Key id,
final int line) {
GWT.runAsync(
new AsyncSplit(token) {
@Override
public void onSuccess() {
Gerrit.display(token, new EditScreen(id, line));
Gerrit.display(token, new EditScreen(project, id, line));
}
});
}

View File

@@ -136,7 +136,8 @@ class SearchPanel extends Composite {
} else {
// changes
if (query.matches("^[1-9][0-9]*$")) {
Gerrit.display(PageLinks.toChange(Change.Id.parse(query)));
// Query is a change number. Project can't be supplied.
Gerrit.display(PageLinks.toChange(null, Change.Id.parse(query)));
} else {
Gerrit.display(PageLinks.toChangeQuery(query), QueryScreen.forQuery(query));
}

View File

@@ -48,7 +48,7 @@ class CreateChangeAction {
public void onSuccess(ChangeInfo result) {
sent = true;
hide();
Gerrit.display(PageLinks.toChange(result.legacyId()));
Gerrit.display(PageLinks.toChange(result.projectNameKey(), result.legacyId()));
}
@Override

View File

@@ -20,15 +20,17 @@ import com.google.gerrit.client.changes.ChangeApi;
import com.google.gerrit.client.info.ChangeInfo;
import com.google.gerrit.client.rpc.GerritCallback;
import com.google.gerrit.reviewdb.client.PatchSet;
import com.google.gerrit.reviewdb.client.Project;
import com.google.gerrit.reviewdb.client.RefNames;
import com.google.gwt.user.client.ui.Button;
public class EditConfigAction {
static void call(Button b, String project) {
static void call(Button b, Project.NameKey project) {
b.setEnabled(false);
ChangeApi.createChange(
project,
project.get(),
RefNames.REFS_CONFIG,
null,
AdminConstants.I.editConfigMessage(),
@@ -37,7 +39,8 @@ public class EditConfigAction {
@Override
public void onSuccess(ChangeInfo result) {
Gerrit.display(
Dispatcher.toEditScreen(new PatchSet.Id(result.legacyId(), 1), "project.config"));
Dispatcher.toEditScreen(
project, new PatchSet.Id(result.legacyId(), 1), "project.config"));
}
@Override

View File

@@ -287,7 +287,7 @@ public class ProjectAccessScreen extends ProjectScreen {
commitMessage.setText("");
error.clear();
if (changeId != null) {
Gerrit.display(PageLinks.toChange(changeId));
Gerrit.display(PageLinks.toChange(getProjectKey(), changeId));
} else {
displayReadOnly(access);
}

View File

@@ -657,7 +657,7 @@ public class ProjectInfoScreen extends ProjectScreen {
new ClickHandler() {
@Override
public void onClick(ClickEvent event) {
EditConfigAction.call(editConfig, getProjectKey().get());
EditConfigAction.call(editConfig, getProjectKey());
}
});
return editConfig;

View File

@@ -39,7 +39,7 @@ public class ChangeGlue {
}
public static void onAction(ChangeInfo change, ActionInfo action, ActionButton button) {
RestApi api = ChangeApi.change(change.legacyId().get()).view(action.id());
RestApi api = ChangeApi.change(change.project(), change.legacyId().get()).view(action.id());
JavaScriptObject f = get(action.id());
if (f != null) {
ActionContext c = ActionContext.create(api);

View File

@@ -29,7 +29,7 @@ import com.google.gwt.user.client.rpc.AsyncCallback;
class DefaultActions {
static void invoke(ChangeInfo change, ActionInfo action, RestApi api) {
invoke(action, api, callback(PageLinks.toChange(change.legacyId())));
invoke(action, api, callback(PageLinks.toChange(change.projectNameKey(), change.legacyId())));
}
static void invoke(Project.NameKey project, ActionInfo action, RestApi api) {

View File

@@ -25,7 +25,7 @@ import com.google.gwt.core.client.JavaScriptObject;
public class EditGlue {
public static void onAction(
ChangeInfo change, EditInfo edit, ActionInfo action, ActionButton button) {
RestApi api = ChangeApi.edit(change.legacyId().get()).view(action.id());
RestApi api = ChangeApi.edit(change.project(), change.legacyId().get()).view(action.id());
JavaScriptObject f = get(action.id());
if (f != null) {

View File

@@ -25,7 +25,9 @@ import com.google.gwt.core.client.JavaScriptObject;
public class RevisionGlue {
public static void onAction(
ChangeInfo change, RevisionInfo revision, ActionInfo action, ActionButton button) {
RestApi api = ChangeApi.revision(change.legacyId().get(), revision.name()).view(action.id());
RestApi api =
ChangeApi.revision(change.project(), change.legacyId().get(), revision.name())
.view(action.id());
JavaScriptObject f = get(action.id());
if (f != null) {

View File

@@ -20,25 +20,29 @@ import com.google.gerrit.client.info.ChangeInfo;
import com.google.gerrit.client.rpc.GerritCallback;
import com.google.gerrit.common.PageLinks;
import com.google.gerrit.reviewdb.client.Change;
import com.google.gerrit.reviewdb.client.Project;
import com.google.gwt.user.client.ui.Button;
class AbandonAction extends ActionMessageBox {
private final Project.NameKey project;
private final Change.Id id;
AbandonAction(Button b, Change.Id id) {
AbandonAction(Button b, Project.NameKey project, Change.Id id) {
super(b);
this.project = project;
this.id = id;
}
@Override
void send(String message) {
ChangeApi.abandon(
project.get(),
id.get(),
message,
new GerritCallback<ChangeInfo>() {
@Override
public void onSuccess(ChangeInfo result) {
Gerrit.display(PageLinks.toChange(id));
Gerrit.display(PageLinks.toChange(project, id));
hide();
}
});

View File

@@ -22,6 +22,7 @@ import com.google.gerrit.client.info.ChangeInfo.CommitInfo;
import com.google.gerrit.client.info.ChangeInfo.RevisionInfo;
import com.google.gerrit.client.rpc.NativeMap;
import com.google.gerrit.reviewdb.client.Change;
import com.google.gerrit.reviewdb.client.Project;
import com.google.gwt.core.client.GWT;
import com.google.gwt.event.dom.client.ClickEvent;
import com.google.gwt.uibinder.client.UiBinder;
@@ -78,7 +79,7 @@ class Actions extends Composite {
private Change.Id changeId;
private ChangeInfo changeInfo;
private String revision;
private String project;
private Project.NameKey project;
private String topic;
private String subject;
private String message;
@@ -99,7 +100,7 @@ class Actions extends Composite {
RevisionInfo revInfo = info.revision(revision);
CommitInfo commit = revInfo.commit();
changeId = info.legacyId();
project = info.project();
project = info.projectNameKey();
topic = info.topic();
subject = commit.subject();
message = commit.message();
@@ -181,7 +182,7 @@ class Actions extends Composite {
@UiHandler("followUp")
void onFollowUp(@SuppressWarnings("unused") ClickEvent e) {
if (followUpAction == null) {
followUpAction = new FollowUpAction(followUp, project, branch, topic, key);
followUpAction = new FollowUpAction(followUp, project.get(), branch, topic, key);
}
followUpAction.show();
}
@@ -189,7 +190,7 @@ class Actions extends Composite {
@UiHandler("abandon")
void onAbandon(@SuppressWarnings("unused") ClickEvent e) {
if (abandonAction == null) {
abandonAction = new AbandonAction(abandon, changeId);
abandonAction = new AbandonAction(abandon, project, changeId);
}
abandonAction.show();
}
@@ -197,24 +198,24 @@ class Actions extends Composite {
@UiHandler("deleteChange")
void onDeleteChange(@SuppressWarnings("unused") ClickEvent e) {
if (Window.confirm(Resources.C.deleteChange())) {
ChangeActions.delete(changeId, deleteChange);
ChangeActions.delete(project, changeId, deleteChange);
}
}
@UiHandler("markPrivate")
void onMarkPrivate(@SuppressWarnings("unused") ClickEvent e) {
ChangeActions.markPrivate(changeId, markPrivate);
ChangeActions.markPrivate(project, changeId, markPrivate);
}
@UiHandler("unmarkPrivate")
void onUnmarkPrivate(@SuppressWarnings("unused") ClickEvent e) {
ChangeActions.unmarkPrivate(changeId, unmarkPrivate);
ChangeActions.unmarkPrivate(project, changeId, unmarkPrivate);
}
@UiHandler("restore")
void onRestore(@SuppressWarnings("unused") ClickEvent e) {
if (restoreAction == null) {
restoreAction = new RestoreAction(restore, changeId);
restoreAction = new RestoreAction(restore, project, changeId);
}
restoreAction.show();
}
@@ -237,7 +238,7 @@ class Actions extends Composite {
@UiHandler("revert")
void onRevert(@SuppressWarnings("unused") ClickEvent e) {
RevertAction.call(revert, changeId, revision, subject);
RevertAction.call(revert, changeId, project, revision, subject);
}
private static void a2b(NativeMap<ActionInfo> actions, String a, Button b) {

View File

@@ -16,6 +16,7 @@ package com.google.gerrit.client.change;
import com.google.gerrit.client.info.ChangeInfo.RevisionInfo;
import com.google.gerrit.reviewdb.client.Change;
import com.google.gerrit.reviewdb.client.Project;
import com.google.gwt.event.logical.shared.CloseEvent;
import com.google.gwt.event.logical.shared.CloseHandler;
import com.google.gwt.user.client.ui.PopupPanel;
@@ -23,6 +24,7 @@ import com.google.gwt.user.client.ui.Widget;
import com.google.gwtexpui.globalkey.client.GlobalKey;
class AddFileAction {
private final Project.NameKey project;
private final Change.Id changeId;
private final RevisionInfo revision;
private final ChangeScreen.Style style;
@@ -33,11 +35,13 @@ class AddFileAction {
private PopupPanel popup;
AddFileAction(
Project.NameKey project,
Change.Id changeId,
RevisionInfo revision,
ChangeScreen.Style style,
Widget addButton,
FileTable files) {
this.project = project;
this.changeId = changeId;
this.revision = revision;
this.style = style;
@@ -53,7 +57,7 @@ class AddFileAction {
files.unregisterKeys();
if (addBox == null) {
addBox = new AddFileBox(changeId, revision, files);
addBox = new AddFileBox(project, changeId, revision, files);
}
addBox.clearPath();

View File

@@ -20,6 +20,7 @@ import com.google.gerrit.client.info.ChangeInfo.RevisionInfo;
import com.google.gerrit.client.ui.RemoteSuggestBox;
import com.google.gerrit.reviewdb.client.Change;
import com.google.gerrit.reviewdb.client.PatchSet;
import com.google.gerrit.reviewdb.client.Project;
import com.google.gwt.core.client.GWT;
import com.google.gwt.event.dom.client.ClickEvent;
import com.google.gwt.event.logical.shared.CloseEvent;
@@ -40,6 +41,7 @@ class AddFileBox extends Composite {
private static final Binder uiBinder = GWT.create(Binder.class);
private final Project.NameKey project;
private final Change.Id changeId;
private final RevisionInfo revision;
private final FileTable fileTable;
@@ -50,12 +52,13 @@ class AddFileBox extends Composite {
@UiField(provided = true)
RemoteSuggestBox path;
AddFileBox(Change.Id changeId, RevisionInfo revision, FileTable files) {
AddFileBox(Project.NameKey project, Change.Id changeId, RevisionInfo revision, FileTable files) {
this.project = project;
this.changeId = changeId;
this.revision = revision;
this.fileTable = files;
path = new RemoteSuggestBox(new PathSuggestOracle(changeId, revision));
path = new RemoteSuggestBox(new PathSuggestOracle(project, changeId, revision));
path.addSelectionHandler(
new SelectionHandler<String>() {
@Override
@@ -90,7 +93,8 @@ class AddFileBox extends Composite {
private void open(String path) {
hide();
Gerrit.display(Dispatcher.toEditScreen(new PatchSet.Id(changeId, revision._number()), path));
Gerrit.display(
Dispatcher.toEditScreen(project, new PatchSet.Id(changeId, revision._number()), path));
}
@UiHandler("cancel")

View File

@@ -26,6 +26,7 @@ import com.google.gerrit.client.ui.InlineHyperlink;
import com.google.gerrit.client.ui.RemoteSuggestBox;
import com.google.gerrit.common.PageLinks;
import com.google.gerrit.reviewdb.client.Change;
import com.google.gerrit.reviewdb.client.Project;
import com.google.gwt.core.client.GWT;
import com.google.gwt.dom.client.Element;
import com.google.gwt.event.dom.client.ClickEvent;
@@ -62,6 +63,7 @@ public class Assignee extends Composite {
private AssigneeSuggestOracle assigneeSuggestOracle;
private Change.Id changeId;
private Project.NameKey project;
private boolean canEdit;
private AccountInfo currentAssignee;
@@ -98,6 +100,7 @@ public class Assignee extends Composite {
void set(ChangeInfo info) {
this.changeId = info.legacyId();
this.project = info.projectNameKey();
this.canEdit = info.hasActions() && info.actions().containsKey("assignee");
setAssignee(info.assignee());
editAssigneeIcon.setVisible(canEdit);
@@ -143,6 +146,7 @@ public class Assignee extends Composite {
private void editAssignee(String assignee) {
if (assignee.trim().isEmpty()) {
ChangeApi.deleteAssignee(
project.get(),
changeId.get(),
new GerritCallback<AccountInfo>() {
@Override
@@ -166,6 +170,7 @@ public class Assignee extends Composite {
});
} else {
ChangeApi.setAssignee(
project.get(),
changeId.get(),
assignee,
new GerritCallback<AccountInfo>() {

View File

@@ -19,38 +19,42 @@ import com.google.gerrit.client.changes.ChangeApi;
import com.google.gerrit.client.rpc.GerritCallback;
import com.google.gerrit.common.PageLinks;
import com.google.gerrit.reviewdb.client.Change;
import com.google.gerrit.reviewdb.client.Project;
import com.google.gwt.core.client.JavaScriptObject;
import com.google.gwt.user.client.rpc.AsyncCallback;
import com.google.gwt.user.client.ui.Button;
public class ChangeActions {
static void publish(Change.Id id, String revision, Button... draftButtons) {
ChangeApi.publish(id.get(), revision, cs(id, draftButtons));
static void publish(
Project.NameKey project, Change.Id id, String revision, Button... draftButtons) {
ChangeApi.publish(project.get(), id.get(), revision, cs(project, id, draftButtons));
}
static void delete(Change.Id id, String revision, Button... draftButtons) {
ChangeApi.deleteRevision(id.get(), revision, cs(id, draftButtons));
static void delete(
Project.NameKey project, Change.Id id, String revision, Button... draftButtons) {
ChangeApi.deleteRevision(project.get(), id.get(), revision, cs(project, id, draftButtons));
}
static void delete(Change.Id id, Button... draftButtons) {
ChangeApi.deleteChange(id.get(), mine(draftButtons));
static void delete(Project.NameKey project, Change.Id id, Button... draftButtons) {
ChangeApi.deleteChange(project.get(), id.get(), mine(draftButtons));
}
static void markPrivate(Change.Id id, Button... draftButtons) {
ChangeApi.markPrivate(id.get(), cs(id, draftButtons));
static void markPrivate(Project.NameKey project, Change.Id id, Button... draftButtons) {
ChangeApi.markPrivate(project.get(), id.get(), cs(project, id, draftButtons));
}
static void unmarkPrivate(Change.Id id, Button... draftButtons) {
ChangeApi.unmarkPrivate(id.get(), cs(id, draftButtons));
static void unmarkPrivate(Project.NameKey project, Change.Id id, Button... draftButtons) {
ChangeApi.unmarkPrivate(project.get(), id.get(), cs(project, id, draftButtons));
}
public static GerritCallback<JavaScriptObject> cs(final Change.Id id, Button... draftButtons) {
public static GerritCallback<JavaScriptObject> cs(
Project.NameKey project, final Change.Id id, Button... draftButtons) {
setEnabled(false, draftButtons);
return new GerritCallback<JavaScriptObject>() {
@Override
public void onSuccess(JavaScriptObject result) {
Gerrit.display(PageLinks.toChange(id));
Gerrit.display(PageLinks.toChange(project, id));
}
@Override
@@ -58,7 +62,7 @@ public class ChangeActions {
setEnabled(true, draftButtons);
if (SubmitFailureDialog.isConflict(err)) {
new SubmitFailureDialog(err.getMessage()).center();
Gerrit.display(PageLinks.toChange(id));
Gerrit.display(PageLinks.toChange(project, id));
} else {
super.onFailure(err);
}

View File

@@ -57,12 +57,14 @@ import com.google.gerrit.client.ui.Hyperlink;
import com.google.gerrit.client.ui.InlineHyperlink;
import com.google.gerrit.client.ui.Screen;
import com.google.gerrit.client.ui.UserActivityMonitor;
import com.google.gerrit.common.Nullable;
import com.google.gerrit.common.PageLinks;
import com.google.gerrit.extensions.client.ListChangesOption;
import com.google.gerrit.extensions.client.SubmitType;
import com.google.gerrit.reviewdb.client.Change;
import com.google.gerrit.reviewdb.client.Change.Status;
import com.google.gerrit.reviewdb.client.PatchSet;
import com.google.gerrit.reviewdb.client.Project;
import com.google.gwt.core.client.GWT;
import com.google.gwt.core.client.JsArray;
import com.google.gwt.core.client.JsArrayString;
@@ -159,6 +161,7 @@ public class ChangeScreen extends Screen {
}
private final Change.Id changeId;
@Nullable private Project.NameKey project;
private DiffObject base;
private String revision;
private ChangeInfo changeInfo;
@@ -254,20 +257,27 @@ public class ChangeScreen extends Screen {
private RenameFileAction renameFileAction;
public ChangeScreen(
@Nullable Project.NameKey project,
Change.Id changeId,
DiffObject base,
String revision,
boolean openReplyBox,
FileTable.Mode mode) {
this.project = project;
this.changeId = changeId;
this.base = base;
this.revision = normalize(revision);
this.openReplyBox = openReplyBox;
this.fileTableMode = mode;
this.lc = new LocalComments(changeId);
this.lc = new LocalComments(project, changeId);
add(uiBinder.createAndBindUi(this));
}
@SuppressWarnings("null")
public Project.NameKey getProject() {
return project;
}
PatchSet.Id getPatchSetId() {
return new PatchSet.Id(changeInfo.legacyId(), changeInfo.revisions().get(revision)._number());
}
@@ -291,6 +301,7 @@ public class ChangeScreen extends Screen {
public void onFailure(Throwable caught) {}
}));
ChangeApi.editWithFiles(
Project.NameKey.asStringOrNull(project),
changeId.get(),
group.add(
new AsyncCallback<EditInfo>() {
@@ -310,6 +321,15 @@ public class ChangeScreen extends Screen {
@Override
public void onSuccess(ChangeInfo info) {
info.init();
if (project == null) {
// Update Project when the first API call succeeded if it wasn't already present.
// This is the case when the user used a URL that doesn't include the project.
// Setting it here will rewrite the URL token to include the project (visible to
// the user) and all future API calls made from the change screen will use
// project/+/changeId to identify the change.
project = info.projectNameKey();
}
initCurrentRevision(info);
final RevisionInfo rev = info.revision(revision);
CallbackGroup group = new CallbackGroup();
@@ -434,7 +454,7 @@ public class ChangeScreen extends Screen {
}
void loadChangeInfo(boolean fg, AsyncCallback<ChangeInfo> cb) {
RestApi call = ChangeApi.detail(changeId.get());
RestApi call = ChangeApi.detail(Project.NameKey.asStringOrNull(project), changeId.get());
EnumSet<ListChangesOption> opts =
EnumSet.of(ListChangesOption.ALL_REVISIONS, ListChangesOption.CHANGE_ACTIONS);
if (enableSignedPush()) {
@@ -448,7 +468,7 @@ public class ChangeScreen extends Screen {
}
void loadRevisionInfo() {
RestApi call = ChangeApi.actions(changeId.get(), revision);
RestApi call = ChangeApi.actions(getProject().get(), changeId.get(), revision);
call.background();
call.get(
new GerritCallback<NativeMap<ActionInfo>>() {
@@ -517,6 +537,7 @@ public class ChangeScreen extends Screen {
if (0 <= i + offset && i + offset < revisions.length()) {
Gerrit.display(
PageLinks.toChange(
project,
new PatchSet.Id(changeInfo.legacyId(), revisions.get(i + offset)._number())));
return;
}
@@ -527,7 +548,9 @@ public class ChangeScreen extends Screen {
private void initIncludedInAction(ChangeInfo info) {
if (info.status() == Status.MERGED) {
includedInAction = new IncludedInAction(info.legacyId(), style, headerLine, includedIn);
includedInAction =
new IncludedInAction(
info.projectNameKey(), info.legacyId(), style, headerLine, includedIn);
includedIn.setVisible(true);
}
}
@@ -567,7 +590,8 @@ public class ChangeScreen extends Screen {
patchSetsText.setInnerText(Resources.M.patchSets(currentlyViewedPatchSet, currentPatchSet));
updatePatchSetsTextStyle(isPatchSetCurrent);
patchSetsAction =
new PatchSetsAction(info.legacyId(), revision, edit, style, headerLine, patchSets);
new PatchSetsAction(
info.projectNameKey(), info.legacyId(), revision, edit, style, headerLine, patchSets);
RevisionInfo revInfo = info.revision(revision);
if (revInfo.draft()) {
@@ -623,11 +647,14 @@ public class ChangeScreen extends Screen {
renameFile.setVisible(!editMode.isVisible());
reviewMode.setVisible(!editMode.isVisible());
addFileAction =
new AddFileAction(changeId, info.revision(revision), style, addFile, files);
new AddFileAction(
info.projectNameKey(), changeId, info.revision(revision), style, addFile, files);
deleteFileAction =
new DeleteFileAction(changeId, info.revision(revision), style, addFile);
new DeleteFileAction(
info.projectNameKey(), changeId, info.revision(revision), style, addFile);
renameFileAction =
new RenameFileAction(changeId, info.revision(revision), style, addFile);
new RenameFileAction(
info.projectNameKey(), changeId, info.revision(revision), style, addFile);
} else {
editMode.setVisible(false);
addFile.setVisible(false);
@@ -661,30 +688,30 @@ public class ChangeScreen extends Screen {
@UiHandler("publishEdit")
void onPublishEdit(@SuppressWarnings("unused") ClickEvent e) {
EditActions.publishEdit(changeId, publishEdit, rebaseEdit, deleteEdit);
EditActions.publishEdit(getProject(), changeId, publishEdit, rebaseEdit, deleteEdit);
}
@UiHandler("rebaseEdit")
void onRebaseEdit(@SuppressWarnings("unused") ClickEvent e) {
EditActions.rebaseEdit(changeId, publishEdit, rebaseEdit, deleteEdit);
EditActions.rebaseEdit(getProject(), changeId, publishEdit, rebaseEdit, deleteEdit);
}
@UiHandler("deleteEdit")
void onDeleteEdit(@SuppressWarnings("unused") ClickEvent e) {
if (Window.confirm(Resources.C.deleteChangeEdit())) {
EditActions.deleteEdit(changeId, publishEdit, rebaseEdit, deleteEdit);
EditActions.deleteEdit(getProject(), changeId, publishEdit, rebaseEdit, deleteEdit);
}
}
@UiHandler("publish")
void onPublish(@SuppressWarnings("unused") ClickEvent e) {
ChangeActions.publish(changeId, revision, publish, deleteRevision);
ChangeActions.publish(getProject(), changeId, revision, publish, deleteRevision);
}
@UiHandler("deleteRevision")
void onDeleteRevision(@SuppressWarnings("unused") ClickEvent e) {
if (Window.confirm(Resources.C.deleteDraftRevision())) {
ChangeActions.delete(changeId, revision, publish, deleteRevision);
ChangeActions.delete(getProject(), changeId, revision, publish, deleteRevision);
}
}
@@ -704,7 +731,7 @@ public class ChangeScreen extends Screen {
new KeyCommand(0, 'R', Util.C.keyReloadChange()) {
@Override
public void onKeyPress(KeyPressEvent event) {
Gerrit.display(PageLinks.toChange(changeId));
Gerrit.display(PageLinks.toChange(project, changeId));
}
});
keysNavigation.add(
@@ -814,21 +841,20 @@ public class ChangeScreen extends Screen {
}
private void scrollToPath(String token) {
int s = token.indexOf('/');
ProjectChangeId cId;
try {
String c = token.substring(0, s);
int editIndex = c.indexOf(",edit");
if (editIndex > 0) {
c = c.substring(0, editIndex);
}
if (s < 0 || !changeId.equals(Change.Id.parse(c))) {
return; // Unrelated URL, do not scroll.
}
cId = ProjectChangeId.create(token);
} catch (IllegalArgumentException e) {
// Scrolling is best-effort.
return;
}
if (!changeId.equals(cId.getChangeId())) {
return; // Unrelated URL, do not scroll.
}
s = token.indexOf('/', s + 1);
// Extract the start of a file path. The patch set is always contained in the URL and separated
// by from the changeId by a forward slash. Example: /c/project/+/123/1/folder/file.txt
int s = token.indexOf('/', cId.identifierLength() + 1);
if (s < 0) {
return; // URL does not name a file.
}
@@ -873,7 +899,7 @@ public class ChangeScreen extends Screen {
@UiHandler("permalink")
void onReload(ClickEvent e) {
e.preventDefault();
Gerrit.display(PageLinks.toChange(changeId));
Gerrit.display(PageLinks.toChange(project, changeId));
}
private void onReply() {
@@ -1056,7 +1082,10 @@ public class ChangeScreen extends Screen {
}
private void updateToken(ChangeInfo info, DiffObject base, RevisionInfo rev) {
StringBuilder token = new StringBuilder("/c/").append(info._number()).append("/");
StringBuilder token =
new StringBuilder("/c/")
.append(PageLinks.toChangeId(info.projectNameKey(), info.legacyId()))
.append("/");
if (base.asString() != null) {
token.append(base.asString()).append("..");
}
@@ -1090,7 +1119,7 @@ public class ChangeScreen extends Screen {
loadFileList(base, baseRev, rev, myLastReply, group, comments, drafts);
if (Gerrit.isSignedIn() && fileTableMode == FileTable.Mode.REVIEW) {
ChangeApi.revision(changeId.get(), rev.name())
ChangeApi.revision(getProject().get(), changeId.get(), rev.name())
.view("files")
.addParameterTrue("reviewed")
.get(
@@ -1116,6 +1145,7 @@ public class ChangeScreen extends Screen {
final List<NativeMap<JsArray<CommentInfo>>> comments,
final List<NativeMap<JsArray<CommentInfo>>> drafts) {
DiffApi.list(
getProject().get(),
changeId.get(),
rev.name(),
baseRev,
@@ -1126,6 +1156,7 @@ public class ChangeScreen extends Screen {
files.set(
base,
new PatchSet.Id(changeId, rev._number()),
getProject(),
style,
reply,
fileTableMode,
@@ -1149,7 +1180,7 @@ public class ChangeScreen extends Screen {
final List<NativeMap<JsArray<CommentInfo>>> r = new ArrayList<>(1);
// TODO(dborowitz): Could eliminate this call by adding an option to include
// inline comments in the change detail.
ChangeApi.comments(changeId.get())
ChangeApi.comments(getProject().get(), changeId.get())
.get(
group.add(
new AsyncCallback<NativeMap<JsArray<CommentInfo>>>() {
@@ -1188,7 +1219,7 @@ public class ChangeScreen extends Screen {
private List<NativeMap<JsArray<CommentInfo>>> loadDrafts(RevisionInfo rev, CallbackGroup group) {
final List<NativeMap<JsArray<CommentInfo>>> r = new ArrayList<>(1);
if (Gerrit.isSignedIn()) {
ChangeApi.revision(changeId.get(), rev.name())
ChangeApi.revision(getProject().get(), changeId.get(), rev.name())
.view("drafts")
.get(
group.add(
@@ -1213,6 +1244,7 @@ public class ChangeScreen extends Screen {
}
ChangeApi.commitWithLinks(
getProject().get(),
changeId.get(),
rev.name(),
group.add(
@@ -1578,7 +1610,7 @@ public class ChangeScreen extends Screen {
new UpdateAvailableBar() {
@Override
void onShow() {
Gerrit.display(PageLinks.toChange(changeId));
Gerrit.display(PageLinks.toChange(project, changeId));
}
@Override

View File

@@ -32,11 +32,11 @@ class CherryPickAction {
final Button b,
final ChangeInfo info,
final String revision,
String project,
final Project.NameKey project,
final String commitMessage) {
// TODO Replace CherryPickDialog with a nicer looking display.
b.setEnabled(false);
new CherryPickDialog(new Project.NameKey(project)) {
new CherryPickDialog(project) {
{
sendButton.setText(Util.C.buttonCherryPickChangeSend());
if (info.status() == Change.Status.MERGED) {
@@ -49,6 +49,7 @@ class CherryPickAction {
@Override
public void onSend() {
ChangeApi.cherrypick(
info.project(),
info.legacyId().get(),
revision,
getDestinationBranch(),
@@ -58,7 +59,7 @@ class CherryPickAction {
public void onSuccess(ChangeInfo result) {
sent = true;
hide();
Gerrit.display(PageLinks.toChange(result.legacyId()));
Gerrit.display(PageLinks.toChange(project, result.legacyId()));
}
@Override

View File

@@ -16,6 +16,7 @@ package com.google.gerrit.client.change;
import com.google.gerrit.client.info.ChangeInfo.RevisionInfo;
import com.google.gerrit.reviewdb.client.Change;
import com.google.gerrit.reviewdb.client.Project;
import com.google.gwt.event.logical.shared.CloseEvent;
import com.google.gwt.event.logical.shared.CloseHandler;
import com.google.gwt.user.client.ui.PopupPanel;
@@ -23,6 +24,7 @@ import com.google.gwt.user.client.ui.Widget;
import com.google.gwtexpui.globalkey.client.GlobalKey;
class DeleteFileAction {
private final Project.NameKey project;
private final Change.Id changeId;
private final RevisionInfo revision;
private final ChangeScreen.Style style;
@@ -32,7 +34,12 @@ class DeleteFileAction {
private PopupPanel popup;
DeleteFileAction(
Change.Id changeId, RevisionInfo revision, ChangeScreen.Style style, Widget deleteButton) {
Project.NameKey project,
Change.Id changeId,
RevisionInfo revision,
ChangeScreen.Style style,
Widget deleteButton) {
this.project = project;
this.changeId = changeId;
this.revision = revision;
this.style = style;
@@ -46,7 +53,7 @@ class DeleteFileAction {
}
if (deleteBox == null) {
deleteBox = new DeleteFileBox(changeId, revision);
deleteBox = new DeleteFileBox(project, changeId, revision);
}
deleteBox.clearPath();

View File

@@ -21,6 +21,7 @@ import com.google.gerrit.client.info.ChangeInfo.RevisionInfo;
import com.google.gerrit.client.ui.RemoteSuggestBox;
import com.google.gerrit.common.PageLinks;
import com.google.gerrit.reviewdb.client.Change;
import com.google.gerrit.reviewdb.client.Project;
import com.google.gwt.core.client.GWT;
import com.google.gwt.event.dom.client.ClickEvent;
import com.google.gwt.event.logical.shared.CloseEvent;
@@ -42,6 +43,7 @@ class DeleteFileBox extends Composite {
private static final Binder uiBinder = GWT.create(Binder.class);
private final Project.NameKey project;
private final Change.Id changeId;
@UiField Button delete;
@@ -50,10 +52,11 @@ class DeleteFileBox extends Composite {
@UiField(provided = true)
RemoteSuggestBox path;
DeleteFileBox(Change.Id changeId, RevisionInfo revision) {
DeleteFileBox(Project.NameKey project, Change.Id changeId, RevisionInfo revision) {
this.project = project;
this.changeId = changeId;
path = new RemoteSuggestBox(new PathSuggestOracle(changeId, revision));
path = new RemoteSuggestBox(new PathSuggestOracle(project, changeId, revision));
path.addSelectionHandler(
new SelectionHandler<String>() {
@Override
@@ -88,12 +91,13 @@ class DeleteFileBox extends Composite {
private void delete(String path) {
hide();
ChangeEditApi.delete(
project.get(),
changeId.get(),
path,
new AsyncCallback<VoidResult>() {
@Override
public void onSuccess(VoidResult result) {
Gerrit.display(PageLinks.toChangeInEditMode(changeId));
Gerrit.display(PageLinks.toChangeInEditMode(project, changeId));
}
@Override

View File

@@ -78,7 +78,7 @@ class DownloadBox extends VerticalPanel {
protected void onLoad() {
if (fetch == null) {
if (psId.get() == 0) {
ChangeApi.editWithCommands(change.legacyId().get())
ChangeApi.editWithCommands(change.project(), change.legacyId().get())
.get(
new AsyncCallback<EditInfo>() {
@Override
@@ -91,7 +91,7 @@ class DownloadBox extends VerticalPanel {
public void onFailure(Throwable caught) {}
});
} else {
RestApi call = ChangeApi.detail(change.legacyId().get());
RestApi call = ChangeApi.detail(change.project(), change.legacyId().get());
ChangeList.addOptions(
call,
EnumSet.of(

View File

@@ -19,29 +19,31 @@ import com.google.gerrit.client.changes.ChangeApi;
import com.google.gerrit.client.rpc.GerritCallback;
import com.google.gerrit.common.PageLinks;
import com.google.gerrit.reviewdb.client.Change;
import com.google.gerrit.reviewdb.client.Project;
import com.google.gwt.core.client.JavaScriptObject;
import com.google.gwt.user.client.ui.Button;
public class EditActions {
static void deleteEdit(Change.Id id, Button... editButtons) {
ChangeApi.deleteEdit(id.get(), cs(id, editButtons));
static void deleteEdit(Project.NameKey project, Change.Id id, Button... editButtons) {
ChangeApi.deleteEdit(project.get(), id.get(), cs(project, id, editButtons));
}
static void publishEdit(Change.Id id, Button... editButtons) {
ChangeApi.publishEdit(id.get(), cs(id, editButtons));
static void publishEdit(Project.NameKey project, Change.Id id, Button... editButtons) {
ChangeApi.publishEdit(project.get(), id.get(), cs(project, id, editButtons));
}
static void rebaseEdit(Change.Id id, Button... editButtons) {
ChangeApi.rebaseEdit(id.get(), cs(id, editButtons));
static void rebaseEdit(Project.NameKey project, Change.Id id, Button... editButtons) {
ChangeApi.rebaseEdit(project.get(), id.get(), cs(project, id, editButtons));
}
public static GerritCallback<JavaScriptObject> cs(final Change.Id id, Button... editButtons) {
public static GerritCallback<JavaScriptObject> cs(
Project.NameKey project, final Change.Id id, Button... editButtons) {
setEnabled(false, editButtons);
return new GerritCallback<JavaScriptObject>() {
@Override
public void onSuccess(JavaScriptObject result) {
Gerrit.display(PageLinks.toChange(id));
Gerrit.display(PageLinks.toChange(project, id));
}
@Override
@@ -49,7 +51,7 @@ public class EditActions {
setEnabled(true, editButtons);
if (SubmitFailureDialog.isConflict(err)) {
new SubmitFailureDialog(err.getMessage()).center();
Gerrit.display(PageLinks.toChange(id));
Gerrit.display(PageLinks.toChange(project, id));
} else {
super.onFailure(err);
}

View File

@@ -19,6 +19,7 @@ import com.google.gerrit.client.changes.CommentInfo;
import com.google.gerrit.client.ui.CommentLinkProcessor;
import com.google.gerrit.client.ui.InlineHyperlink;
import com.google.gerrit.reviewdb.client.PatchSet;
import com.google.gerrit.reviewdb.client.Project;
import com.google.gwt.core.client.GWT;
import com.google.gwt.uibinder.client.UiBinder;
import com.google.gwt.uibinder.client.UiField;
@@ -36,17 +37,21 @@ class FileComments extends Composite {
@UiField FlowPanel comments;
FileComments(
CommentLinkProcessor clp, PatchSet.Id defaultPs, String title, List<CommentInfo> list) {
CommentLinkProcessor clp,
Project.NameKey project,
PatchSet.Id defaultPs,
String title,
List<CommentInfo> list) {
initWidget(uiBinder.createAndBindUi(this));
path.setTargetHistoryToken(url(defaultPs, list.get(0)));
path.setTargetHistoryToken(url(project, defaultPs, list.get(0)));
path.setText(title);
for (CommentInfo c : list) {
comments.add(new LineComment(clp, defaultPs, c));
comments.add(new LineComment(clp, project, defaultPs, c));
}
}
private static String url(PatchSet.Id ps, CommentInfo info) {
return Dispatcher.toPatch(null, ps, info.path());
private static String url(Project.NameKey project, PatchSet.Id ps, CommentInfo info) {
return Dispatcher.toPatch(project, null, ps, info.path());
}
}

View File

@@ -41,6 +41,7 @@ import com.google.gerrit.extensions.client.Side;
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.gwt.core.client.GWT;
import com.google.gwt.core.client.JsArray;
import com.google.gwt.core.client.JsArrayString;
@@ -199,6 +200,7 @@ public class FileTable extends FlowPanel {
private DiffObject base;
private PatchSet.Id curr;
private Project.NameKey project;
private MyTable table;
private boolean register;
private JsArrayString reviewed;
@@ -217,12 +219,14 @@ public class FileTable extends FlowPanel {
public void set(
DiffObject base,
PatchSet.Id curr,
Project.NameKey project,
ChangeScreen.Style style,
Widget replyButton,
Mode mode,
boolean editExists) {
this.base = base;
this.curr = curr;
this.project = project;
this.style = style;
this.replyButton = replyButton;
this.mode = mode;
@@ -318,10 +322,10 @@ public class FileTable extends FlowPanel {
private String url(FileInfo info) {
return info.binary()
? Dispatcher.toUnified(base, curr, info.path())
? Dispatcher.toUnified(project, base, curr, info.path())
: mode == Mode.REVIEW
? Dispatcher.toPatch(base, curr, info.path())
: Dispatcher.toEditScreen(curr, info.path());
? Dispatcher.toPatch(project, base, curr, info.path())
: Dispatcher.toEditScreen(project, curr, info.path());
}
private final class MyTable extends NavigationTable<FileInfo> {
@@ -364,12 +368,13 @@ public class FileTable extends FlowPanel {
void onDelete(int idx) {
String path = list.get(idx).path();
ChangeEditApi.delete(
project.get(),
curr.getParentKey().get(),
path,
new AsyncCallback<VoidResult>() {
@Override
public void onSuccess(VoidResult result) {
Gerrit.display(PageLinks.toChangeInEditMode(curr.getParentKey()));
Gerrit.display(PageLinks.toChangeInEditMode(project, curr.getParentKey()));
}
@Override
@@ -380,12 +385,13 @@ public class FileTable extends FlowPanel {
void onRestore(int idx) {
String path = list.get(idx).path();
ChangeEditApi.restore(
project.get(),
curr.getParentKey().get(),
path,
new AsyncCallback<VoidResult>() {
@Override
public void onSuccess(VoidResult result) {
Gerrit.display(PageLinks.toChangeInEditMode(curr.getParentKey()));
Gerrit.display(PageLinks.toChangeInEditMode(project, curr.getParentKey()));
}
@Override
@@ -398,7 +404,8 @@ public class FileTable extends FlowPanel {
}
private void setReviewed(FileInfo info, boolean r) {
RestApi api = ChangeApi.revision(curr).view("files").id(info.path()).view("reviewed");
RestApi api =
ChangeApi.revision(project.get(), curr).view("files").id(info.path()).view("reviewed");
if (r) {
api.put(CallbackGroup.<ReviewInfo>emptyCallback());
} else {

View File

@@ -46,7 +46,7 @@ class FollowUpAction extends ActionMessageBox {
new GerritCallback<ChangeInfo>() {
@Override
public void onSuccess(ChangeInfo result) {
Gerrit.display(PageLinks.toChange(result.legacyId()));
Gerrit.display(PageLinks.toChange(result.projectNameKey(), result.legacyId()));
hide();
}
});

View File

@@ -21,6 +21,7 @@ import com.google.gerrit.client.rpc.Natives;
import com.google.gerrit.common.PageLinks;
import com.google.gerrit.reviewdb.client.Change;
import com.google.gerrit.reviewdb.client.PatchSet;
import com.google.gerrit.reviewdb.client.Project;
import com.google.gwt.core.client.GWT;
import com.google.gwt.core.client.JavaScriptObject;
import com.google.gwt.core.client.JsArrayString;
@@ -73,14 +74,14 @@ public class Hashtags extends Composite {
if (hashtags != null) {
final ChangeScreen screen = ChangeScreen.get(event);
final PatchSet.Id psId = screen.getPatchSetId();
ChangeApi.hashtags(psId.getParentKey().get())
ChangeApi.hashtags(screen.getProject().get(), psId.getParentKey().get())
.post(
PostInput.create(null, hashtags),
new GerritCallback<JavaScriptObject>() {
@Override
public void onSuccess(JavaScriptObject result) {
if (screen.isCurrentView()) {
Gerrit.display(PageLinks.toChange(psId));
Gerrit.display(PageLinks.toChange(screen.getProject(), psId));
}
}
});
@@ -107,6 +108,7 @@ public class Hashtags extends Composite {
private ChangeScreen.Style style;
private Change.Id changeId;
private Project.NameKey project;
public Hashtags() {
@@ -141,6 +143,7 @@ public class Hashtags extends Composite {
void set(ChangeInfo info, String revision) {
psId = new PatchSet.Id(info.legacyId(), info.revisions().get(revision)._number());
project = info.projectNameKey();
canEdit = info.hasActions() && info.actions().containsKey("hashtags");
this.changeId = info.legacyId();
@@ -219,13 +222,14 @@ public class Hashtags extends Composite {
}
private void addHashtag(String hashtags) {
ChangeApi.hashtags(changeId.get())
ChangeApi.hashtags(project.get(), changeId.get())
.post(
PostInput.create(hashtags, null),
new GerritCallback<JsArrayString>() {
@Override
public void onSuccess(JsArrayString result) {
Gerrit.display(PageLinks.toChange(psId.getParentKey(), String.valueOf(psId.get())));
Gerrit.display(
PageLinks.toChange(project, psId.getParentKey(), String.valueOf(psId.get())));
}
@Override

View File

@@ -21,6 +21,7 @@ import com.google.gerrit.client.rpc.NativeMap;
import com.google.gerrit.client.rpc.Natives;
import com.google.gerrit.client.ui.CommentLinkProcessor;
import com.google.gerrit.reviewdb.client.Change;
import com.google.gerrit.reviewdb.client.Project;
import com.google.gwt.core.client.JsArray;
import com.google.gwt.user.client.ui.FlowPanel;
import com.google.gwt.user.client.ui.Widget;
@@ -35,6 +36,7 @@ class History extends FlowPanel {
private CommentLinkProcessor clp;
private ReplyAction replyAction;
private Change.Id changeId;
private Project.NameKey project;
private final Map<Integer, List<CommentInfo>> byAuthor = new HashMap<>();
@@ -42,6 +44,7 @@ class History extends FlowPanel {
this.clp = clp;
this.replyAction = ra;
this.changeId = id;
this.project = info.projectNameKey();
JsArray<MessageInfo> messages = info.messages();
if (messages != null) {
@@ -80,6 +83,10 @@ class History extends FlowPanel {
return changeId;
}
Project.NameKey getProject() {
return project;
}
void replyTo(MessageInfo info) {
replyAction.onReply(info);
}

View File

@@ -15,6 +15,7 @@
package com.google.gerrit.client.change;
import com.google.gerrit.reviewdb.client.Change;
import com.google.gerrit.reviewdb.client.Project;
import com.google.gwt.user.client.ui.UIObject;
import com.google.gwt.user.client.ui.Widget;
@@ -22,9 +23,13 @@ class IncludedInAction extends RightSidePopdownAction {
private final IncludedInBox includedInBox;
IncludedInAction(
Change.Id changeId, ChangeScreen.Style style, UIObject relativeTo, Widget includedInButton) {
Project.NameKey project,
Change.Id changeId,
ChangeScreen.Style style,
UIObject relativeTo,
Widget includedInButton) {
super(style, relativeTo, includedInButton);
this.includedInBox = new IncludedInBox(changeId);
this.includedInBox = new IncludedInBox(project, changeId);
}
@Override

View File

@@ -17,6 +17,7 @@ package com.google.gerrit.client.change;
import com.google.gerrit.client.changes.ChangeApi;
import com.google.gerrit.client.info.ChangeInfo.IncludedInInfo;
import com.google.gerrit.reviewdb.client.Change;
import com.google.gerrit.reviewdb.client.Project;
import com.google.gwt.core.client.GWT;
import com.google.gwt.core.client.JsArrayString;
import com.google.gwt.dom.client.Document;
@@ -42,6 +43,7 @@ class IncludedInBox extends Composite {
String includedInElement();
}
private final Project.NameKey project;
private final Change.Id changeId;
private boolean loaded;
@@ -50,7 +52,8 @@ class IncludedInBox extends Composite {
@UiField Element branches;
@UiField Element tags;
IncludedInBox(Change.Id changeId) {
IncludedInBox(Project.NameKey project, Change.Id changeId) {
this.project = project;
this.changeId = changeId;
initWidget(uiBinder.createAndBindUi(this));
}
@@ -59,6 +62,7 @@ class IncludedInBox extends Composite {
protected void onLoad() {
if (!loaded) {
ChangeApi.includedIn(
project.get(),
changeId.get(),
new AsyncCallback<IncludedInInfo>() {
@Override

View File

@@ -72,13 +72,13 @@ class Labels extends Grid {
if (user != null) {
final ChangeScreen screen = ChangeScreen.get(event);
final Change.Id changeId = screen.getPatchSetId().getParentKey();
ChangeApi.reviewer(changeId.get(), user)
ChangeApi.reviewer(screen.getProject().get(), changeId.get(), user)
.delete(
new GerritCallback<JavaScriptObject>() {
@Override
public void onSuccess(JavaScriptObject result) {
if (screen.isCurrentView()) {
Gerrit.display(PageLinks.toChange(changeId));
Gerrit.display(PageLinks.toChange(screen.getProject(), changeId));
}
}
});
@@ -91,13 +91,13 @@ class Labels extends Grid {
if (user != null && vote != null) {
final ChangeScreen screen = ChangeScreen.get(event);
final Change.Id changeId = screen.getPatchSetId().getParentKey();
ChangeApi.vote(changeId.get(), user, vote)
ChangeApi.vote(screen.getProject().get(), changeId.get(), user, vote)
.delete(
new GerritCallback<JavaScriptObject>() {
@Override
public void onSuccess(JavaScriptObject result) {
if (screen.isCurrentView()) {
Gerrit.display(PageLinks.toChange(changeId));
Gerrit.display(PageLinks.toChange(screen.getProject(), changeId));
}
}
});

View File

@@ -22,6 +22,7 @@ import com.google.gerrit.client.ui.CommentLinkProcessor;
import com.google.gerrit.client.ui.InlineHyperlink;
import com.google.gerrit.extensions.client.Side;
import com.google.gerrit.reviewdb.client.PatchSet;
import com.google.gerrit.reviewdb.client.Project;
import com.google.gwt.core.client.GWT;
import com.google.gwt.dom.client.Element;
import com.google.gwt.uibinder.client.UiBinder;
@@ -43,7 +44,8 @@ class LineComment extends Composite {
@UiField InlineHyperlink line;
@UiField Element message;
LineComment(CommentLinkProcessor clp, PatchSet.Id defaultPs, CommentInfo info) {
LineComment(
CommentLinkProcessor clp, Project.NameKey project, PatchSet.Id defaultPs, CommentInfo info) {
initWidget(uiBinder.createAndBindUi(this));
PatchSet.Id ps;
@@ -70,7 +72,7 @@ class LineComment extends Composite {
fileLoc.removeFromParent();
fileLoc = null;
line.setTargetHistoryToken(url(ps, info));
line.setTargetHistoryToken(url(project, ps, info));
line.setText(Integer.toString(info.line()));
} else {
@@ -86,8 +88,9 @@ class LineComment extends Composite {
}
}
private static String url(PatchSet.Id ps, CommentInfo info) {
private static String url(Project.NameKey project, PatchSet.Id ps, CommentInfo info) {
return Dispatcher.toPatch(
project,
null,
ps,
info.path(),

View File

@@ -19,24 +19,30 @@ import com.google.gerrit.client.changes.CommentInfo;
import com.google.gerrit.client.diff.CommentRange;
import com.google.gerrit.client.rpc.GerritCallback;
import com.google.gerrit.client.rpc.RestApi;
import com.google.gerrit.common.Nullable;
import com.google.gerrit.common.PageLinks;
import com.google.gerrit.extensions.client.Side;
import com.google.gerrit.reviewdb.client.Change;
import com.google.gerrit.reviewdb.client.PatchSet;
import com.google.gerrit.reviewdb.client.Project;
import com.google.gwt.storage.client.Storage;
import com.google.gwt.user.client.Cookies;
import java.util.ArrayList;
import java.util.Collection;
public class LocalComments {
@Nullable private final Project.NameKey project;
private final Change.Id changeId;
private final PatchSet.Id psId;
private final StorageBackend storage;
private static class InlineComment {
@Nullable final Project.NameKey project;
final PatchSet.Id psId;
final CommentInfo commentInfo;
InlineComment(PatchSet.Id psId, CommentInfo commentInfo) {
InlineComment(@Nullable Project.NameKey project, PatchSet.Id psId, CommentInfo commentInfo) {
this.project = project;
this.psId = psId;
this.commentInfo = commentInfo;
}
@@ -87,13 +93,15 @@ public class LocalComments {
}
}
public LocalComments(Change.Id changeId) {
public LocalComments(@Nullable Project.NameKey project, Change.Id changeId) {
this.project = project;
this.changeId = changeId;
this.psId = null;
this.storage = new StorageBackend();
}
public LocalComments(PatchSet.Id psId) {
public LocalComments(@Nullable Project.NameKey project, PatchSet.Id psId) {
this.project = project;
this.changeId = psId.getParentKey();
this.psId = psId;
this.storage = new StorageBackend();
@@ -120,7 +128,7 @@ public class LocalComments {
}
private String getReplyCommentName() {
return "savedReplyComment-" + changeId.toString();
return "savedReplyComment-" + PageLinks.toChangeId(project, changeId);
}
public static void saveInlineComments() {
@@ -130,6 +138,7 @@ public class LocalComments {
InlineComment input = getInlineComment(cookie);
if (input.commentInfo.id() == null) {
CommentApi.createDraft(
Project.NameKey.asStringOrNull(input.project),
input.psId,
input.commentInfo,
new GerritCallback<CommentInfo>() {
@@ -140,6 +149,7 @@ public class LocalComments {
});
} else {
CommentApi.updateDraft(
Project.NameKey.asStringOrNull(input.project),
input.psId,
input.commentInfo.id(),
input.commentInfo,
@@ -201,8 +211,8 @@ public class LocalComments {
if (key.startsWith("patchReply-") || key.startsWith("patchCommentEdit-")) {
offset = 2;
}
Change.Id changeId = new Change.Id(Integer.parseInt(elements[offset + 0]));
PatchSet.Id psId = new PatchSet.Id(changeId, Integer.parseInt(elements[offset + 1]));
ProjectChangeId id = ProjectChangeId.create(elements[offset + 0]);
PatchSet.Id psId = new PatchSet.Id(id.getChangeId(), Integer.parseInt(elements[offset + 1]));
path = atob(elements[offset + 2]);
side = (Side.PARENT.toString().equals(elements[offset + 3])) ? Side.PARENT : Side.REVISION;
range = null;
@@ -227,7 +237,7 @@ public class LocalComments {
} else if (key.startsWith("patchCommentEdit-")) {
info.id(elements[1]);
}
InlineComment inlineComment = new InlineComment(psId, info);
InlineComment inlineComment = new InlineComment(id.getProject(), psId, info);
return inlineComment;
}
@@ -241,8 +251,9 @@ public class LocalComments {
} else if (comment.inReplyTo() != null) {
result = "patchReply-" + comment.inReplyTo() + "-";
}
result +=
changeId + "-" + psId.getId() + "-" + btoa(comment.path()) + "-" + comment.side() + "-";
result += PageLinks.toChangeId(project, changeId);
result += "-" + psId.getId() + "-" + btoa(comment.path()) + "-" + comment.side() + "-";
if (comment.hasRange()) {
result +=
"R"

View File

@@ -173,14 +173,14 @@ class Message extends Composite {
TreeMap<String, List<CommentInfo>> m = byPath(list);
List<CommentInfo> l = m.remove(Patch.COMMIT_MSG);
if (l != null) {
comments.add(new FileComments(clp, ps, Util.C.commitMessage(), l));
comments.add(new FileComments(clp, history.getProject(), ps, Util.C.commitMessage(), l));
}
l = m.remove(Patch.MERGE_LIST);
if (l != null) {
comments.add(new FileComments(clp, ps, Util.C.mergeList(), l));
comments.add(new FileComments(clp, history.getProject(), ps, Util.C.mergeList(), l));
}
for (Map.Entry<String, List<CommentInfo>> e : m.entrySet()) {
comments.add(new FileComments(clp, ps, e.getKey(), e.getValue()));
comments.add(new FileComments(clp, history.getProject(), ps, e.getKey(), e.getValue()));
}
}

View File

@@ -16,6 +16,7 @@ package com.google.gerrit.client.change;
import com.google.gerrit.client.info.ChangeInfo.EditInfo;
import com.google.gerrit.reviewdb.client.Change;
import com.google.gerrit.reviewdb.client.Project;
import com.google.gwt.user.client.ui.UIObject;
import com.google.gwt.user.client.ui.Widget;
@@ -23,6 +24,7 @@ class PatchSetsAction extends RightSidePopdownAction {
private final PatchSetsBox revisionBox;
PatchSetsAction(
Project.NameKey project,
Change.Id changeId,
String revision,
EditInfo edit,
@@ -30,7 +32,7 @@ class PatchSetsAction extends RightSidePopdownAction {
UIObject relativeTo,
Widget downloadButton) {
super(style, relativeTo, downloadButton);
this.revisionBox = new PatchSetsBox(changeId, revision, edit);
this.revisionBox = new PatchSetsBox(project, changeId, revision, edit);
}
@Override

View File

@@ -29,6 +29,7 @@ import com.google.gerrit.client.ui.FancyFlexTableImpl;
import com.google.gerrit.common.PageLinks;
import com.google.gerrit.extensions.client.ListChangesOption;
import com.google.gerrit.reviewdb.client.Change;
import com.google.gerrit.reviewdb.client.Project;
import com.google.gwt.core.client.GWT;
import com.google.gwt.core.client.JsArray;
import com.google.gwt.dom.client.Element;
@@ -103,6 +104,7 @@ class PatchSetsBox extends Composite {
}
private final Change.Id changeId;
private final Project.NameKey project;
private final String revision;
private final EditInfo edit;
private boolean loaded;
@@ -111,7 +113,8 @@ class PatchSetsBox extends Composite {
@UiField FlexTable table;
@UiField Style style;
PatchSetsBox(Change.Id changeId, String revision, EditInfo edit) {
PatchSetsBox(Project.NameKey project, Change.Id changeId, String revision, EditInfo edit) {
this.project = project;
this.changeId = changeId;
this.revision = revision;
this.edit = edit;
@@ -121,7 +124,7 @@ class PatchSetsBox extends Composite {
@Override
protected void onLoad() {
if (!loaded) {
RestApi call = ChangeApi.detail(changeId.get());
RestApi call = ChangeApi.detail(project.get(), changeId.get());
ChangeList.addOptions(
call, EnumSet.of(ListChangesOption.ALL_COMMITS, ListChangesOption.ALL_REVISIONS));
call.get(
@@ -219,7 +222,7 @@ class PatchSetsBox extends Composite {
}
private String url(RevisionInfo r) {
return PageLinks.toChange(changeId, r.id());
return PageLinks.toChange(project, changeId, r.id());
}
private void closeParent() {

View File

@@ -19,6 +19,7 @@ import com.google.gerrit.client.info.ChangeInfo.RevisionInfo;
import com.google.gerrit.client.rpc.Natives;
import com.google.gerrit.client.rpc.RestApi;
import com.google.gerrit.reviewdb.client.Change;
import com.google.gerrit.reviewdb.client.Project;
import com.google.gwt.core.client.JsArrayString;
import com.google.gwt.user.client.rpc.AsyncCallback;
import com.google.gwtexpui.safehtml.client.HighlightSuggestOracle;
@@ -28,17 +29,19 @@ import java.util.List;
class PathSuggestOracle extends HighlightSuggestOracle {
private final Project.NameKey project;
private final Change.Id changeId;
private final RevisionInfo revision;
PathSuggestOracle(Change.Id changeId, RevisionInfo revision) {
PathSuggestOracle(Project.NameKey project, Change.Id changeId, RevisionInfo revision) {
this.project = project;
this.changeId = changeId;
this.revision = revision;
}
@Override
protected void onRequestSuggestions(Request req, Callback cb) {
RestApi api = ChangeApi.revision(changeId.get(), revision.name()).view("files");
RestApi api = ChangeApi.revision(project.get(), changeId.get(), revision.name()).view("files");
if (req.getQuery() != null) {
api.addParameter("q", req.getQuery() == null ? "" : req.getQuery());
}

View File

@@ -0,0 +1,115 @@
// Copyright (C) 2017 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.change;
import com.google.common.annotations.VisibleForTesting;
import com.google.gerrit.common.Nullable;
import com.google.gerrit.common.PageLinks;
import com.google.gerrit.reviewdb.client.Change;
import com.google.gerrit.reviewdb.client.Project;
import java.util.Objects;
/** Provides logic for parsing a numeric change id and project from a URL. */
public class ProjectChangeId {
/** Parses a {@link ProjectChangeId} from it's string representation. */
public static ProjectChangeId create(String token) {
String mutableToken = token;
// Try parsing /c/project/+/numericChangeId where token is project/+/numericChangeId
int delimiter = mutableToken.indexOf(PageLinks.PROJECT_CHANGE_DELIMITER);
Project.NameKey project = null;
if (delimiter > 0) {
project = new Project.NameKey(token.substring(0, delimiter));
mutableToken =
mutableToken.substring(delimiter + PageLinks.PROJECT_CHANGE_DELIMITER.length());
}
// Try parsing /c/numericChangeId where token is numericChangeId
int s = mutableToken.indexOf('/');
if (s > 0) {
mutableToken = mutableToken.substring(0, s);
}
// Special case: project/+/1233,edit/
s = mutableToken.indexOf(",edit");
if (s > 0) {
mutableToken = mutableToken.substring(0, s);
}
Integer cId = tryParse(mutableToken);
if (cId != null) {
return new ProjectChangeId(project, new Change.Id(cId));
}
throw new IllegalArgumentException(token + " is not a valid change identifier");
}
@Nullable private final Project.NameKey project;
private final Change.Id changeId;
@VisibleForTesting
ProjectChangeId(@Nullable Project.NameKey project, Change.Id changeId) {
this.project = project;
this.changeId = changeId;
}
@Nullable
public Project.NameKey getProject() {
return project;
}
public Change.Id getChangeId() {
return changeId;
}
/**
* Calculate the length of the string representation of the change ID that was parsed from the
* token.
*
* @return the length of the {@link Change.Id} if no project was parsed from the token. The length
* of {@link Project.NameKey} + the delimiter + the length of {@link Change.Id} otherwise.
*/
public int identifierLength() {
if (project == null) {
return String.valueOf(changeId).length();
}
return PageLinks.toChangeId(project, changeId).length();
}
@Override
public boolean equals(Object obj) {
if (obj instanceof ProjectChangeId) {
ProjectChangeId other = (ProjectChangeId) obj;
return Objects.equals(changeId, other.changeId) && Objects.equals(project, other.project);
}
return false;
}
@Override
public int hashCode() {
return Objects.hash(changeId, project);
}
@Override
public String toString() {
return "ProjectChangeId.Result{changeId: " + changeId + ", project: " + project + "}";
}
private static Integer tryParse(String s) {
try {
return Integer.parseInt(s);
} catch (NumberFormatException e) {
return null;
}
}
}

View File

@@ -24,6 +24,7 @@ import com.google.gerrit.client.rpc.GerritCallback;
import com.google.gerrit.client.rpc.Natives;
import com.google.gerrit.common.PageLinks;
import com.google.gerrit.reviewdb.client.Change;
import com.google.gerrit.reviewdb.client.Project;
import com.google.gwt.core.client.JsArrayString;
import com.google.gwt.event.dom.client.ClickEvent;
import com.google.gwt.event.dom.client.ClickHandler;
@@ -33,6 +34,7 @@ import com.google.gwtexpui.safehtml.client.SafeHtmlBuilder;
/** Applies a label with one mouse click. */
class QuickApprove extends Button implements ClickHandler {
private Change.Id changeId;
private Project.NameKey project;
private String revision;
private ReviewInput input;
private ReplyAction replyAction;
@@ -71,6 +73,7 @@ class QuickApprove extends Button implements ClickHandler {
if (qName != null) {
changeId = info.legacyId();
project = info.projectNameKey();
revision = commit;
input = ReviewInput.create();
input.drafts(DraftHandling.PUBLISH_ALL_REVISIONS);
@@ -93,14 +96,14 @@ class QuickApprove extends Button implements ClickHandler {
if (replyAction != null && replyAction.isVisible()) {
replyAction.quickApprove(input);
} else {
ChangeApi.revision(changeId.get(), revision)
ChangeApi.revision(project.get(), changeId.get(), revision)
.view("review")
.post(
input,
new GerritCallback<ReviewInput>() {
@Override
public void onSuccess(ReviewInput result) {
Gerrit.display(PageLinks.toChange(changeId));
Gerrit.display(PageLinks.toChange(project, changeId));
}
});
}

View File

@@ -21,6 +21,7 @@ import com.google.gerrit.client.rpc.GerritCallback;
import com.google.gerrit.client.ui.RebaseDialog;
import com.google.gerrit.common.PageLinks;
import com.google.gerrit.reviewdb.client.Change;
import com.google.gerrit.reviewdb.client.Project;
import com.google.gwt.event.logical.shared.CloseEvent;
import com.google.gwt.user.client.ui.Button;
import com.google.gwt.user.client.ui.PopupPanel;
@@ -28,7 +29,7 @@ import com.google.gwt.user.client.ui.PopupPanel;
class RebaseAction {
static void call(
final Button b,
final String project,
final Project.NameKey project,
final String branch,
final Change.Id id,
final String revision,
@@ -39,6 +40,7 @@ class RebaseAction {
@Override
public void onSend() {
ChangeApi.rebase(
project.get(),
id.get(),
revision,
getBase(),
@@ -47,7 +49,7 @@ class RebaseAction {
public void onSuccess(ChangeInfo result) {
sent = true;
hide();
Gerrit.display(PageLinks.toChange(id));
Gerrit.display(PageLinks.toChange(project, id));
}
@Override

View File

@@ -203,7 +203,7 @@ public class RelatedChanges extends TabPanel {
setForOpenChange(info, revision);
}
ChangeApi.revision(info.legacyId().get(), revision)
ChangeApi.revision(info.project(), info.legacyId().get(), revision)
.view("related")
.get(
new TabCallback<RelatedInfo>(Tab.RELATED_CHANGES, info.project(), revision) {
@@ -224,7 +224,7 @@ public class RelatedChanges extends TabPanel {
new TabChangeListCallback(Tab.CHERRY_PICKS, info.project(), revision));
if (info.currentRevision() != null && info.currentRevision().equals(revision)) {
ChangeApi.change(info.legacyId().get())
ChangeApi.change(info.project(), info.legacyId().get())
.view("submitted_together")
.get(new TabChangeListCallback(Tab.SUBMITTED_TOGETHER, info.project(), revision));
}

View File

@@ -20,6 +20,7 @@ import com.google.gerrit.client.changes.Util;
import com.google.gerrit.client.info.ChangeInfo.CommitInfo;
import com.google.gerrit.common.PageLinks;
import com.google.gerrit.reviewdb.client.Change;
import com.google.gerrit.reviewdb.client.Project;
import com.google.gwt.core.client.GWT;
import com.google.gwt.core.client.JsArray;
import com.google.gwt.core.client.Scheduler;
@@ -332,7 +333,7 @@ class RelatedChangesTab implements IsWidget {
private String url() {
if (info.hasChangeNumber() && info.hasRevisionNumber()) {
return "#" + PageLinks.toChange(info.patchSetId());
return "#" + PageLinks.toChange(new Project.NameKey(info.project()), info.patchSetId());
}
return null;
}

View File

@@ -16,6 +16,7 @@ package com.google.gerrit.client.change;
import com.google.gerrit.client.info.ChangeInfo.RevisionInfo;
import com.google.gerrit.reviewdb.client.Change;
import com.google.gerrit.reviewdb.client.Project;
import com.google.gwt.event.logical.shared.CloseEvent;
import com.google.gwt.event.logical.shared.CloseHandler;
import com.google.gwt.user.client.ui.PopupPanel;
@@ -23,6 +24,7 @@ import com.google.gwt.user.client.ui.Widget;
import com.google.gwtexpui.globalkey.client.GlobalKey;
class RenameFileAction {
private final Project.NameKey project;
private final Change.Id changeId;
private final RevisionInfo revision;
private final ChangeScreen.Style style;
@@ -32,7 +34,12 @@ class RenameFileAction {
private PopupPanel popup;
RenameFileAction(
Change.Id changeId, RevisionInfo revision, ChangeScreen.Style style, Widget renameButton) {
Project.NameKey project,
Change.Id changeId,
RevisionInfo revision,
ChangeScreen.Style style,
Widget renameButton) {
this.project = project;
this.changeId = changeId;
this.revision = revision;
this.style = style;
@@ -46,7 +53,7 @@ class RenameFileAction {
}
if (renameBox == null) {
renameBox = new RenameFileBox(changeId, revision);
renameBox = new RenameFileBox(project, changeId, revision);
}
renameBox.clearPath();

View File

@@ -21,6 +21,7 @@ import com.google.gerrit.client.info.ChangeInfo.RevisionInfo;
import com.google.gerrit.client.ui.RemoteSuggestBox;
import com.google.gerrit.common.PageLinks;
import com.google.gerrit.reviewdb.client.Change;
import com.google.gerrit.reviewdb.client.Project;
import com.google.gwt.core.client.GWT;
import com.google.gwt.event.dom.client.ClickEvent;
import com.google.gwt.event.logical.shared.CloseEvent;
@@ -41,6 +42,7 @@ class RenameFileBox extends Composite {
private static final Binder uiBinder = GWT.create(Binder.class);
private final Project.NameKey project;
private final Change.Id changeId;
@UiField Button rename;
@@ -51,10 +53,11 @@ class RenameFileBox extends Composite {
@UiField NpTextBox newPath;
RenameFileBox(Change.Id changeId, RevisionInfo revision) {
RenameFileBox(Project.NameKey project, Change.Id changeId, RevisionInfo revision) {
this.project = project;
this.changeId = changeId;
path = new RemoteSuggestBox(new PathSuggestOracle(changeId, revision));
path = new RemoteSuggestBox(new PathSuggestOracle(project, changeId, revision));
path.addCloseHandler(
new CloseHandler<RemoteSuggestBox>() {
@Override
@@ -82,13 +85,14 @@ class RenameFileBox extends Composite {
private void rename(String path, String newPath) {
hide();
ChangeEditApi.rename(
project.get(),
changeId.get(),
path,
newPath,
new AsyncCallback<VoidResult>() {
@Override
public void onSuccess(VoidResult result) {
Gerrit.display(PageLinks.toChangeInEditMode(changeId));
Gerrit.display(PageLinks.toChangeInEditMode(project, changeId));
}
@Override

View File

@@ -21,6 +21,7 @@ import com.google.gerrit.client.info.ChangeInfo.MessageInfo;
import com.google.gerrit.client.rpc.NativeMap;
import com.google.gerrit.client.ui.CommentLinkProcessor;
import com.google.gerrit.reviewdb.client.PatchSet;
import com.google.gerrit.reviewdb.client.Project;
import com.google.gwt.core.client.JsArrayString;
import com.google.gwt.event.logical.shared.CloseEvent;
import com.google.gwt.event.logical.shared.CloseHandler;
@@ -31,6 +32,7 @@ import com.google.gwtexpui.globalkey.client.GlobalKey;
class ReplyAction {
private final PatchSet.Id psId;
private final Project.NameKey project;
private final String revision;
private final boolean hasDraftComments;
private final ChangeScreen.Style style;
@@ -53,6 +55,7 @@ class ReplyAction {
Widget replyButton,
Widget quickApproveButton) {
this.psId = new PatchSet.Id(info.legacyId(), info.revisions().get(revision)._number());
this.project = info.projectNameKey();
this.revision = revision;
this.hasDraftComments = hasDraftComments;
this.style = style;
@@ -90,7 +93,7 @@ class ReplyAction {
}
if (replyBox == null) {
replyBox = new ReplyBox(clp, psId, revision, allLabels, permittedLabels);
replyBox = new ReplyBox(clp, project, psId, revision, allLabels, permittedLabels);
allLabels = null;
permittedLabels = null;
}

View File

@@ -35,6 +35,7 @@ import com.google.gerrit.common.PageLinks;
import com.google.gerrit.common.data.LabelValue;
import com.google.gerrit.reviewdb.client.Patch;
import com.google.gerrit.reviewdb.client.PatchSet;
import com.google.gerrit.reviewdb.client.Project;
import com.google.gwt.core.client.GWT;
import com.google.gwt.core.client.JsArray;
import com.google.gwt.core.client.JsArrayString;
@@ -92,6 +93,7 @@ public class ReplyBox extends Composite {
}
private final CommentLinkProcessor clp;
private final Project.NameKey project;
private final PatchSet.Id psId;
private final String revision;
private ReviewInput in = ReviewInput.create();
@@ -109,14 +111,16 @@ public class ReplyBox extends Composite {
ReplyBox(
CommentLinkProcessor clp,
Project.NameKey project,
PatchSet.Id psId,
String revision,
NativeMap<LabelInfo> all,
NativeMap<JsArrayString> permitted) {
this.clp = clp;
this.project = project;
this.psId = psId;
this.revision = revision;
this.lc = new LocalComments(psId.getParentKey());
this.lc = new LocalComments(project, psId.getParentKey());
initWidget(uiBinder.createAndBindUi(this));
List<String> names = new ArrayList<>(permitted.keySet());
@@ -160,7 +164,7 @@ public class ReplyBox extends Composite {
message.setText(lc.getReplyComment());
lc.removeReplyComment();
}
ChangeApi.drafts(psId.getParentKey().get())
ChangeApi.drafts(project.get(), psId.getParentKey().get())
.get(
new AsyncCallback<NativeMap<JsArray<CommentInfo>>>() {
@Override
@@ -218,14 +222,14 @@ public class ReplyBox extends Composite {
// e.g. a draft was modified in another tab since we last looked it up.
in.drafts(DraftHandling.PUBLISH_ALL_REVISIONS);
in.prePost();
ChangeApi.revision(psId.getParentKey().get(), revision)
ChangeApi.revision(project.get(), psId.getParentKey().get(), revision)
.view("review")
.post(
in,
new GerritCallback<ReviewInput>() {
@Override
public void onSuccess(ReviewInput result) {
Gerrit.display(PageLinks.toChange(psId));
Gerrit.display(PageLinks.toChange(project, psId));
}
@Override
@@ -425,12 +429,14 @@ public class ReplyBox extends Composite {
JsArray<CommentInfo> l = m.get(Patch.COMMIT_MSG);
if (l != null) {
comments.add(
new FileComments(clp, psId, Util.C.commitMessage(), copyPath(Patch.COMMIT_MSG, l)));
new FileComments(
clp, project, psId, Util.C.commitMessage(), copyPath(Patch.COMMIT_MSG, l)));
}
l = m.get(Patch.MERGE_LIST);
if (l != null) {
comments.add(
new FileComments(clp, psId, Util.C.commitMessage(), copyPath(Patch.MERGE_LIST, l)));
new FileComments(
clp, project, psId, Util.C.commitMessage(), copyPath(Patch.MERGE_LIST, l)));
}
List<String> paths = new ArrayList<>(m.keySet());
@@ -438,7 +444,7 @@ public class ReplyBox extends Composite {
for (String path : paths) {
if (!Patch.isMagic(path)) {
comments.add(new FileComments(clp, psId, path, copyPath(path, m.get(path))));
comments.add(new FileComments(clp, project, psId, path, copyPath(path, m.get(path))));
}
}

View File

@@ -20,25 +20,29 @@ import com.google.gerrit.client.info.ChangeInfo;
import com.google.gerrit.client.rpc.GerritCallback;
import com.google.gerrit.common.PageLinks;
import com.google.gerrit.reviewdb.client.Change;
import com.google.gerrit.reviewdb.client.Project;
import com.google.gwt.user.client.ui.Button;
class RestoreAction extends ActionMessageBox {
private final Project.NameKey project;
private final Change.Id id;
RestoreAction(Button b, Change.Id id) {
RestoreAction(Button b, Project.NameKey project, Change.Id id) {
super(b);
this.project = project;
this.id = id;
}
@Override
void send(String message) {
ChangeApi.restore(
project.get(),
id.get(),
message,
new GerritCallback<ChangeInfo>() {
@Override
public void onSuccess(ChangeInfo result) {
Gerrit.display(PageLinks.toChange(id));
Gerrit.display(PageLinks.toChange(project, id));
hide();
}
});

View File

@@ -22,12 +22,19 @@ import com.google.gerrit.client.rpc.GerritCallback;
import com.google.gerrit.client.ui.TextAreaActionDialog;
import com.google.gerrit.common.PageLinks;
import com.google.gerrit.reviewdb.client.Change;
import com.google.gerrit.reviewdb.client.Project;
import com.google.gwt.event.logical.shared.CloseEvent;
import com.google.gwt.user.client.ui.Button;
import com.google.gwt.user.client.ui.PopupPanel;
class RevertAction {
static void call(final Button b, Change.Id id, String revision, String commitSubject) {
static void call(
final Button b,
Change.Id id,
Project.NameKey project,
String revision,
String commitSubject) {
// TODO Replace ActionDialog with a nicer looking display.
b.setEnabled(false);
new TextAreaActionDialog(Util.C.revertChangeTitle(), Util.C.headingRevertMessage()) {
@@ -39,6 +46,7 @@ class RevertAction {
@Override
public void onSend() {
ChangeApi.revert(
project.get(),
id.get(),
getMessageText(),
new GerritCallback<ChangeInfo>() {
@@ -46,7 +54,7 @@ class RevertAction {
public void onSuccess(ChangeInfo result) {
sent = true;
hide();
Gerrit.display(PageLinks.toChange(result.legacyId()));
Gerrit.display(PageLinks.toChange(result.projectNameKey(), result.legacyId()));
}
@Override

View File

@@ -22,6 +22,7 @@ import com.google.gerrit.client.rpc.GerritCallback;
import com.google.gerrit.client.rpc.Natives;
import com.google.gerrit.client.ui.AccountSuggestOracle;
import com.google.gerrit.reviewdb.client.Change;
import com.google.gerrit.reviewdb.client.Project;
import com.google.gwt.core.client.JavaScriptObject;
import com.google.gwt.core.client.JsArray;
import com.google.gwtexpui.safehtml.client.HighlightSuggestOracle;
@@ -31,11 +32,12 @@ import java.util.List;
/** REST API based suggestion Oracle for reviewers. */
public class ReviewerSuggestOracle extends HighlightSuggestOracle {
private Project.NameKey project;
private Change.Id changeId;
@Override
protected void onRequestSuggestions(Request req, Callback cb) {
ChangeApi.suggestReviewers(changeId.get(), req.getQuery(), req.getLimit(), false)
ChangeApi.suggestReviewers(project.get(), changeId.get(), req.getQuery(), req.getLimit(), false)
.get(
new GerritCallback<JsArray<SuggestReviewerInfo>>() {
@Override
@@ -60,7 +62,8 @@ public class ReviewerSuggestOracle extends HighlightSuggestOracle {
requestSuggestions(req, cb);
}
public void setChange(Change.Id changeId) {
public void setChange(Project.NameKey project, Change.Id changeId) {
this.project = project;
this.changeId = changeId;
}

View File

@@ -31,6 +31,7 @@ import com.google.gerrit.client.rpc.Natives;
import com.google.gerrit.client.ui.RemoteSuggestBox;
import com.google.gerrit.extensions.client.ReviewerState;
import com.google.gerrit.reviewdb.client.Change;
import com.google.gerrit.reviewdb.client.Project;
import com.google.gwt.core.client.GWT;
import com.google.gwt.core.client.JavaScriptObject;
import com.google.gwt.core.client.JsArray;
@@ -78,6 +79,7 @@ public class Reviewers extends Composite {
private ReviewerSuggestOracle reviewerSuggestOracle;
private Change.Id changeId;
private Project.NameKey project;
Reviewers() {
reviewerSuggestOracle = new ReviewerSuggestOracle();
@@ -118,8 +120,9 @@ public class Reviewers extends Composite {
void set(ChangeInfo info) {
this.changeId = info.legacyId();
this.project = info.projectNameKey();
display(info);
reviewerSuggestOracle.setChange(changeId);
reviewerSuggestOracle.setChange(project, changeId);
addReviewerIcon.setVisible(Gerrit.isSignedIn());
}
@@ -156,7 +159,7 @@ public class Reviewers extends Composite {
return;
}
ChangeApi.reviewers(changeId.get())
ChangeApi.reviewers(project.get(), changeId.get())
.post(
PostInput.create(reviewer, confirmed),
new GerritCallback<PostResult>() {
@@ -208,6 +211,7 @@ public class Reviewers extends Composite {
void updateReviewerList() {
ChangeApi.detail(
project.get(),
changeId.get(),
new GerritCallback<ChangeInfo>() {
@Override

View File

@@ -29,6 +29,7 @@ class SubmitAction {
if (ChangeGlue.onSubmitChange(changeInfo, revisionInfo)) {
final Change.Id changeId = changeInfo.legacyId();
ChangeApi.submit(
changeInfo.project(),
changeId.get(),
revisionInfo.name(),
new GerritCallback<SubmitInfo>() {
@@ -48,7 +49,7 @@ class SubmitAction {
}
private void redisplay() {
Gerrit.display(PageLinks.toChange(changeId));
Gerrit.display(PageLinks.toChange(changeInfo.projectNameKey(), changeId));
}
});
}

View File

@@ -21,6 +21,7 @@ import com.google.gerrit.client.rpc.GerritCallback;
import com.google.gerrit.client.ui.InlineHyperlink;
import com.google.gerrit.common.PageLinks;
import com.google.gerrit.reviewdb.client.PatchSet;
import com.google.gerrit.reviewdb.client.Project;
import com.google.gwt.core.client.GWT;
import com.google.gwt.dom.client.Element;
import com.google.gwt.event.dom.client.ClickEvent;
@@ -45,6 +46,7 @@ class Topic extends Composite {
private static final Binder uiBinder = GWT.create(Binder.class);
private PatchSet.Id psId;
private Project.NameKey project;
private boolean canEdit;
@UiField Element show;
@@ -72,6 +74,7 @@ class Topic extends Composite {
canEdit = info.hasActions() && info.actions().containsKey("topic");
psId = new PatchSet.Id(info.legacyId(), info.revisions().get(revision)._number());
project = info.projectNameKey();
initTopicLink(info);
editIcon.setVisible(canEdit);
@@ -124,12 +127,13 @@ class Topic extends Composite {
@UiHandler("save")
void onSave(@SuppressWarnings("unused") ClickEvent e) {
ChangeApi.topic(
project.get(),
psId.getParentKey().get(),
input.getValue().trim(),
new GerritCallback<String>() {
@Override
public void onSuccess(String result) {
Gerrit.display(PageLinks.toChange(psId));
Gerrit.display(PageLinks.toChange(project, psId));
}
});
onCancel(null);

View File

@@ -23,6 +23,7 @@ import com.google.gerrit.client.info.ChangeInfo.IncludedInInfo;
import com.google.gerrit.client.rpc.CallbackGroup.Callback;
import com.google.gerrit.client.rpc.NativeString;
import com.google.gerrit.client.rpc.RestApi;
import com.google.gerrit.common.Nullable;
import com.google.gerrit.reviewdb.client.Change;
import com.google.gerrit.reviewdb.client.PatchSet;
import com.google.gwt.core.client.JavaScriptObject;
@@ -31,10 +32,11 @@ import com.google.gwt.user.client.rpc.AsyncCallback;
/** A collection of static methods which work on the Gerrit REST API for specific changes. */
public class ChangeApi {
/** Abandon the change, ending its review. */
public static void abandon(int id, String msg, AsyncCallback<ChangeInfo> cb) {
public static void abandon(
@Nullable String project, int id, String msg, AsyncCallback<ChangeInfo> cb) {
MessageInput input = MessageInput.create();
input.message(emptyToNull(msg));
call(id, "abandon").post(input, cb);
call(project, id, "abandon").post(input, cb);
}
/**
@@ -66,22 +68,25 @@ public class ChangeApi {
}
/** Restore a previously abandoned change to be open again. */
public static void restore(int id, String msg, AsyncCallback<ChangeInfo> cb) {
public static void restore(
@Nullable String project, int id, String msg, AsyncCallback<ChangeInfo> cb) {
MessageInput input = MessageInput.create();
input.message(emptyToNull(msg));
call(id, "restore").post(input, cb);
call(project, id, "restore").post(input, cb);
}
/** Create a new change that reverts the delta caused by this change. */
public static void revert(int id, String msg, AsyncCallback<ChangeInfo> cb) {
public static void revert(
@Nullable String project, int id, String msg, AsyncCallback<ChangeInfo> cb) {
MessageInput input = MessageInput.create();
input.message(emptyToNull(msg));
call(id, "revert").post(input, cb);
call(project, id, "revert").post(input, cb);
}
/** Update the topic of a change. */
public static void topic(int id, String topic, AsyncCallback<String> cb) {
RestApi call = call(id, "topic");
public static void topic(
@Nullable String project, int id, String topic, AsyncCallback<String> cb) {
RestApi call = call(project, id, "topic");
topic = emptyToNull(topic);
if (topic != null) {
TopicInput input = TopicInput.create();
@@ -92,177 +97,201 @@ public class ChangeApi {
}
}
public static void detail(int id, AsyncCallback<ChangeInfo> cb) {
detail(id).get(cb);
public static void detail(@Nullable String project, int id, AsyncCallback<ChangeInfo> cb) {
detail(project, id).get(cb);
}
public static RestApi detail(int id) {
return call(id, "detail");
public static RestApi detail(@Nullable String project, int id) {
return call(project, id, "detail");
}
public static RestApi blame(PatchSet.Id id, String path, boolean base) {
return revision(id).view("files").id(path).view("blame").addParameter("base", base);
public static RestApi blame(@Nullable String project, PatchSet.Id id, String path, boolean base) {
return revision(project, id).view("files").id(path).view("blame").addParameter("base", base);
}
public static RestApi actions(int id, String revision) {
public static RestApi actions(@Nullable String project, int id, String revision) {
if (revision == null || revision.equals("")) {
revision = "current";
}
return call(id, revision, "actions");
return call(project, id, revision, "actions");
}
public static void deleteAssignee(int id, AsyncCallback<AccountInfo> cb) {
change(id).view("assignee").delete(cb);
public static void deleteAssignee(
@Nullable String project, int id, AsyncCallback<AccountInfo> cb) {
change(project, id).view("assignee").delete(cb);
}
public static void setAssignee(int id, String user, AsyncCallback<AccountInfo> cb) {
public static void setAssignee(
@Nullable String project, int id, String user, AsyncCallback<AccountInfo> cb) {
AssigneeInput input = AssigneeInput.create();
input.assignee(user);
change(id).view("assignee").put(input, cb);
change(project, id).view("assignee").put(input, cb);
}
public static void markPrivate(int id, AsyncCallback<JavaScriptObject> cb) {
change(id).view("private").post(PrivateInput.create(), cb);
public static void markPrivate(
@Nullable String project, int id, AsyncCallback<JavaScriptObject> cb) {
change(project, id).view("private").post(PrivateInput.create(), cb);
}
public static void unmarkPrivate(int id, AsyncCallback<JavaScriptObject> cb) {
change(id).view("private.delete").post(PrivateInput.create(), cb);
public static void unmarkPrivate(
@Nullable String project, int id, AsyncCallback<JavaScriptObject> cb) {
change(project, id).view("private.delete").post(PrivateInput.create(), cb);
}
public static RestApi comments(int id) {
return call(id, "comments");
public static RestApi comments(@Nullable String project, int id) {
return call(project, id, "comments");
}
public static RestApi drafts(int id) {
return call(id, "drafts");
public static RestApi drafts(@Nullable String project, int id) {
return call(project, id, "drafts");
}
public static void edit(int id, AsyncCallback<EditInfo> cb) {
edit(id).get(cb);
public static void edit(@Nullable String project, int id, AsyncCallback<EditInfo> cb) {
edit(project, id).get(cb);
}
public static void editWithFiles(int id, AsyncCallback<EditInfo> cb) {
edit(id).addParameterTrue("list").get(cb);
public static void editWithFiles(@Nullable String project, int id, AsyncCallback<EditInfo> cb) {
edit(project, id).addParameterTrue("list").get(cb);
}
public static RestApi edit(int id) {
return change(id).view("edit");
public static RestApi edit(@Nullable String project, int id) {
return change(project, id).view("edit");
}
public static RestApi editWithCommands(int id) {
return edit(id).addParameterTrue("download-commands");
public static RestApi editWithCommands(@Nullable String project, int id) {
return edit(project, id).addParameterTrue("download-commands");
}
public static void includedIn(int id, AsyncCallback<IncludedInInfo> cb) {
call(id, "in").get(cb);
public static void includedIn(
@Nullable String project, int id, AsyncCallback<IncludedInInfo> cb) {
call(project, id, "in").get(cb);
}
public static RestApi revision(int id, String revision) {
return change(id).view("revisions").id(revision);
public static RestApi revision(@Nullable String project, int id, String revision) {
return change(project, id).view("revisions").id(revision);
}
public static RestApi revision(PatchSet.Id id) {
public static RestApi revision(@Nullable String project, PatchSet.Id id) {
int cn = id.getParentKey().get();
String revision = RevisionInfoCache.get(id);
if (revision != null) {
return revision(cn, revision);
return revision(project, cn, revision);
}
return change(cn).view("revisions").id(id.get());
return change(project, cn).view("revisions").id(id.get());
}
public static RestApi reviewers(int id) {
return change(id).view("reviewers");
public static RestApi reviewers(@Nullable String project, int id) {
return change(project, id).view("reviewers");
}
public static RestApi suggestReviewers(int id, String q, int n, boolean e) {
RestApi api = change(id).view("suggest_reviewers").addParameter("n", n).addParameter("e", e);
public static RestApi suggestReviewers(
@Nullable String project, int id, String q, int n, boolean e) {
RestApi api =
change(project, id).view("suggest_reviewers").addParameter("n", n).addParameter("e", e);
if (q != null) {
api.addParameter("q", q);
}
return api;
}
public static RestApi vote(int id, int reviewer, String vote) {
return reviewer(id, reviewer).view("votes").id(vote);
public static RestApi vote(@Nullable String project, int id, int reviewer, String vote) {
return reviewer(project, id, reviewer).view("votes").id(vote);
}
public static RestApi reviewer(int id, int reviewer) {
return change(id).view("reviewers").id(reviewer);
public static RestApi reviewer(@Nullable String project, int id, int reviewer) {
return change(project, id).view("reviewers").id(reviewer);
}
public static RestApi reviewer(int id, String reviewer) {
return change(id).view("reviewers").id(reviewer);
public static RestApi reviewer(@Nullable String project, int id, String reviewer) {
return change(project, id).view("reviewers").id(reviewer);
}
public static RestApi hashtags(int changeId) {
return change(changeId).view("hashtags");
public static RestApi hashtags(@Nullable String project, int changeId) {
return change(project, changeId).view("hashtags");
}
public static RestApi hashtag(int changeId, String hashtag) {
return change(changeId).view("hashtags").id(hashtag);
public static RestApi hashtag(@Nullable String project, int changeId, String hashtag) {
return change(project, changeId).view("hashtags").id(hashtag);
}
/** Submit a specific revision of a change. */
public static void cherrypick(
int id, String commit, String destination, String message, AsyncCallback<ChangeInfo> cb) {
String project,
int id,
String commit,
String destination,
String message,
AsyncCallback<ChangeInfo> cb) {
CherryPickInput cherryPickInput = CherryPickInput.create();
cherryPickInput.setMessage(message);
cherryPickInput.setDestination(destination);
call(id, commit, "cherrypick").post(cherryPickInput, cb);
call(project, id, commit, "cherrypick").post(cherryPickInput, cb);
}
/** Edit commit message for specific revision of a change. */
public static void message(
int id, String commit, String message, AsyncCallback<JavaScriptObject> cb) {
@Nullable String project,
int id,
String commit,
String message,
AsyncCallback<JavaScriptObject> cb) {
CherryPickInput input = CherryPickInput.create();
input.setMessage(message);
call(id, commit, "message").post(input, cb);
call(project, id, commit, "message").post(input, cb);
}
/** Submit a specific revision of a change. */
public static void submit(int id, String commit, AsyncCallback<SubmitInfo> cb) {
public static void submit(
@Nullable String project, int id, String commit, AsyncCallback<SubmitInfo> cb) {
JavaScriptObject in = JavaScriptObject.createObject();
call(id, commit, "submit").post(in, cb);
call(project, id, commit, "submit").post(in, cb);
}
/** Publish a specific revision of a draft change. */
public static void publish(int id, String commit, AsyncCallback<JavaScriptObject> cb) {
public static void publish(
@Nullable String project, int id, String commit, AsyncCallback<JavaScriptObject> cb) {
JavaScriptObject in = JavaScriptObject.createObject();
call(id, commit, "publish").post(in, cb);
call(project, id, commit, "publish").post(in, cb);
}
/** Delete a specific draft change. */
public static void deleteChange(int id, AsyncCallback<JavaScriptObject> cb) {
change(id).delete(cb);
public static void deleteChange(
@Nullable String project, int id, AsyncCallback<JavaScriptObject> cb) {
change(project, id).delete(cb);
}
/** Delete a specific draft patch set. */
public static void deleteRevision(int id, String commit, AsyncCallback<JavaScriptObject> cb) {
revision(id, commit).delete(cb);
public static void deleteRevision(
@Nullable String project, int id, String commit, AsyncCallback<JavaScriptObject> cb) {
revision(project, id, commit).delete(cb);
}
/** Delete change edit. */
public static void deleteEdit(int id, AsyncCallback<JavaScriptObject> cb) {
edit(id).delete(cb);
public static void deleteEdit(
@Nullable String project, int id, AsyncCallback<JavaScriptObject> cb) {
edit(project, id).delete(cb);
}
/** Publish change edit. */
public static void publishEdit(int id, AsyncCallback<JavaScriptObject> cb) {
public static void publishEdit(
@Nullable String project, int id, AsyncCallback<JavaScriptObject> cb) {
JavaScriptObject in = JavaScriptObject.createObject();
change(id).view("edit:publish").post(in, cb);
change(project, id).view("edit:publish").post(in, cb);
}
/** Rebase change edit on latest patch set. */
public static void rebaseEdit(int id, AsyncCallback<JavaScriptObject> cb) {
public static void rebaseEdit(
@Nullable String project, int id, AsyncCallback<JavaScriptObject> cb) {
JavaScriptObject in = JavaScriptObject.createObject();
change(id).view("edit:rebase").post(in, cb);
change(project, id).view("edit:rebase").post(in, cb);
}
/** Rebase a revision onto the branch tip or another change. */
public static void rebase(int id, String commit, String base, AsyncCallback<ChangeInfo> cb) {
public static void rebase(
@Nullable String project, int id, String commit, String base, AsyncCallback<ChangeInfo> cb) {
RebaseInput rebaseInput = RebaseInput.create();
rebaseInput.setBase(base);
call(id, commit, "rebase").post(rebaseInput, cb);
call(project, id, commit, "rebase").post(rebaseInput, cb);
}
private static class MessageInput extends JavaScriptObject {
@@ -347,24 +376,28 @@ public class ChangeApi {
protected RebaseInput() {}
}
private static RestApi call(int id, String action) {
return change(id).view(action);
private static RestApi call(@Nullable String project, int id, String action) {
return change(project, id).view(action);
}
private static RestApi call(int id, String commit, String action) {
return change(id).view("revisions").id(commit).view(action);
private static RestApi call(@Nullable String project, int id, String commit, String action) {
return change(project, id).view("revisions").id(commit).view(action);
}
public static RestApi change(int id) {
// TODO Switch to triplet project~branch~id format in URI.
return new RestApi("/changes/").id(String.valueOf(id));
public static RestApi change(@Nullable String project, int id) {
if (project == null) {
return new RestApi("/changes/").id(String.valueOf(id));
} else {
return new RestApi("/changes/").id(project, id);
}
}
public static String emptyToNull(String str) {
return str == null || str.isEmpty() ? null : str;
}
public static void commitWithLinks(int changeId, String revision, Callback<CommitInfo> callback) {
revision(changeId, revision).view("commit").addParameterTrue("links").get(callback);
public static void commitWithLinks(
@Nullable String project, int changeId, String revision, Callback<CommitInfo> callback) {
revision(project, changeId, revision).view("commit").addParameterTrue("links").get(callback);
}
}

View File

@@ -20,81 +20,110 @@ import com.google.gerrit.client.rpc.GerritCallback;
import com.google.gerrit.client.rpc.HttpCallback;
import com.google.gerrit.client.rpc.NativeString;
import com.google.gerrit.client.rpc.RestApi;
import com.google.gerrit.common.Nullable;
import com.google.gerrit.reviewdb.client.Patch;
import com.google.gerrit.reviewdb.client.PatchSet;
import com.google.gerrit.reviewdb.client.Project;
import com.google.gwt.core.client.JavaScriptObject;
import com.google.gwt.user.client.rpc.AsyncCallback;
/** REST API helpers to remotely edit a change. */
public class ChangeEditApi {
/** Get file (or commit message) contents. */
public static void get(PatchSet.Id id, String path, boolean base, HttpCallback<NativeString> cb) {
public static void get(
@Nullable Project.NameKey project,
PatchSet.Id id,
String path,
boolean base,
HttpCallback<NativeString> cb) {
RestApi api;
if (id.get() != 0) {
// Read from a published revision, when change edit doesn't
// exist for the caller, or is not currently active.
api = ChangeApi.revision(id).view("files").id(path).view("content");
api =
ChangeApi.revision(Project.NameKey.asStringOrNull(project), id)
.view("files")
.id(path)
.view("content");
} else if (Patch.COMMIT_MSG.equals(path)) {
api = editMessage(id.getParentKey().get()).addParameter("base", base);
api =
editMessage(Project.NameKey.asStringOrNull(project), id.getParentKey().get())
.addParameter("base", base);
} else {
api = editFile(id.getParentKey().get(), path).addParameter("base", base);
api =
editFile(Project.NameKey.asStringOrNull(project), id.getParentKey().get(), path)
.addParameter("base", base);
}
api.get(cb);
}
/** Get file (or commit message) contents of the edit. */
public static void get(PatchSet.Id id, String path, HttpCallback<NativeString> cb) {
get(id, path, false, cb);
public static void get(
@Nullable Project.NameKey project,
PatchSet.Id id,
String path,
HttpCallback<NativeString> cb) {
get(project, id, path, false, cb);
}
/** Get meta info for change edit. */
public static void getMeta(PatchSet.Id id, String path, AsyncCallback<EditFileInfo> cb) {
public static void getMeta(
@Nullable String project, PatchSet.Id id, String path, AsyncCallback<EditFileInfo> cb) {
if (id.get() != 0) {
throw new IllegalStateException("only supported for edits");
}
editFile(id.getParentKey().get(), path).view("meta").get(cb);
editFile(project, id.getParentKey().get(), path).view("meta").get(cb);
}
/** Put message into a change edit. */
public static void putMessage(int id, String m, GerritCallback<VoidResult> cb) {
editMessage(id).put(m, cb);
public static void putMessage(
@Nullable String project, int id, String m, GerritCallback<VoidResult> cb) {
editMessage(project, id).put(m, cb);
}
/** Put contents into a file or commit message in a change edit. */
public static void put(int id, String path, String content, GerritCallback<VoidResult> cb) {
public static void put(
@Nullable String project,
int id,
String path,
String content,
GerritCallback<VoidResult> cb) {
if (Patch.COMMIT_MSG.equals(path)) {
putMessage(id, content, cb);
putMessage(project, id, content, cb);
} else {
editFile(id, path).put(content, cb);
editFile(project, id, path).put(content, cb);
}
}
/** Delete a file in the pending edit. */
public static void delete(int id, String path, AsyncCallback<VoidResult> cb) {
editFile(id, path).delete(cb);
public static void delete(
@Nullable String project, int id, String path, AsyncCallback<VoidResult> cb) {
editFile(project, id, path).delete(cb);
}
/** Rename a file in the pending edit. */
public static void rename(int id, String path, String newPath, AsyncCallback<VoidResult> cb) {
public static void rename(
@Nullable String project, int id, String path, String newPath, AsyncCallback<VoidResult> cb) {
Input in = Input.create();
in.oldPath(path);
in.newPath(newPath);
ChangeApi.edit(id).post(in, cb);
ChangeApi.edit(project, id).post(in, cb);
}
/** Restore (undo delete/modify) a file in the pending edit. */
public static void restore(int id, String path, AsyncCallback<VoidResult> cb) {
public static void restore(
@Nullable String project, int id, String path, AsyncCallback<VoidResult> cb) {
Input in = Input.create();
in.restorePath(path);
ChangeApi.edit(id).post(in, cb);
ChangeApi.edit(project, id).post(in, cb);
}
private static RestApi editMessage(int id) {
return ChangeApi.change(id).view("edit:message");
private static RestApi editMessage(@Nullable String project, int id) {
return ChangeApi.change(project, id).view("edit:message");
}
private static RestApi editFile(int id, String path) {
return ChangeApi.edit(id).id(path);
private static RestApi editFile(@Nullable String project, int id, String path) {
return ChangeApi.edit(project, id).id(path);
}
private static class Input extends JavaScriptObject {

View File

@@ -140,8 +140,7 @@ public class ChangeTable extends NavigationTable<ChangeInfo> {
@Override
protected void onOpenRow(int row) {
final ChangeInfo c = getRowItem(row);
final Change.Id id = c.legacyId();
Gerrit.display(PageLinks.toChange(id));
Gerrit.display(PageLinks.toChange(c.projectNameKey(), c.legacyId()));
}
private void insertNoneRow(int row) {
@@ -475,7 +474,7 @@ public class ChangeTable extends NavigationTable<ChangeInfo> {
private final class TableChangeLink extends ChangeLink {
private TableChangeLink(String text, ChangeInfo c) {
super(text, c.legacyId());
super(c.projectNameKey(), c.legacyId(), text);
}
@Override

View File

@@ -16,6 +16,7 @@ package com.google.gerrit.client.changes;
import com.google.gerrit.client.rpc.NativeMap;
import com.google.gerrit.client.rpc.RestApi;
import com.google.gerrit.common.Nullable;
import com.google.gerrit.reviewdb.client.PatchSet;
import com.google.gwt.core.client.JavaScriptObject;
import com.google.gwt.core.client.JsArray;
@@ -23,39 +24,53 @@ import com.google.gwt.user.client.rpc.AsyncCallback;
public class CommentApi {
public static void comments(PatchSet.Id id, AsyncCallback<NativeMap<JsArray<CommentInfo>>> cb) {
revision(id, "comments").get(cb);
public static void comments(
@Nullable String project, PatchSet.Id id, AsyncCallback<NativeMap<JsArray<CommentInfo>>> cb) {
revision(project, id, "comments").get(cb);
}
public static void comment(PatchSet.Id id, String commentId, AsyncCallback<CommentInfo> cb) {
revision(id, "comments").id(commentId).get(cb);
public static void comment(
@Nullable String project, PatchSet.Id id, String commentId, AsyncCallback<CommentInfo> cb) {
revision(project, id, "comments").id(commentId).get(cb);
}
public static void drafts(PatchSet.Id id, AsyncCallback<NativeMap<JsArray<CommentInfo>>> cb) {
revision(id, "drafts").get(cb);
public static void drafts(
@Nullable String project, PatchSet.Id id, AsyncCallback<NativeMap<JsArray<CommentInfo>>> cb) {
revision(project, id, "drafts").get(cb);
}
public static void draft(PatchSet.Id id, String draftId, AsyncCallback<CommentInfo> cb) {
revision(id, "drafts").id(draftId).get(cb);
public static void draft(
@Nullable String project, PatchSet.Id id, String draftId, AsyncCallback<CommentInfo> cb) {
revision(project, id, "drafts").id(draftId).get(cb);
}
public static void createDraft(
PatchSet.Id id, CommentInfo content, AsyncCallback<CommentInfo> cb) {
revision(id, "drafts").put(content, cb);
@Nullable String project,
PatchSet.Id id,
CommentInfo content,
AsyncCallback<CommentInfo> cb) {
revision(project, id, "drafts").put(content, cb);
}
public static void updateDraft(
PatchSet.Id id, String draftId, CommentInfo content, AsyncCallback<CommentInfo> cb) {
revision(id, "drafts").id(draftId).put(content, cb);
@Nullable String project,
PatchSet.Id id,
String draftId,
CommentInfo content,
AsyncCallback<CommentInfo> cb) {
revision(project, id, "drafts").id(draftId).put(content, cb);
}
public static void deleteDraft(
PatchSet.Id id, String draftId, AsyncCallback<JavaScriptObject> cb) {
revision(id, "drafts").id(draftId).delete(cb);
@Nullable String project,
PatchSet.Id id,
String draftId,
AsyncCallback<JavaScriptObject> cb) {
revision(project, id, "drafts").id(draftId).delete(cb);
}
private static RestApi revision(PatchSet.Id id, String type) {
return ChangeApi.revision(id).view(type);
private static RestApi revision(@Nullable String project, PatchSet.Id id, String type) {
return ChangeApi.revision(project, id).view(type);
}
private CommentApi() {}

View File

@@ -65,7 +65,7 @@ public class QueryScreen extends PagedSingleListScreen implements ChangeListScre
if (result.length() == 1 && isSingleQuery(query)) {
ChangeInfo c = result.get(0);
Change.Id id = c.legacyId();
Gerrit.display(PageLinks.toChange(id));
Gerrit.display(PageLinks.toChange(c.projectNameKey(), id));
} else {
display(result);
QueryScreen.this.display();

View File

@@ -21,8 +21,10 @@ import com.google.gerrit.client.patches.SkippedLine;
import com.google.gerrit.client.rpc.CallbackGroup;
import com.google.gerrit.client.rpc.Natives;
import com.google.gerrit.client.ui.CommentLinkProcessor;
import com.google.gerrit.common.Nullable;
import com.google.gerrit.extensions.client.Side;
import com.google.gerrit.reviewdb.client.PatchSet;
import com.google.gerrit.reviewdb.client.Project;
import com.google.gwt.core.client.JsArray;
import java.util.ArrayList;
import java.util.Collection;
@@ -39,6 +41,7 @@ import net.codemirror.lib.TextMarker.FromTo;
/** Tracks comment widgets for {@link DiffScreen}. */
abstract class CommentManager {
@Nullable private final Project.NameKey project;
private final DiffObject base;
private final PatchSet.Id revision;
private final String path;
@@ -54,12 +57,14 @@ abstract class CommentManager {
CommentManager(
DiffScreen host,
@Nullable Project.NameKey project,
DiffObject base,
PatchSet.Id revision,
String path,
CommentLinkProcessor clp,
boolean open) {
this.host = host;
this.project = project;
this.base = base;
this.revision = revision;
this.path = path;
@@ -232,7 +237,12 @@ abstract class CommentManager {
CommentGroup group = group(side, cmLinePlusOne);
DraftBox box =
new DraftBox(
group, getCommentLinkProcessor(), getPatchSetIdFromSide(side), info, isExpandAll());
group,
getCommentLinkProcessor(),
project,
getPatchSetIdFromSide(side),
info,
isExpandAll());
if (info.inReplyTo() != null) {
PublishedBox r = getPublished().get(info.inReplyTo());
@@ -350,6 +360,7 @@ abstract class CommentManager {
new PublishedBox(
group,
getCommentLinkProcessor(),
project,
getPatchSetIdFromSide(side),
info,
side,

View File

@@ -21,8 +21,10 @@ import com.google.gerrit.client.changes.CommentInfo;
import com.google.gerrit.client.rpc.CallbackGroup;
import com.google.gerrit.client.rpc.NativeMap;
import com.google.gerrit.client.rpc.Natives;
import com.google.gerrit.common.Nullable;
import com.google.gerrit.extensions.client.Side;
import com.google.gerrit.reviewdb.client.PatchSet;
import com.google.gerrit.reviewdb.client.Project;
import com.google.gwt.core.client.JsArray;
import com.google.gwt.user.client.rpc.AsyncCallback;
import java.util.Collections;
@@ -30,6 +32,7 @@ import java.util.Comparator;
/** Collection of published and draft comments loaded from the server. */
class CommentsCollections {
@Nullable private final Project.NameKey project;
private final String path;
private final DiffObject base;
private final PatchSet.Id revision;
@@ -40,7 +43,9 @@ class CommentsCollections {
JsArray<CommentInfo> draftsBase;
JsArray<CommentInfo> draftsRevision;
CommentsCollections(DiffObject base, PatchSet.Id revision, String path) {
CommentsCollections(
@Nullable Project.NameKey project, DiffObject base, PatchSet.Id revision, String path) {
this.project = project;
this.path = path;
this.base = base;
this.revision = revision;
@@ -48,15 +53,19 @@ class CommentsCollections {
void load(CallbackGroup group) {
if (base.isPatchSet()) {
CommentApi.comments(base.asPatchSetId(), group.add(publishedBase()));
CommentApi.comments(
Project.NameKey.asStringOrNull(project), base.asPatchSetId(), group.add(publishedBase()));
}
CommentApi.comments(revision, group.add(publishedRevision()));
CommentApi.comments(
Project.NameKey.asStringOrNull(project), revision, group.add(publishedRevision()));
if (Gerrit.isSignedIn()) {
if (base.isPatchSet()) {
CommentApi.drafts(base.asPatchSetId(), group.add(draftsBase()));
CommentApi.drafts(
Project.NameKey.asStringOrNull(project), base.asPatchSetId(), group.add(draftsBase()));
}
CommentApi.drafts(revision, group.add(draftsRevision()));
CommentApi.drafts(
Project.NameKey.asStringOrNull(project), revision, group.add(draftsRevision()));
}
}

View File

@@ -21,14 +21,19 @@ import com.google.gerrit.client.info.ChangeInfo.RevisionInfo;
import com.google.gerrit.client.info.FileInfo;
import com.google.gerrit.client.rpc.NativeMap;
import com.google.gerrit.client.rpc.RestApi;
import com.google.gerrit.common.Nullable;
import com.google.gerrit.extensions.client.DiffPreferencesInfo;
import com.google.gerrit.reviewdb.client.PatchSet;
import com.google.gwt.user.client.rpc.AsyncCallback;
public class DiffApi {
public static void list(
int id, String revision, RevisionInfo base, AsyncCallback<NativeMap<FileInfo>> cb) {
RestApi api = ChangeApi.revision(id, revision).view("files");
@Nullable String project,
int id,
String revision,
RevisionInfo base,
AsyncCallback<NativeMap<FileInfo>> cb) {
RestApi api = ChangeApi.revision(project, id, revision).view("files");
if (base != null) {
if (base._number() < 0) {
api.addParameter("parent", -base._number());
@@ -39,8 +44,12 @@ public class DiffApi {
api.get(NativeMap.copyKeysIntoChildren("path", cb));
}
public static void list(PatchSet.Id id, PatchSet.Id base, AsyncCallback<NativeMap<FileInfo>> cb) {
RestApi api = ChangeApi.revision(id).view("files");
public static void list(
@Nullable String project,
PatchSet.Id id,
PatchSet.Id base,
AsyncCallback<NativeMap<FileInfo>> cb) {
RestApi api = ChangeApi.revision(project, id).view("files");
if (base != null) {
if (base.get() < 0) {
api.addParameter("parent", -base.get());
@@ -51,8 +60,8 @@ public class DiffApi {
api.get(NativeMap.copyKeysIntoChildren("path", cb));
}
public static DiffApi diff(PatchSet.Id id, String path) {
return new DiffApi(ChangeApi.revision(id).view("files").id(path).view("diff"));
public static DiffApi diff(@Nullable String project, PatchSet.Id id, String path) {
return new DiffApi(ChangeApi.revision(project, id).view("files").id(path).view("diff"));
}
private final RestApi call;

View File

@@ -39,12 +39,14 @@ import com.google.gerrit.client.rpc.GerritCallback;
import com.google.gerrit.client.rpc.RestApi;
import com.google.gerrit.client.rpc.ScreenLoadCallback;
import com.google.gerrit.client.ui.Screen;
import com.google.gerrit.common.Nullable;
import com.google.gerrit.common.PageLinks;
import com.google.gerrit.extensions.client.GeneralPreferencesInfo.DiffView;
import com.google.gerrit.extensions.client.ListChangesOption;
import com.google.gerrit.reviewdb.client.Change;
import com.google.gerrit.reviewdb.client.Patch;
import com.google.gerrit.reviewdb.client.PatchSet;
import com.google.gerrit.reviewdb.client.Project;
import com.google.gwt.core.client.JsArray;
import com.google.gwt.core.client.Scheduler;
import com.google.gwt.core.client.Scheduler.RepeatingCommand;
@@ -94,6 +96,7 @@ abstract class DiffScreen extends Screen {
}
}
@Nullable private Project.NameKey project;
private final Change.Id changeId;
final DiffObject base;
final PatchSet.Id revision;
@@ -122,12 +125,14 @@ abstract class DiffScreen extends Screen {
Header header;
DiffScreen(
@Nullable Project.NameKey project,
DiffObject base,
DiffObject revision,
String path,
DisplaySide startSide,
int startLine,
DiffView diffScreenType) {
this.project = project;
this.base = base;
this.revision = revision.asPatchSetId();
this.changeId = revision.asPatchSetId().getParentKey();
@@ -138,7 +143,7 @@ abstract class DiffScreen extends Screen {
prefs = DiffPreferences.create(Gerrit.getDiffPreferences());
handlers = new ArrayList<>(6);
keysNavigation = new KeyCommandSet(Gerrit.C.sectionNavigation());
header = new Header(keysNavigation, base, revision, path, diffScreenType, prefs);
header = new Header(keysNavigation, project, base, revision, path, diffScreenType, prefs);
skipManager = new SkipManager(this);
}
@@ -171,7 +176,7 @@ abstract class DiffScreen extends Screen {
public void onFailure(Throwable caught) {}
}));
DiffApi.diff(revision, path)
DiffApi.diff(Project.NameKey.asStringOrNull(project), revision, path)
.base(base.asPatchSetId())
.wholeFile()
.intraline(prefs.intralineDifference())
@@ -200,6 +205,7 @@ abstract class DiffScreen extends Screen {
if (Gerrit.isSignedIn()) {
ChangeApi.edit(
Project.NameKey.asStringOrNull(project),
changeId.get(),
group2.add(
new AsyncCallback<EditInfo>() {
@@ -213,12 +219,12 @@ abstract class DiffScreen extends Screen {
}));
}
final CommentsCollections comments = new CommentsCollections(base, revision, path);
final CommentsCollections comments = new CommentsCollections(project, base, revision, path);
comments.load(group2);
countParents(group2);
RestApi call = ChangeApi.detail(changeId.get());
RestApi call = ChangeApi.detail(Project.NameKey.asStringOrNull(project), changeId.get());
ChangeList.addOptions(call, EnumSet.of(ListChangesOption.ALL_REVISIONS));
call.get(
group2.add(
@@ -226,6 +232,7 @@ abstract class DiffScreen extends Screen {
@Override
public void onSuccess(ChangeInfo info) {
changeStatus = info.status();
project = info.projectNameKey();
info.revisions().copyKeysIntoChildren("name");
if (edit != null) {
edit.setName(edit.commit().commit());
@@ -259,7 +266,7 @@ abstract class DiffScreen extends Screen {
}
private void countParents(CallbackGroup cbg) {
ChangeApi.revision(changeId.get(), revision.getId())
ChangeApi.revision(Project.NameKey.asStringOrNull(project), changeId.get(), revision.getId())
.view("commit")
.get(
cbg.add(
@@ -443,7 +450,7 @@ abstract class DiffScreen extends Screen {
public void registerKeys() {
super.registerKeys();
keysNavigation.add(new UpToChangeCommand(revision, 0, 'u'));
keysNavigation.add(new UpToChangeCommand(project, revision, 0, 'u'));
keysNavigation.add(
new NoOpKeyCommand(0, 'j', PatchUtil.C.lineNext()),
new NoOpKeyCommand(0, 'k', PatchUtil.C.linePrev()));
@@ -513,6 +520,11 @@ abstract class DiffScreen extends Screen {
}
}
@Nullable
public Project.NameKey getProject() {
return project;
}
void registerHandlers() {
removeKeyHandlerRegistrations();
handlers.add(GlobalKey.add(this, keysAction));
@@ -632,7 +644,7 @@ abstract class DiffScreen extends Screen {
if (Patch.COMMIT_MSG.equals(path)) {
line = adjustCommitMessageLine(line);
}
String token = Dispatcher.toEditScreen(revision, path, line);
String token = Dispatcher.toEditScreen(project, revision, path, line);
if (!Gerrit.isSignedIn()) {
Gerrit.doSignIn(token);
} else {
@@ -712,8 +724,9 @@ abstract class DiffScreen extends Screen {
public void onSuccess(Void result) {
String rev = String.valueOf(revision.get());
Gerrit.display(
PageLinks.toChange(changeId, base.asString(), rev),
new ChangeScreen(changeId, base, rev, openReplyBox, FileTable.Mode.REVIEW));
PageLinks.toChange(project, changeId, base.asString(), rev),
new ChangeScreen(
project, changeId, base, rev, openReplyBox, FileTable.Mode.REVIEW));
}
});
};
@@ -808,7 +821,7 @@ abstract class DiffScreen extends Screen {
void prefetchNextFile() {
String nextPath = header.getNextPath();
if (nextPath != null) {
DiffApi.diff(revision, nextPath)
DiffApi.diff(Project.NameKey.asStringOrNull(project), revision, nextPath)
.base(base.asPatchSetId())
.wholeFile()
.intraline(prefs.intralineDifference())
@@ -831,7 +844,7 @@ abstract class DiffScreen extends Screen {
void reloadDiffInfo() {
int id = ++reloadVersionId;
DiffApi.diff(revision, path)
DiffApi.diff(Project.NameKey.asStringOrNull(project), revision, path)
.base(base.asPatchSetId())
.wholeFile()
.intraline(prefs.intralineDifference())

View File

@@ -73,10 +73,20 @@ abstract class DiffTable extends Composite {
DiffTable(DiffScreen parent, DiffObject base, DiffObject revision, String path) {
patchSetSelectBoxA =
new PatchSetSelectBox(
parent, DisplaySide.A, revision.asPatchSetId().getParentKey(), base, path);
parent,
DisplaySide.A,
parent.getProject(),
revision.asPatchSetId().getParentKey(),
base,
path);
patchSetSelectBoxB =
new PatchSetSelectBox(
parent, DisplaySide.B, revision.asPatchSetId().getParentKey(), revision, path);
parent,
DisplaySide.B,
parent.getProject(),
revision.asPatchSetId().getParentKey(),
revision,
path);
PatchSetSelectBox.link(patchSetSelectBoxA, patchSetSelectBoxB);
this.scrollbar = new Scrollbar(this);

View File

@@ -22,7 +22,9 @@ import com.google.gerrit.client.rpc.CallbackGroup;
import com.google.gerrit.client.rpc.GerritCallback;
import com.google.gerrit.client.rpc.RestApi;
import com.google.gerrit.client.ui.CommentLinkProcessor;
import com.google.gerrit.common.Nullable;
import com.google.gerrit.reviewdb.client.PatchSet;
import com.google.gerrit.reviewdb.client.Project;
import com.google.gwt.core.client.GWT;
import com.google.gwt.core.client.JavaScriptObject;
import com.google.gwt.core.client.Scheduler;
@@ -63,6 +65,7 @@ class DraftBox extends CommentBox {
private final CommentLinkProcessor linkProcessor;
private final PatchSet.Id psId;
@Nullable private final Project.NameKey project;
private final boolean expandAll;
private CommentInfo comment;
private PublishedBox replyToBox;
@@ -90,6 +93,7 @@ class DraftBox extends CommentBox {
DraftBox(
CommentGroup group,
CommentLinkProcessor clp,
@Nullable Project.NameKey pj,
PatchSet.Id id,
CommentInfo info,
boolean expandAllComments) {
@@ -97,6 +101,7 @@ class DraftBox extends CommentBox {
linkProcessor = clp;
psId = id;
project = pj;
expandAll = expandAllComments;
initWidget(uiBinder.createAndBindUi(this));
@@ -295,7 +300,7 @@ class DraftBox extends CommentBox {
enableEdit(false);
pendingGroup = group;
final LocalComments lc = new LocalComments(psId);
final LocalComments lc = new LocalComments(project, psId);
GerritCallback<CommentInfo> cb =
new GerritCallback<CommentInfo>() {
@Override
@@ -323,9 +328,10 @@ class DraftBox extends CommentBox {
}
};
if (input.id() == null) {
CommentApi.createDraft(psId, input, group.add(cb));
CommentApi.createDraft(Project.NameKey.asStringOrNull(project), psId, input, group.add(cb));
} else {
CommentApi.updateDraft(psId, input.id(), input, group.add(cb));
CommentApi.updateDraft(
Project.NameKey.asStringOrNull(project), psId, input.id(), input, group.add(cb));
}
CodeMirror cm = getCm();
cm.vim().handleKey("<Esc>");
@@ -364,6 +370,7 @@ class DraftBox extends CommentBox {
setEdit(false);
pendingGroup = new CallbackGroup();
CommentApi.deleteDraft(
Project.NameKey.asStringOrNull(project),
psId,
comment.id(),
pendingGroup.addFinal(

View File

@@ -32,11 +32,13 @@ import com.google.gerrit.client.rpc.NativeMap;
import com.google.gerrit.client.rpc.Natives;
import com.google.gerrit.client.rpc.RestApi;
import com.google.gerrit.client.ui.InlineHyperlink;
import com.google.gerrit.common.Nullable;
import com.google.gerrit.common.PageLinks;
import com.google.gerrit.extensions.client.GeneralPreferencesInfo.DiffView;
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.gwt.core.client.GWT;
import com.google.gwt.core.client.JsArray;
import com.google.gwt.core.client.JsArrayString;
@@ -90,6 +92,7 @@ public class Header extends Composite {
@UiField Image preferences;
private final KeyCommandSet keys;
@Nullable private final Project.NameKey projectKey;
private final DiffObject base;
private final PatchSet.Id patchSetId;
private final String path;
@@ -104,6 +107,7 @@ public class Header extends Composite {
Header(
KeyCommandSet keys,
@Nullable Project.NameKey project,
DiffObject base,
DiffObject patchSetId,
String path,
@@ -111,6 +115,7 @@ public class Header extends Composite {
DiffPreferences prefs) {
initWidget(uiBinder.createAndBindUi(this));
this.keys = keys;
this.projectKey = project;
this.base = base;
this.patchSetId = patchSetId.asPatchSetId();
this.path = path;
@@ -123,6 +128,7 @@ public class Header extends Composite {
SafeHtml.setInnerHTML(filePath, formatPath(path));
up.setTargetHistoryToken(
PageLinks.toChange(
project,
patchSetId.asPatchSetId().getParentKey(),
base.asString(),
patchSetId.asPatchSetId().getId()));
@@ -158,6 +164,7 @@ public class Header extends Composite {
@Override
protected void onLoad() {
DiffApi.list(
Project.NameKey.asStringOrNull(projectKey),
patchSetId,
base.asPatchSetId(),
new GerritCallback<NativeMap<FileInfo>>() {
@@ -172,7 +179,7 @@ public class Header extends Composite {
});
if (Gerrit.isSignedIn()) {
ChangeApi.revision(patchSetId)
ChangeApi.revision(Project.NameKey.asStringOrNull(projectKey), patchSetId)
.view("files")
.addParameterTrue("reviewed")
.get(
@@ -242,7 +249,10 @@ public class Header extends Composite {
}
private RestApi reviewed() {
return ChangeApi.revision(patchSetId).view("files").id(path).view("reviewed");
return ChangeApi.revision(Project.NameKey.asStringOrNull(projectKey), patchSetId)
.view("files")
.id(path)
.view("reviewed");
}
@UiHandler("preferences")
@@ -252,8 +262,8 @@ public class Header extends Composite {
private String url(FileInfo info) {
return diffScreenType == DiffView.UNIFIED_DIFF
? Dispatcher.toUnified(base, patchSetId, info.path())
: Dispatcher.toSideBySide(base, patchSetId, info.path());
? Dispatcher.toUnified(projectKey, base, patchSetId, info.path())
: Dispatcher.toSideBySide(projectKey, base, patchSetId, info.path());
}
private KeyCommand setupNav(InlineHyperlink link, char key, String help, FileInfo info) {
@@ -279,7 +289,7 @@ public class Header extends Composite {
return k;
}
link.getElement().getStyle().setVisibility(Visibility.HIDDEN);
keys.add(new UpToChangeCommand(patchSetId, 0, key));
keys.add(new UpToChangeCommand(projectKey, patchSetId, 0, key));
return null;
}

View File

@@ -26,9 +26,11 @@ import com.google.gerrit.client.patches.PatchUtil;
import com.google.gerrit.client.rpc.GerritCallback;
import com.google.gerrit.client.rpc.Natives;
import com.google.gerrit.client.ui.InlineHyperlink;
import com.google.gerrit.common.Nullable;
import com.google.gerrit.reviewdb.client.Change;
import com.google.gerrit.reviewdb.client.Patch;
import com.google.gerrit.reviewdb.client.PatchSet;
import com.google.gerrit.reviewdb.client.Project;
import com.google.gwt.core.client.GWT;
import com.google.gwt.core.client.JsArray;
import com.google.gwt.event.dom.client.ClickEvent;
@@ -61,17 +63,24 @@ class PatchSetSelectBox extends Composite {
@UiField HTMLPanel linkPanel;
@UiField BoxStyle style;
@Nullable private final Project.NameKey project;
private final Change.Id changeId;
private DiffScreen parent;
private DisplaySide side;
private boolean sideA;
private String path;
private Change.Id changeId;
private PatchSet.Id revision;
private DiffObject idActive;
private PatchSetSelectBox other;
PatchSetSelectBox(
DiffScreen parent, DisplaySide side, Change.Id changeId, DiffObject diffObject, String path) {
DiffScreen parent,
DisplaySide side,
@Nullable Project.NameKey project,
Change.Id changeId,
DiffObject diffObject,
String path) {
initWidget(uiBinder.createAndBindUi(this));
icon.setTitle(PatchUtil.C.addFileCommentToolTip());
icon.addStyleName(Gerrit.RESOURCES.css().link());
@@ -79,6 +88,7 @@ class PatchSetSelectBox extends Composite {
this.parent = parent;
this.side = side;
this.sideA = side == DisplaySide.A;
this.project = project;
this.changeId = changeId;
this.revision = diffObject.asPatchSetId();
this.idActive = diffObject;
@@ -157,7 +167,7 @@ class PatchSetSelectBox extends Composite {
if (cm.extras().getBlameInfo() != null) {
cm.extras().toggleAnnotation();
} else {
ChangeApi.blame(rev, path, isBase)
ChangeApi.blame(Project.NameKey.asStringOrNull(project), rev, path, isBase)
.get(
new GerritCallback<JsArray<BlameInfo>>() {
@@ -179,7 +189,7 @@ class PatchSetSelectBox extends Composite {
Anchor anchor =
new Anchor(
new ImageResourceRenderer().render(Gerrit.RESOURCES.edit()),
"#" + Dispatcher.toEditScreen(id, path));
"#" + Dispatcher.toEditScreen(project, id, path));
anchor.setTitle(PatchUtil.C.edit());
return anchor;
}
@@ -206,8 +216,8 @@ class PatchSetSelectBox extends Composite {
return new InlineHyperlink(
label,
parent.isSideBySide()
? Dispatcher.toSideBySide(diffBase, revision.asPatchSetId(), path)
: Dispatcher.toUnified(diffBase, revision.asPatchSetId(), path));
? Dispatcher.toSideBySide(project, diffBase, revision.asPatchSetId(), path)
: Dispatcher.toUnified(project, diffBase, revision.asPatchSetId(), path));
}
private Anchor createDownloadLink() {

View File

@@ -26,7 +26,9 @@ import com.google.gerrit.client.changes.Util;
import com.google.gerrit.client.patches.PatchUtil;
import com.google.gerrit.client.rpc.GerritCallback;
import com.google.gerrit.client.ui.CommentLinkProcessor;
import com.google.gerrit.common.Nullable;
import com.google.gerrit.reviewdb.client.PatchSet;
import com.google.gerrit.reviewdb.client.Project;
import com.google.gwt.core.client.GWT;
import com.google.gwt.dom.client.Element;
import com.google.gwt.event.dom.client.ClickEvent;
@@ -52,6 +54,7 @@ class PublishedBox extends CommentBox {
}
private final PatchSet.Id psId;
@Nullable private final Project.NameKey project;
private final CommentInfo comment;
private final DisplaySide displaySide;
private DraftBox replyBox;
@@ -73,6 +76,7 @@ class PublishedBox extends CommentBox {
PublishedBox(
CommentGroup group,
CommentLinkProcessor clp,
@Nullable Project.NameKey project,
PatchSet.Id psId,
CommentInfo info,
DisplaySide displaySide,
@@ -80,6 +84,7 @@ class PublishedBox extends CommentBox {
super(group, info.range());
this.psId = psId;
this.project = project;
this.comment = info;
this.displaySide = displaySide;
@@ -194,6 +199,7 @@ class PublishedBox extends CommentBox {
CommentInfo input = CommentInfo.createReply(comment);
input.message(PatchUtil.C.cannedReplyDone());
CommentApi.createDraft(
Project.NameKey.asStringOrNull(project),
psId,
input,
new GerritCallback<CommentInfo>() {
@@ -213,7 +219,7 @@ class PublishedBox extends CommentBox {
@UiHandler("fix")
void onFix(ClickEvent e) {
e.stopPropagation();
String t = Dispatcher.toEditScreen(psId, comment.path(), comment.line());
String t = Dispatcher.toEditScreen(project, psId, comment.path(), comment.line());
if (!Gerrit.isSignedIn()) {
Gerrit.doSignIn(t);
} else {

View File

@@ -24,8 +24,10 @@ import com.google.gerrit.client.patches.PatchUtil;
import com.google.gerrit.client.projects.ConfigInfoCache;
import com.google.gerrit.client.rpc.ScreenLoadCallback;
import com.google.gerrit.client.ui.InlineHyperlink;
import com.google.gerrit.common.Nullable;
import com.google.gerrit.extensions.client.GeneralPreferencesInfo.DiffView;
import com.google.gerrit.reviewdb.client.Patch;
import com.google.gerrit.reviewdb.client.Project;
import com.google.gwt.core.client.GWT;
import com.google.gwt.core.client.Scheduler;
import com.google.gwt.core.client.Scheduler.ScheduledCommand;
@@ -68,8 +70,13 @@ public class SideBySide extends DiffScreen {
private SideBySideCommentManager commentManager;
public SideBySide(
DiffObject base, DiffObject revision, String path, DisplaySide startSide, int startLine) {
super(base, revision, path, startSide, startLine, DiffView.SIDE_BY_SIDE);
@Nullable Project.NameKey project,
DiffObject base,
DiffObject revision,
String path,
DisplaySide startSide,
int startLine) {
super(project, base, revision, path, startSide, startLine, DiffView.SIDE_BY_SIDE);
diffTable = new SideBySideTable(this, base, revision, path);
add(uiBinder.createAndBindUi(this));
@@ -85,6 +92,7 @@ public class SideBySide extends DiffScreen {
commentManager =
new SideBySideCommentManager(
SideBySide.this,
getProject(),
base,
revision,
path,
@@ -231,7 +239,8 @@ public class SideBySide extends DiffScreen {
private List<InlineHyperlink> getUnifiedDiffLink() {
InlineHyperlink toUnifiedDiffLink = new InlineHyperlink();
toUnifiedDiffLink.setHTML(new ImageResourceRenderer().render(Gerrit.RESOURCES.unifiedDiff()));
toUnifiedDiffLink.setTargetHistoryToken(Dispatcher.toUnified(base, revision, path));
toUnifiedDiffLink.setTargetHistoryToken(
Dispatcher.toUnified(getProject(), base, revision, path));
toUnifiedDiffLink.setTitle(PatchUtil.C.unifiedDiff());
return Collections.singletonList(toUnifiedDiffLink);
}

View File

@@ -18,7 +18,9 @@ import com.google.gerrit.client.DiffObject;
import com.google.gerrit.client.Gerrit;
import com.google.gerrit.client.changes.CommentInfo;
import com.google.gerrit.client.ui.CommentLinkProcessor;
import com.google.gerrit.common.Nullable;
import com.google.gerrit.reviewdb.client.PatchSet;
import com.google.gerrit.reviewdb.client.Project;
import java.util.Collection;
import java.util.Map;
import java.util.SortedMap;
@@ -29,12 +31,13 @@ import net.codemirror.lib.TextMarker.FromTo;
class SideBySideCommentManager extends CommentManager {
SideBySideCommentManager(
SideBySide host,
@Nullable Project.NameKey project,
DiffObject base,
PatchSet.Id revision,
String path,
CommentLinkProcessor clp,
boolean open) {
super(host, base, revision, path, clp, open);
super(host, project, base, revision, path, clp, open);
}
@Override

View File

@@ -24,8 +24,10 @@ import com.google.gerrit.client.patches.PatchUtil;
import com.google.gerrit.client.projects.ConfigInfoCache;
import com.google.gerrit.client.rpc.ScreenLoadCallback;
import com.google.gerrit.client.ui.InlineHyperlink;
import com.google.gerrit.common.Nullable;
import com.google.gerrit.extensions.client.GeneralPreferencesInfo.DiffView;
import com.google.gerrit.reviewdb.client.Patch;
import com.google.gerrit.reviewdb.client.Project;
import com.google.gwt.core.client.GWT;
import com.google.gwt.core.client.JavaScriptObject;
import com.google.gwt.core.client.JsArrayString;
@@ -67,8 +69,13 @@ public class Unified extends DiffScreen {
private boolean autoHideDiffTableHeader;
public Unified(
DiffObject base, DiffObject revision, String path, DisplaySide startSide, int startLine) {
super(base, revision, path, startSide, startLine, DiffView.UNIFIED_DIFF);
@Nullable Project.NameKey project,
DiffObject base,
DiffObject revision,
String path,
DisplaySide startSide,
int startLine) {
super(project, base, revision, path, startSide, startLine, DiffView.UNIFIED_DIFF);
diffTable = new UnifiedTable(this, base, revision, path);
add(uiBinder.createAndBindUi(this));
@@ -84,6 +91,7 @@ public class Unified extends DiffScreen {
commentManager =
new UnifiedCommentManager(
Unified.this,
getProject(),
base,
revision,
path,
@@ -202,7 +210,8 @@ public class Unified extends DiffScreen {
InlineHyperlink toSideBySideDiffLink = new InlineHyperlink();
toSideBySideDiffLink.setHTML(
new ImageResourceRenderer().render(Gerrit.RESOURCES.sideBySideDiff()));
toSideBySideDiffLink.setTargetHistoryToken(Dispatcher.toSideBySide(base, revision, path));
toSideBySideDiffLink.setTargetHistoryToken(
Dispatcher.toSideBySide(getProject(), base, revision, path));
toSideBySideDiffLink.setTitle(PatchUtil.C.sideBySideDiff());
return Collections.singletonList(toSideBySideDiffLink);
}

View File

@@ -21,7 +21,9 @@ import com.google.gerrit.client.diff.LineMapper.LineOnOtherInfo;
import com.google.gerrit.client.diff.UnifiedChunkManager.LineRegionInfo;
import com.google.gerrit.client.diff.UnifiedChunkManager.RegionType;
import com.google.gerrit.client.ui.CommentLinkProcessor;
import com.google.gerrit.common.Nullable;
import com.google.gerrit.reviewdb.client.PatchSet;
import com.google.gerrit.reviewdb.client.Project;
import java.util.Collection;
import java.util.HashMap;
import java.util.Map;
@@ -43,12 +45,13 @@ class UnifiedCommentManager extends CommentManager {
UnifiedCommentManager(
Unified host,
@Nullable Project.NameKey project,
DiffObject base,
PatchSet.Id revision,
String path,
CommentLinkProcessor clp,
boolean open) {
super(host, base, revision, path, clp, open);
super(host, project, base, revision, path, clp, open);
mergedMap = new TreeMap<>();
duplicates = new HashMap<>();
}

View File

@@ -16,21 +16,25 @@ package com.google.gerrit.client.diff;
import com.google.gerrit.client.Gerrit;
import com.google.gerrit.client.patches.PatchUtil;
import com.google.gerrit.common.Nullable;
import com.google.gerrit.common.PageLinks;
import com.google.gerrit.reviewdb.client.PatchSet;
import com.google.gerrit.reviewdb.client.Project;
import com.google.gwt.event.dom.client.KeyPressEvent;
import com.google.gwtexpui.globalkey.client.KeyCommand;
class UpToChangeCommand extends KeyCommand {
private final PatchSet.Id revision;
@Nullable private final Project.NameKey project;
UpToChangeCommand(PatchSet.Id revision, int mask, int key) {
UpToChangeCommand(@Nullable Project.NameKey project, PatchSet.Id revision, int mask, int key) {
super(mask, key, PatchUtil.C.upToChange());
this.revision = revision;
this.project = project;
}
@Override
public void onKeyPress(KeyPressEvent event) {
Gerrit.display(PageLinks.toChange(revision.getParentKey(), revision.getId()));
Gerrit.display(PageLinks.toChange(project, revision.getParentKey(), revision.getId()));
}
}

View File

@@ -41,11 +41,13 @@ import com.google.gerrit.client.rpc.RestApi;
import com.google.gerrit.client.rpc.ScreenLoadCallback;
import com.google.gerrit.client.ui.InlineHyperlink;
import com.google.gerrit.client.ui.Screen;
import com.google.gerrit.common.Nullable;
import com.google.gerrit.common.PageLinks;
import com.google.gerrit.extensions.client.KeyMapType;
import com.google.gerrit.extensions.client.Theme;
import com.google.gerrit.reviewdb.client.Patch;
import com.google.gerrit.reviewdb.client.PatchSet;
import com.google.gerrit.reviewdb.client.Project;
import com.google.gwt.core.client.GWT;
import com.google.gwt.core.client.JsArray;
import com.google.gwt.core.client.Scheduler;
@@ -99,6 +101,7 @@ public class EditScreen extends Screen {
String hideBase();
}
@Nullable private Project.NameKey projectKey;
private final PatchSet.Id revision;
private final String path;
private final int startLine;
@@ -129,7 +132,8 @@ public class EditScreen extends Screen {
private HandlerRegistration closeHandler;
private int generation;
public EditScreen(Patch.Key patch, int startLine) {
public EditScreen(@Nullable Project.NameKey projectKey, Patch.Key patch, int startLine) {
this.projectKey = projectKey;
this.revision = patch.getParentKey();
this.path = patch.get();
this.startLine = startLine - 1;
@@ -187,11 +191,13 @@ public class EditScreen extends Screen {
}));
ChangeApi.detail(
Project.NameKey.asStringOrNull(projectKey),
revision.getParentKey().get(),
group1.add(
new AsyncCallback<ChangeInfo>() {
@Override
public void onSuccess(ChangeInfo c) {
projectKey = c.projectNameKey();
project.setInnerText(c.project());
SafeHtml.setInnerHTML(filePath, Header.formatPath(path));
}
@@ -202,6 +208,7 @@ public class EditScreen extends Screen {
if (revision.get() == 0) {
ChangeEditApi.getMeta(
Project.NameKey.asStringOrNull(projectKey),
revision,
path,
group1.add(
@@ -217,6 +224,7 @@ public class EditScreen extends Screen {
if (prefs.showBase()) {
ChangeEditApi.get(
projectKey,
revision,
path,
true /* base */,
@@ -237,7 +245,7 @@ public class EditScreen extends Screen {
} 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)
DiffApi.diff(Project.NameKey.asStringOrNull(projectKey), revision, path)
.webLinksOnly()
.get(
group1.addFinal(
@@ -253,6 +261,7 @@ public class EditScreen extends Screen {
}
ChangeEditApi.get(
projectKey,
revision,
path,
group2.add(
@@ -427,6 +436,7 @@ public class EditScreen extends Screen {
if (shouldShow) {
if (baseContent == null) {
ChangeEditApi.get(
projectKey,
revision,
path,
true /* base */,
@@ -529,7 +539,7 @@ public class EditScreen extends Screen {
}
private void upToChange() {
Gerrit.display(PageLinks.toChangeInEditMode(revision.getParentKey()));
Gerrit.display(PageLinks.toChangeInEditMode(projectKey, revision.getParentKey()));
}
private void initEditor() {
@@ -606,14 +616,14 @@ public class EditScreen extends Screen {
InlineHyperlink sbs = new InlineHyperlink();
sbs.setHTML(new ImageResourceRenderer().render(Gerrit.RESOURCES.sideBySideDiff()));
sbs.setTargetHistoryToken(
Dispatcher.toPatch("sidebyside", null, new Patch.Key(revision, path)));
Dispatcher.toPatch(projectKey, "sidebyside", null, new Patch.Key(revision, path)));
sbs.setTitle(PatchUtil.C.sideBySideDiff());
linkPanel.add(sbs);
InlineHyperlink unified = new InlineHyperlink();
unified.setHTML(new ImageResourceRenderer().render(Gerrit.RESOURCES.unifiedDiff()));
unified.setTargetHistoryToken(
Dispatcher.toPatch("unified", null, new Patch.Key(revision, path)));
Dispatcher.toPatch(projectKey, "unified", null, new Patch.Key(revision, path)));
unified.setTitle(PatchUtil.C.unifiedDiff());
linkPanel.add(unified);
}
@@ -656,6 +666,7 @@ public class EditScreen extends Screen {
}
final int g = cmEdit.changeGeneration(false);
ChangeEditApi.put(
Project.NameKey.asStringOrNull(projectKey),
revision.getParentKey().get(),
path,
text,

View File

@@ -122,7 +122,8 @@ public class ConfigInfoCache {
getImpl(name, cb);
return;
}
ChangeApi.change(id)
// TODO(hiesel) Make a preflight request to get project before we deprecate the numeric changeId
ChangeApi.change(null, id)
.get(
new AsyncCallback<ChangeInfo>() {
@Override

View File

@@ -179,7 +179,7 @@ public class RestApi {
}
};
// Defer handling the response if the parse took a while.
// Defer handling the response if the create took a while.
if ((System.currentTimeMillis() - start) > 75) {
Scheduler.get().scheduleDeferred(cmd);
} else {
@@ -258,6 +258,10 @@ public class RestApi {
return idRaw(URL.encodePathSegment(id));
}
public RestApi id(String project, int id) {
return idRaw(URL.encodePathSegment(project) + "~" + id);
}
public RestApi id(int id) {
return idRaw(Integer.toString(id));
}

View File

@@ -17,6 +17,7 @@ package com.google.gerrit.client.ui;
import com.google.gerrit.client.Gerrit;
import com.google.gerrit.common.PageLinks;
import com.google.gerrit.reviewdb.client.Change;
import com.google.gerrit.reviewdb.client.Project;
import com.google.gwt.core.client.GWT;
public class ChangeLink extends InlineHyperlink {
@@ -26,8 +27,8 @@ public class ChangeLink extends InlineHyperlink {
protected Change.Id cid;
public ChangeLink(String text, Change.Id c) {
super(text, PageLinks.toChange(c));
public ChangeLink(Project.NameKey project, Change.Id c, String text) {
super(text, PageLinks.toChange(project, c));
getElement().setPropertyString("href", permalink(c));
cid = c;
}

View File

@@ -42,7 +42,7 @@ public abstract class RebaseDialog extends CommentedActionDialog {
private final boolean sendEnabled;
public RebaseDialog(
final String project,
final Project.NameKey project,
final String branch,
final Change.Id changeId,
final boolean sendEnabled) {
@@ -88,7 +88,7 @@ public abstract class RebaseDialog extends CommentedActionDialog {
public void onClick(ClickEvent event) {
if (changeParent.getValue()) {
ChangeList.query(
PageLinks.projectQuery(new Project.NameKey(project))
PageLinks.projectQuery(project)
+ " "
+ PageLinks.op("branch", branch)
+ " is:open -age:90d",

View File

@@ -0,0 +1,86 @@
// Copyright (C) 2017 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.change;
import static com.google.common.truth.Truth.assertThat;
import com.google.gerrit.common.Nullable;
import com.google.gerrit.reviewdb.client.Change;
import com.google.gerrit.reviewdb.client.Project;
import org.junit.Rule;
import org.junit.Test;
import org.junit.rules.ExpectedException;
public class ProjectChangeIdTest {
@Rule public ExpectedException exception = ExpectedException.none();
@Test
public void emptyStringThrowsException() {
exception.expect(IllegalArgumentException.class);
exception.expectMessage(" is not a valid change identifier");
ProjectChangeId.create("");
}
@Test
public void noChangeIdThrowsException() {
exception.expect(IllegalArgumentException.class);
exception.expectMessage("some/path is not a valid change identifier");
ProjectChangeId.create("some/path");
}
@Test
public void noChangeButProjectIdThrowsException() {
exception.expect(IllegalArgumentException.class);
exception.expectMessage("some/+/path is not a valid change identifier");
ProjectChangeId.create("some/+/path");
}
@Test
public void project() {
assertThat(ProjectChangeId.create("test/+/123/some/path")).isEqualTo(result("test", 123));
assertThat(ProjectChangeId.create("test/+/123/some/path/")).isEqualTo(result("test", 123));
assertThat(ProjectChangeId.create("test/+/123/")).isEqualTo(result("test", 123));
assertThat(ProjectChangeId.create("test/+/123")).isEqualTo(result("test", 123));
// Numeric Project.NameKey
assertThat(ProjectChangeId.create("123/+/123")).isEqualTo(result("123", 123));
// Numeric Project.NameKey with ,edit as part of the name
assertThat(ProjectChangeId.create("123,edit/+/123")).isEqualTo(result("123,edit", 123));
}
@Test
public void noProject() {
assertThat(ProjectChangeId.create("123/some/path")).isEqualTo(result(null, 123));
assertThat(ProjectChangeId.create("123/some/path/")).isEqualTo(result(null, 123));
assertThat(ProjectChangeId.create("123/")).isEqualTo(result(null, 123));
assertThat(ProjectChangeId.create("123")).isEqualTo(result(null, 123));
}
@Test
public void editSuffix() {
assertThat(ProjectChangeId.create("123,edit/some/path")).isEqualTo(result(null, 123));
assertThat(ProjectChangeId.create("123,edit/")).isEqualTo(result(null, 123));
assertThat(ProjectChangeId.create("123,edit")).isEqualTo(result(null, 123));
assertThat(ProjectChangeId.create("test/+/123,edit/some/path")).isEqualTo(result("test", 123));
assertThat(ProjectChangeId.create("test/+/123,edit/")).isEqualTo(result("test", 123));
assertThat(ProjectChangeId.create("test/+/123,edit")).isEqualTo(result("test", 123));
}
private static ProjectChangeId result(@Nullable String project, int id) {
return new ProjectChangeId(
project == null ? null : new Project.NameKey(project), new Change.Id(id));
}
}

View File

@@ -9,6 +9,7 @@ import com.google.gerrit.extensions.api.changes.Changes;
import com.google.gerrit.extensions.common.ChangeInfo;
import com.google.gerrit.extensions.restapi.RestApiException;
import com.google.gerrit.reviewdb.client.Change;
import com.google.gerrit.reviewdb.client.Project;
import com.google.inject.Inject;
import com.google.inject.Singleton;
import java.io.IOException;
@@ -45,7 +46,8 @@ class DirectChangeByCommit extends HttpServlet {
if (results.size() == 1) {
// If exactly one change matches, link to that change.
// TODO Link to a specific patch set, if one matched.
token = PageLinks.toChange(new Change.Id(results.iterator().next()._number));
ChangeInfo ci = results.iterator().next();
token = PageLinks.toChange(new Project.NameKey(ci.project), new Change.Id(ci._number));
} else {
// Otherwise, link to the query page.
token = PageLinks.toChangeQuery(query);

View File

@@ -178,7 +178,10 @@ class UrlModule extends ServletModule {
idString = idString.substring(0, idString.length() - 1);
}
Change.Id id = Change.Id.parse(idString);
toGerrit(PageLinks.toChange(id), req, rsp);
// User accessed Gerrit with /1234, so we have no project yet.
// TODO(hiesel) Replace with a preflight request to obtain project before we deprecate
// the numeric change id.
toGerrit(PageLinks.toChange(null, id), req, rsp);
} catch (IllegalArgumentException err) {
rsp.sendError(HttpServletResponse.SC_NOT_FOUND);
}

View File

@@ -64,6 +64,10 @@ public final class Project {
r.fromString(str);
return r;
}
public static String asStringOrNull(NameKey key) {
return key == null ? null : key.get();
}
}
protected NameKey name;