blob: f077b2099606e9b32c01d4c9b75c255d2eea1f81 [file] [log] [blame]
// Copyright (C) 2008 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;
import static com.google.gerrit.common.PageLinks.ADMIN_CREATE_GROUP;
import static com.google.gerrit.common.PageLinks.ADMIN_CREATE_PROJECT;
import static com.google.gerrit.common.PageLinks.ADMIN_GROUPS;
import static com.google.gerrit.common.PageLinks.ADMIN_PLUGINS;
import static com.google.gerrit.common.PageLinks.ADMIN_PROJECTS;
import static com.google.gerrit.common.PageLinks.DASHBOARDS;
import static com.google.gerrit.common.PageLinks.MINE;
import static com.google.gerrit.common.PageLinks.MY_GROUPS;
import static com.google.gerrit.common.PageLinks.PROJECTS;
import static com.google.gerrit.common.PageLinks.QUERY;
import static com.google.gerrit.common.PageLinks.REGISTER;
import static com.google.gerrit.common.PageLinks.SETTINGS;
import static com.google.gerrit.common.PageLinks.SETTINGS_AGREEMENTS;
import static com.google.gerrit.common.PageLinks.SETTINGS_CONTACT;
import static com.google.gerrit.common.PageLinks.SETTINGS_DIFF_PREFERENCES;
import static com.google.gerrit.common.PageLinks.SETTINGS_EDIT_PREFERENCES;
import static com.google.gerrit.common.PageLinks.SETTINGS_EXTENSION;
import static com.google.gerrit.common.PageLinks.SETTINGS_GPGKEYS;
import static com.google.gerrit.common.PageLinks.SETTINGS_HTTP_PASSWORD;
import static com.google.gerrit.common.PageLinks.SETTINGS_MYGROUPS;
import static com.google.gerrit.common.PageLinks.SETTINGS_NEW_AGREEMENT;
import static com.google.gerrit.common.PageLinks.SETTINGS_OAUTH_TOKEN;
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;
import com.google.gerrit.client.account.MyDiffPreferencesScreen;
import com.google.gerrit.client.account.MyEditPreferencesScreen;
import com.google.gerrit.client.account.MyGpgKeysScreen;
import com.google.gerrit.client.account.MyGroupsScreen;
import com.google.gerrit.client.account.MyIdentitiesScreen;
import com.google.gerrit.client.account.MyOAuthTokenScreen;
import com.google.gerrit.client.account.MyPasswordScreen;
import com.google.gerrit.client.account.MyPreferencesScreen;
import com.google.gerrit.client.account.MyProfileScreen;
import com.google.gerrit.client.account.MySshKeysScreen;
import com.google.gerrit.client.account.MyWatchedProjectsScreen;
import com.google.gerrit.client.account.NewAgreementScreen;
import com.google.gerrit.client.account.RegisterScreen;
import com.google.gerrit.client.account.ValidateEmailScreen;
import com.google.gerrit.client.admin.AccountGroupAuditLogScreen;
import com.google.gerrit.client.admin.AccountGroupInfoScreen;
import com.google.gerrit.client.admin.AccountGroupMembersScreen;
import com.google.gerrit.client.admin.AccountGroupScreen;
import com.google.gerrit.client.admin.CreateGroupScreen;
import com.google.gerrit.client.admin.CreateProjectScreen;
import com.google.gerrit.client.admin.GroupListScreen;
import com.google.gerrit.client.admin.PluginListScreen;
import com.google.gerrit.client.admin.ProjectAccessScreen;
import com.google.gerrit.client.admin.ProjectBranchesScreen;
import com.google.gerrit.client.admin.ProjectDashboardsScreen;
import com.google.gerrit.client.admin.ProjectInfoScreen;
import com.google.gerrit.client.admin.ProjectListScreen;
import com.google.gerrit.client.admin.ProjectScreen;
import com.google.gerrit.client.admin.ProjectTagsScreen;
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.changes.AccountDashboardScreen;
import com.google.gerrit.client.changes.CustomDashboardScreen;
import com.google.gerrit.client.changes.ProjectDashboardScreen;
import com.google.gerrit.client.changes.QueryScreen;
import com.google.gerrit.client.dashboards.DashboardInfo;
import com.google.gerrit.client.dashboards.DashboardList;
import com.google.gerrit.client.diff.DisplaySide;
import com.google.gerrit.client.diff.SideBySide;
import com.google.gerrit.client.diff.Unified;
import com.google.gerrit.client.documentation.DocScreen;
import com.google.gerrit.client.editor.EditScreen;
import com.google.gerrit.client.groups.GroupApi;
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.PageLinks;
import com.google.gerrit.extensions.client.GeneralPreferencesInfo.DiffView;
import com.google.gerrit.reviewdb.client.Account;
import com.google.gerrit.reviewdb.client.AccountGroup;
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.RunAsyncCallback;
import com.google.gwt.http.client.URL;
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(
DiffObject diffBase, PatchSet.Id revision, String fileName, DisplaySide side, int line) {
return toPatch("", diffBase, revision, fileName, side, line);
}
public static String toSideBySide(DiffObject diffBase, Patch.Key id) {
return toPatch("sidebyside", diffBase, id);
}
public static String toSideBySide(DiffObject diffBase, PatchSet.Id revision, String fileName) {
return toPatch("sidebyside", 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 toUnified(DiffObject diffBase, Patch.Key id) {
return toPatch("unified", diffBase, id);
}
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);
}
private static String toPatch(
String type,
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("/");
if (diffBase != null && diffBase.asString() != null) {
p.append(diffBase.asString()).append("..");
}
p.append(revision.getId()).append("/").append(KeyUtil.encode(fileName));
if (type != null && !type.isEmpty() && (!"sidebyside".equals(type) || preferUnified())) {
p.append(",").append(type);
}
if (side == DisplaySide.A && line > 0) {
p.append("@a").append(line);
} else if (line > 0) {
p.append("@").append(line);
}
return p.toString();
}
public static String toGroup(final AccountGroup.Id id) {
return ADMIN_GROUPS + id.toString();
}
public static String toGroup(AccountGroup.Id id, String panel) {
return ADMIN_GROUPS + id.toString() + "," + panel;
}
public static String toGroup(AccountGroup.UUID uuid) {
return PageLinks.toGroup(uuid);
}
public static String toGroup(AccountGroup.UUID uuid, String panel) {
return toGroup(uuid) + "," + panel;
}
public static String toProject(Project.NameKey n) {
return toProjectAdmin(n, ProjectScreen.getSavedPanel());
}
public static String toProjectAdmin(Project.NameKey n, String panel) {
if (panel == null || ProjectScreen.INFO.equals(panel)) {
return ADMIN_PROJECTS + n.toString();
}
return ADMIN_PROJECTS + n.toString() + "," + panel;
}
static final String RELOAD_UI = "/reload-ui/";
private static boolean wasStartedByReloadUI;
void display(String token) {
assert token != null;
try {
try {
if (matchPrefix(RELOAD_UI, token)) {
wasStartedByReloadUI = true;
token = skip(token);
}
select(token);
} finally {
wasStartedByReloadUI = false;
}
} catch (RuntimeException err) {
GWT.log("Error parsing history token: " + token, err);
Gerrit.display(token, new NotFoundScreen());
}
}
private static void select(String token) {
token = Gerrit.getUrlAliasMatcher().replace(token);
if (matchPrefix(QUERY, token)) {
query(token);
} else if (matchPrefix("/Documentation/", token)) {
docSearch(token);
} else if (matchPrefix("/c/", token)) {
change(token);
} else if (matchPrefix("/x/", token)) {
extension(token);
} else if (matchExact(MINE, token)) {
String defaultScreenToken = Gerrit.getDefaultScreenToken();
if (defaultScreenToken != null && !MINE.equals(defaultScreenToken)) {
select(defaultScreenToken);
} else {
Gerrit.display(token, mine());
}
} else if (matchPrefix("/dashboard/", token)) {
dashboard(token);
} else if (matchPrefix(PROJECTS, token)) {
projects(token);
} else if (matchExact(SETTINGS, token)
|| matchPrefix("/settings/", token)
|| matchExact(MY_GROUPS, token)
|| matchExact("register", token)
|| matchExact(REGISTER, token)
|| matchPrefix("/register/", token)
|| matchPrefix("/VE/", token)
|| matchPrefix("VE,", token)
|| matchPrefix("/SignInFailure,", token)) {
settings(token);
} else if (matchPrefix("/admin/", token)) {
admin(token);
} else {
Gerrit.display(token, new NotFoundScreen());
}
}
private static void query(String token) {
String s = skip(token);
int c = s.indexOf(',');
Screen screen;
if (c >= 0) {
String prefix = s.substring(0, c);
if (s.substring(c).equals(",n,z")) {
// Respect legacy token with max sortkey.
screen = new QueryScreen(prefix, 0);
} else {
screen = new QueryScreen(prefix, Integer.parseInt(s.substring(c + 1)));
}
} else {
screen = new QueryScreen(s, 0);
}
Gerrit.display(token, screen);
}
private static Screen mine() {
if (Gerrit.isSignedIn()) {
return new AccountDashboardScreen(Gerrit.getUserAccount().getId());
}
Screen r = new AccountDashboardScreen(null);
r.setRequiresSignIn(true);
return r;
}
private static void dashboard(final String token) {
String rest = skip(token);
if (rest.matches("[0-9]+")) {
Gerrit.display(token, new AccountDashboardScreen(Account.Id.parse(rest)));
return;
}
if (rest.equals("self")) {
if (Gerrit.isSignedIn()) {
Gerrit.display(token, new AccountDashboardScreen(Gerrit.getUserAccount().getId()));
} else {
Screen s = new AccountDashboardScreen(null);
s.setRequiresSignIn(true);
Gerrit.display(token, s);
}
return;
}
if (rest.startsWith("?")) {
Gerrit.display(token, new CustomDashboardScreen(rest.substring(1)));
return;
}
Gerrit.display(token, new NotFoundScreen());
}
private static void projects(final String token) {
String rest = skip(token);
int c = rest.indexOf(DASHBOARDS);
if (0 <= c) {
final String project = URL.decodePathSegment(rest.substring(0, c));
rest = rest.substring(c);
if (matchPrefix(DASHBOARDS, rest)) {
final String dashboardId = skip(rest);
GerritCallback<DashboardInfo> cb =
new GerritCallback<DashboardInfo>() {
@Override
public void onSuccess(DashboardInfo result) {
if (matchPrefix("/dashboard/", result.url())) {
String params = skip(result.url()).substring(1);
ProjectDashboardScreen dash =
new ProjectDashboardScreen(new Project.NameKey(project), params);
Gerrit.display(token, dash);
}
}
@Override
public void onFailure(Throwable caught) {
if ("default".equals(dashboardId) && RestApi.isNotFound(caught)) {
Gerrit.display(
toChangeQuery(PageLinks.projectQuery(new Project.NameKey(project))));
} else {
super.onFailure(caught);
}
}
};
if ("default".equals(dashboardId)) {
DashboardList.getDefault(new Project.NameKey(project), cb);
return;
}
c = dashboardId.indexOf(":");
if (0 <= c) {
final String ref = URL.decodeQueryString(dashboardId.substring(0, c));
final String path = URL.decodeQueryString(dashboardId.substring(c + 1));
DashboardList.get(new Project.NameKey(project), ref + ":" + path, cb);
return;
}
}
}
Gerrit.display(token, new NotFoundScreen());
}
private static void change(final String token) {
String rest = skip(token);
int c = rest.lastIndexOf(',');
String panel = null;
if (0 <= c) {
panel = rest.substring(c + 1);
rest = rest.substring(0, c);
int at = panel.lastIndexOf('@');
if (at > 0) {
rest += panel.substring(at);
panel = panel.substring(0, at);
}
}
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 = "";
}
if (rest.isEmpty()) {
FileTable.Mode mode = FileTable.Mode.REVIEW;
if (panel != null && (panel.equals("edit") || panel.startsWith("edit/"))) {
mode = FileTable.Mode.EDIT;
panel = null;
}
Gerrit.display(
token,
panel == null
? new ChangeScreen(id, DiffObject.base(), null, false, mode)
: new NotFoundScreen());
return;
}
String psIdStr;
s = rest.indexOf('/');
if (0 <= s) {
psIdStr = rest.substring(0, s);
rest = rest.substring(s + 1);
} else {
psIdStr = rest;
rest = "";
}
DiffObject base = DiffObject.base();
PatchSet.Id ps;
int dotdot = psIdStr.indexOf("..");
if (1 <= dotdot) {
base = DiffObject.parse(id, psIdStr.substring(0, dotdot));
if (base == null) {
Gerrit.display(token, new NotFoundScreen());
}
psIdStr = psIdStr.substring(dotdot + 2);
}
ps = toPsId(id, psIdStr);
if (!rest.isEmpty()) {
DisplaySide side = DisplaySide.B;
int line = 0;
int at = rest.lastIndexOf('@');
if (at > 0) {
String l = rest.substring(at + 1);
if (l.startsWith("a")) {
side = DisplaySide.A;
l = l.substring(1);
}
line = Integer.parseInt(l);
rest = rest.substring(0, at);
}
Patch.Key p = new Patch.Key(ps, KeyUtil.decode(rest));
patch(token, base, p, side, line, panel);
} else {
if (panel == null) {
Gerrit.display(
token,
new ChangeScreen(id, base, String.valueOf(ps.get()), false, FileTable.Mode.REVIEW));
} else {
Gerrit.display(token, new NotFoundScreen());
}
}
}
public static PatchSet.Id toPsId(Change.Id id, String psIdStr) {
return new PatchSet.Id(id, psIdStr.equals("edit") ? 0 : Integer.parseInt(psIdStr));
}
private static void extension(final String token) {
ExtensionScreen view = new ExtensionScreen(skip(token));
if (view.isFound()) {
Gerrit.display(token, view);
} else {
Gerrit.display(token, new NotFoundScreen());
}
}
private static void patch(
String token, DiffObject base, Patch.Key id, DisplaySide side, int line, String panelType) {
String panel = panelType;
if (panel == null) {
int c = token.lastIndexOf(',');
panel = 0 <= c ? token.substring(c + 1) : "";
}
if ("".equals(panel) || /* DEPRECATED URL */ "cm".equals(panel)) {
if (preferUnified()) {
unified(token, base, id, side, line);
} else {
codemirror(token, base, id, side, line);
}
} else if ("sidebyside".equals(panel)) {
codemirror(token, base, id, side, line);
} else if ("unified".equals(panel)) {
unified(token, base, id, side, line);
} else if ("edit".equals(panel)) {
if (!Patch.isMagic(id.get()) || Patch.COMMIT_MSG.equals(id.get())) {
codemirrorForEdit(token, id, line);
} else {
Gerrit.display(token, new NotFoundScreen());
}
} else {
Gerrit.display(token, new NotFoundScreen());
}
}
private static boolean preferUnified() {
return DiffView.UNIFIED_DIFF.equals(Gerrit.getUserPreferences().diffView())
|| (UserAgent.isPortrait() && UserAgent.isMobile());
}
private static void unified(
final String token,
final DiffObject base,
final Patch.Key id,
final DisplaySide side,
final int line) {
GWT.runAsync(
new AsyncSplit(token) {
@Override
public void onSuccess() {
Gerrit.display(
token,
new Unified(base, DiffObject.patchSet(id.getParentKey()), id.get(), side, line));
}
});
}
private static void codemirror(
final String token,
final DiffObject base,
final Patch.Key id,
final DisplaySide side,
final int line) {
GWT.runAsync(
new AsyncSplit(token) {
@Override
public void onSuccess() {
Gerrit.display(
token,
new SideBySide(base, DiffObject.patchSet(id.getParentKey()), id.get(), side, line));
}
});
}
private static void codemirrorForEdit(final String token, final Patch.Key id, final int line) {
GWT.runAsync(
new AsyncSplit(token) {
@Override
public void onSuccess() {
Gerrit.display(token, new EditScreen(id, line));
}
});
}
private static void settings(String token) {
GWT.runAsync(
new AsyncSplit(token) {
@Override
public void onSuccess() {
Gerrit.display(token, select());
}
private Screen select() {
if (matchExact(SETTINGS, token)) {
return new MyProfileScreen();
}
if (matchExact(SETTINGS_PREFERENCES, token)) {
return new MyPreferencesScreen();
}
if (matchExact(SETTINGS_DIFF_PREFERENCES, token)) {
return new MyDiffPreferencesScreen();
}
if (matchExact(SETTINGS_EDIT_PREFERENCES, token)) {
return new MyEditPreferencesScreen();
}
if (matchExact(SETTINGS_PROJECTS, token)) {
return new MyWatchedProjectsScreen();
}
if (matchExact(SETTINGS_CONTACT, token)) {
return new MyContactInformationScreen();
}
if (matchExact(SETTINGS_SSHKEYS, token)) {
return new MySshKeysScreen();
}
if (matchExact(SETTINGS_GPGKEYS, token) && Gerrit.info().gerrit().editGpgKeys()) {
return new MyGpgKeysScreen();
}
if (matchExact(SETTINGS_WEBIDENT, token)) {
return new MyIdentitiesScreen();
}
if (matchExact(SETTINGS_HTTP_PASSWORD, token)) {
return new MyPasswordScreen();
}
if (matchExact(SETTINGS_OAUTH_TOKEN, token) && Gerrit.info().auth().isOAuth()) {
return new MyOAuthTokenScreen();
}
if (matchExact(MY_GROUPS, token) || matchExact(SETTINGS_MYGROUPS, token)) {
return new MyGroupsScreen();
}
if (matchExact(SETTINGS_AGREEMENTS, token)
&& Gerrit.info().auth().useContributorAgreements()) {
return new MyAgreementsScreen();
}
if (matchExact(REGISTER, token)
|| matchExact("/register/", token)
|| matchExact("register", token)) {
return new RegisterScreen(MINE);
} else if (matchPrefix("/register/", token)) {
return new RegisterScreen("/" + skip(token));
}
if (matchPrefix("/VE/", token) || matchPrefix("VE,", token)) {
return new ValidateEmailScreen(skip(token));
}
if (matchExact(SETTINGS_NEW_AGREEMENT, token)) {
return new NewAgreementScreen();
}
if (matchPrefix(SETTINGS_NEW_AGREEMENT + "/", token)) {
return new NewAgreementScreen(skip(token));
}
if (matchPrefix(SETTINGS_EXTENSION, token)) {
ExtensionSettingsScreen view = new ExtensionSettingsScreen(skip(token));
if (view.isFound()) {
return view;
}
return new NotFoundScreen();
}
return new NotFoundScreen();
}
});
}
private static void admin(String token) {
GWT.runAsync(
new AsyncSplit(token) {
@Override
public void onSuccess() {
if (matchExact(ADMIN_GROUPS, token) || matchExact("/admin/groups", token)) {
Gerrit.display(token, new GroupListScreen());
} else if (matchPrefix(ADMIN_GROUPS, token)) {
String rest = skip(token);
if (rest.startsWith("?")) {
Gerrit.display(token, new GroupListScreen(rest.substring(1)));
} else {
group();
}
} else if (matchPrefix("/admin/groups", token)) {
String rest = skip(token);
if (rest.startsWith("?")) {
Gerrit.display(token, new GroupListScreen(rest.substring(1)));
}
} else if (matchExact(ADMIN_PROJECTS, token) || matchExact("/admin/projects", token)) {
Gerrit.display(token, new ProjectListScreen());
} else if (matchPrefix(ADMIN_PROJECTS, token)) {
String rest = skip(token);
if (rest.startsWith("?")) {
Gerrit.display(token, new ProjectListScreen(rest.substring(1)));
} else {
Gerrit.display(token, selectProject());
}
} else if (matchPrefix("/admin/projects", token)) {
String rest = skip(token);
if (rest.startsWith("?")) {
Gerrit.display(token, new ProjectListScreen(rest.substring(1)));
}
} else if (matchPrefix(ADMIN_PLUGINS, token) || matchExact("/admin/plugins", token)) {
Gerrit.display(token, new PluginListScreen());
} else if (matchExact(ADMIN_CREATE_PROJECT, token)
|| matchExact("/admin/create-project", token)) {
Gerrit.display(token, new CreateProjectScreen());
} else if (matchExact(ADMIN_CREATE_GROUP, token)
|| matchExact("/admin/create-group", token)) {
Gerrit.display(token, new CreateGroupScreen());
} else {
Gerrit.display(token, new NotFoundScreen());
}
}
private void group() {
final String panel;
final String group;
if (matchPrefix("/admin/groups/uuid-", token)) {
String p = skip(token);
int c = p.indexOf(',');
if (c < 0) {
group = p;
panel = null;
} else {
group = p.substring(0, c);
panel = p.substring(c + 1);
}
} else if (matchPrefix(ADMIN_GROUPS, token)) {
String p = skip(token);
int c = p.indexOf(',');
if (c < 0) {
group = p;
panel = null;
} else {
group = p.substring(0, c);
panel = p.substring(c + 1);
}
} else {
Gerrit.display(token, new NotFoundScreen());
return;
}
GroupApi.getGroupDetail(
group,
new GerritCallback<GroupInfo>() {
@Override
public void onSuccess(GroupInfo group) {
if (panel == null || panel.isEmpty()) {
// The token does not say which group screen should be shown,
// as default for internal groups show the members, as default
// for external and system groups show the info screen (since
// for external and system groups the members cannot be
// shown in the web UI).
//
if (AccountGroup.isInternalGroup(group.getGroupUUID())) {
String newToken = toGroup(group.getGroupId(), AccountGroupScreen.MEMBERS);
Gerrit.display(newToken, new AccountGroupMembersScreen(group, newToken));
} else {
String newToken = toGroup(group.getGroupId(), AccountGroupScreen.INFO);
Gerrit.display(newToken, new AccountGroupInfoScreen(group, newToken));
}
} else if (AccountGroupScreen.INFO.equals(panel)) {
Gerrit.display(token, new AccountGroupInfoScreen(group, token));
} else if (AccountGroupScreen.MEMBERS.equals(panel)) {
Gerrit.display(token, new AccountGroupMembersScreen(group, token));
} else if (AccountGroupScreen.AUDIT_LOG.equals(panel)) {
Gerrit.display(token, new AccountGroupAuditLogScreen(group, token));
} else {
Gerrit.display(token, new NotFoundScreen());
}
}
});
}
private Screen selectProject() {
if (matchPrefix(ADMIN_PROJECTS, token)) {
String rest = skip(token);
int c = rest.lastIndexOf(',');
if (c < 0) {
return new ProjectInfoScreen(Project.NameKey.parse(rest));
} else if (c == 0) {
return new NotFoundScreen();
}
int q = rest.lastIndexOf('?');
if (q > 0 && rest.lastIndexOf(',', q) > 0) {
c = rest.substring(0, q - 1).lastIndexOf(',');
}
Project.NameKey k = Project.NameKey.parse(rest.substring(0, c));
String panel = rest.substring(c + 1);
if (ProjectScreen.INFO.equals(panel)) {
return new ProjectInfoScreen(k);
}
if (ProjectScreen.BRANCHES.equals(panel)
|| matchPrefix(ProjectScreen.BRANCHES, panel)) {
return new ProjectBranchesScreen(k);
}
if (ProjectScreen.TAGS.equals(panel) || matchPrefix(ProjectScreen.TAGS, panel)) {
return new ProjectTagsScreen(k);
}
if (ProjectScreen.ACCESS.equals(panel)) {
return new ProjectAccessScreen(k);
}
if (ProjectScreen.DASHBOARDS.equals(panel)) {
return new ProjectDashboardsScreen(k);
}
}
return new NotFoundScreen();
}
});
}
private static boolean matchExact(String want, String token) {
return token.equals(want);
}
private static int prefixlen;
private static boolean matchPrefix(String want, String token) {
if (token.startsWith(want)) {
prefixlen = want.length();
return true;
}
return false;
}
private static String skip(String token) {
return token.substring(prefixlen);
}
private abstract static class AsyncSplit implements RunAsyncCallback {
private final boolean isReloadUi;
protected final String token;
protected AsyncSplit(String token) {
this.isReloadUi = wasStartedByReloadUI;
this.token = token;
}
@Override
public final void onFailure(Throwable reason) {
if (!isReloadUi && "HTTP download failed with status 404".equals(reason.getMessage())) {
// The server was upgraded since we last download the main script,
// so the pointers to the splits aren't valid anymore. Force the
// page to reload itself and pick up the new code.
//
Gerrit.upgradeUI(token);
} else {
new ErrorDialog(reason).center();
}
}
}
private static void docSearch(final String token) {
GWT.runAsync(
new AsyncSplit(token) {
@Override
public void onSuccess() {
Gerrit.display(token, new DocScreen(skip(token)));
}
});
}
}