PageRenderTime 223ms CodeModel.GetById 67ms RepoModel.GetById 0ms app.codeStats 1ms

/gerrit-gwtui/src/main/java/com/google/gerrit/client/Dispatcher.java

https://gitlab.com/chenfengxu/gerrit
Java | 879 lines | 753 code | 102 blank | 24 comment | 202 complexity | decf9524c9bbc14b2d88e6488b6464e3 MD5 | raw file
  1. // Copyright (C) 2008 The Android Open Source Project
  2. //
  3. // Licensed under the Apache License, Version 2.0 (the "License");
  4. // you may not use this file except in compliance with the License.
  5. // You may obtain a copy of the License at
  6. //
  7. // http://www.apache.org/licenses/LICENSE-2.0
  8. //
  9. // Unless required by applicable law or agreed to in writing, software
  10. // distributed under the License is distributed on an "AS IS" BASIS,
  11. // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  12. // See the License for the specific language governing permissions and
  13. // limitations under the License.
  14. package com.google.gerrit.client;
  15. import static com.google.gerrit.common.PageLinks.ADMIN_CREATE_GROUP;
  16. import static com.google.gerrit.common.PageLinks.ADMIN_CREATE_PROJECT;
  17. import static com.google.gerrit.common.PageLinks.ADMIN_GROUPS;
  18. import static com.google.gerrit.common.PageLinks.ADMIN_PLUGINS;
  19. import static com.google.gerrit.common.PageLinks.ADMIN_PROJECTS;
  20. import static com.google.gerrit.common.PageLinks.DASHBOARDS;
  21. import static com.google.gerrit.common.PageLinks.MINE;
  22. import static com.google.gerrit.common.PageLinks.MY_GROUPS;
  23. import static com.google.gerrit.common.PageLinks.PROJECTS;
  24. import static com.google.gerrit.common.PageLinks.QUERY;
  25. import static com.google.gerrit.common.PageLinks.REGISTER;
  26. import static com.google.gerrit.common.PageLinks.SETTINGS;
  27. import static com.google.gerrit.common.PageLinks.SETTINGS_AGREEMENTS;
  28. import static com.google.gerrit.common.PageLinks.SETTINGS_CONTACT;
  29. import static com.google.gerrit.common.PageLinks.SETTINGS_DIFF_PREFERENCES;
  30. import static com.google.gerrit.common.PageLinks.SETTINGS_EDIT_PREFERENCES;
  31. import static com.google.gerrit.common.PageLinks.SETTINGS_EXTENSION;
  32. import static com.google.gerrit.common.PageLinks.SETTINGS_GPGKEYS;
  33. import static com.google.gerrit.common.PageLinks.SETTINGS_HTTP_PASSWORD;
  34. import static com.google.gerrit.common.PageLinks.SETTINGS_MYGROUPS;
  35. import static com.google.gerrit.common.PageLinks.SETTINGS_NEW_AGREEMENT;
  36. import static com.google.gerrit.common.PageLinks.SETTINGS_OAUTH_TOKEN;
  37. import static com.google.gerrit.common.PageLinks.SETTINGS_PREFERENCES;
  38. import static com.google.gerrit.common.PageLinks.SETTINGS_PROJECTS;
  39. import static com.google.gerrit.common.PageLinks.SETTINGS_SSHKEYS;
  40. import static com.google.gerrit.common.PageLinks.SETTINGS_WEBIDENT;
  41. import com.google.gerrit.client.account.MyAgreementsScreen;
  42. import com.google.gerrit.client.account.MyContactInformationScreen;
  43. import com.google.gerrit.client.account.MyDiffPreferencesScreen;
  44. import com.google.gerrit.client.account.MyEditPreferencesScreen;
  45. import com.google.gerrit.client.account.MyGpgKeysScreen;
  46. import com.google.gerrit.client.account.MyGroupsScreen;
  47. import com.google.gerrit.client.account.MyIdentitiesScreen;
  48. import com.google.gerrit.client.account.MyOAuthTokenScreen;
  49. import com.google.gerrit.client.account.MyPasswordScreen;
  50. import com.google.gerrit.client.account.MyPreferencesScreen;
  51. import com.google.gerrit.client.account.MyProfileScreen;
  52. import com.google.gerrit.client.account.MySshKeysScreen;
  53. import com.google.gerrit.client.account.MyWatchedProjectsScreen;
  54. import com.google.gerrit.client.account.NewAgreementScreen;
  55. import com.google.gerrit.client.account.RegisterScreen;
  56. import com.google.gerrit.client.account.ValidateEmailScreen;
  57. import com.google.gerrit.client.admin.AccountGroupAuditLogScreen;
  58. import com.google.gerrit.client.admin.AccountGroupInfoScreen;
  59. import com.google.gerrit.client.admin.AccountGroupMembersScreen;
  60. import com.google.gerrit.client.admin.AccountGroupScreen;
  61. import com.google.gerrit.client.admin.CreateGroupScreen;
  62. import com.google.gerrit.client.admin.CreateProjectScreen;
  63. import com.google.gerrit.client.admin.GroupListScreen;
  64. import com.google.gerrit.client.admin.PluginListScreen;
  65. import com.google.gerrit.client.admin.ProjectAccessScreen;
  66. import com.google.gerrit.client.admin.ProjectBranchesScreen;
  67. import com.google.gerrit.client.admin.ProjectDashboardsScreen;
  68. import com.google.gerrit.client.admin.ProjectInfoScreen;
  69. import com.google.gerrit.client.admin.ProjectListScreen;
  70. import com.google.gerrit.client.admin.ProjectScreen;
  71. import com.google.gerrit.client.admin.ProjectTagsScreen;
  72. import com.google.gerrit.client.api.ExtensionScreen;
  73. import com.google.gerrit.client.api.ExtensionSettingsScreen;
  74. import com.google.gerrit.client.change.ChangeScreen;
  75. import com.google.gerrit.client.change.FileTable;
  76. import com.google.gerrit.client.change.ProjectChangeId;
  77. import com.google.gerrit.client.changes.AccountDashboardScreen;
  78. import com.google.gerrit.client.changes.CustomDashboardScreen;
  79. import com.google.gerrit.client.changes.ProjectDashboardScreen;
  80. import com.google.gerrit.client.changes.QueryScreen;
  81. import com.google.gerrit.client.dashboards.DashboardInfo;
  82. import com.google.gerrit.client.dashboards.DashboardList;
  83. import com.google.gerrit.client.diff.DisplaySide;
  84. import com.google.gerrit.client.diff.SideBySide;
  85. import com.google.gerrit.client.diff.Unified;
  86. import com.google.gerrit.client.documentation.DocScreen;
  87. import com.google.gerrit.client.editor.EditScreen;
  88. import com.google.gerrit.client.groups.GroupApi;
  89. import com.google.gerrit.client.info.GroupInfo;
  90. import com.google.gerrit.client.rpc.GerritCallback;
  91. import com.google.gerrit.client.rpc.RestApi;
  92. import com.google.gerrit.client.ui.Screen;
  93. import com.google.gerrit.common.Nullable;
  94. import com.google.gerrit.common.PageLinks;
  95. import com.google.gerrit.extensions.client.GeneralPreferencesInfo.DiffView;
  96. import com.google.gerrit.reviewdb.client.AccountGroup;
  97. import com.google.gerrit.reviewdb.client.Change;
  98. import com.google.gerrit.reviewdb.client.Patch;
  99. import com.google.gerrit.reviewdb.client.PatchSet;
  100. import com.google.gerrit.reviewdb.client.Project;
  101. import com.google.gwt.core.client.GWT;
  102. import com.google.gwt.core.client.RunAsyncCallback;
  103. import com.google.gwt.http.client.URL;
  104. import com.google.gwtexpui.user.client.UserAgent;
  105. import com.google.gwtorm.client.KeyUtil;
  106. public class Dispatcher {
  107. public static String toPatch(
  108. @Nullable Project.NameKey project,
  109. DiffObject diffBase,
  110. PatchSet.Id revision,
  111. String fileName) {
  112. return toPatch("", project, diffBase, revision, fileName, null, 0);
  113. }
  114. public static String toPatch(
  115. @Nullable Project.NameKey project,
  116. DiffObject diffBase,
  117. PatchSet.Id revision,
  118. String fileName,
  119. DisplaySide side,
  120. int line) {
  121. return toPatch("", project, diffBase, revision, fileName, side, line);
  122. }
  123. public static String toSideBySide(
  124. @Nullable Project.NameKey project,
  125. DiffObject diffBase,
  126. PatchSet.Id revision,
  127. String fileName) {
  128. return toPatch("sidebyside", project, diffBase, revision, fileName, null, 0);
  129. }
  130. public static String toUnified(
  131. @Nullable Project.NameKey project,
  132. DiffObject diffBase,
  133. PatchSet.Id revision,
  134. String fileName) {
  135. return toPatch("unified", project, diffBase, revision, fileName, null, 0);
  136. }
  137. public static String toPatch(
  138. @Nullable Project.NameKey project, String type, DiffObject diffBase, Patch.Key id) {
  139. return toPatch(type, project, diffBase, id.getParentKey(), id.get(), null, 0);
  140. }
  141. public static String toEditScreen(
  142. @Nullable Project.NameKey project, PatchSet.Id revision, String fileName) {
  143. return toEditScreen(project, revision, fileName, 0);
  144. }
  145. public static String toEditScreen(
  146. @Nullable Project.NameKey project, PatchSet.Id revision, String fileName, int line) {
  147. return toPatch("edit", project, DiffObject.base(), revision, fileName, null, line);
  148. }
  149. private static String toPatch(
  150. String type,
  151. @Nullable Project.NameKey project,
  152. DiffObject diffBase,
  153. PatchSet.Id revision,
  154. String fileName,
  155. DisplaySide side,
  156. int line) {
  157. Change.Id c = revision.getParentKey();
  158. StringBuilder p = new StringBuilder(PageLinks.toChange(project, c));
  159. if (diffBase != null && diffBase.asString() != null) {
  160. p.append(diffBase.asString()).append("..");
  161. }
  162. p.append(revision.getId()).append("/").append(KeyUtil.encode(fileName));
  163. if (type != null && !type.isEmpty() && (!"sidebyside".equals(type) || preferUnified())) {
  164. p.append(",").append(type);
  165. }
  166. if (side == DisplaySide.A && line > 0) {
  167. p.append("@a").append(line);
  168. } else if (line > 0) {
  169. p.append("@").append(line);
  170. }
  171. return p.toString();
  172. }
  173. public static String toGroup(AccountGroup.Id id) {
  174. return ADMIN_GROUPS + id.toString();
  175. }
  176. public static String toGroup(AccountGroup.Id id, String panel) {
  177. return ADMIN_GROUPS + id.toString() + "," + panel;
  178. }
  179. public static String toGroup(AccountGroup.UUID uuid) {
  180. return PageLinks.toGroup(uuid);
  181. }
  182. public static String toGroup(AccountGroup.UUID uuid, String panel) {
  183. return toGroup(uuid) + "," + panel;
  184. }
  185. public static String toProject(Project.NameKey n) {
  186. return toProjectAdmin(n, ProjectScreen.getSavedPanel());
  187. }
  188. public static String toProjectAdmin(Project.NameKey n, String panel) {
  189. if (panel == null || ProjectScreen.INFO.equals(panel)) {
  190. return ADMIN_PROJECTS + n.toString();
  191. }
  192. return ADMIN_PROJECTS + n.toString() + "," + panel;
  193. }
  194. static final String RELOAD_UI = "/reload-ui/";
  195. private static boolean wasStartedByReloadUI;
  196. void display(String token) {
  197. assert token != null;
  198. try {
  199. try {
  200. if (matchPrefix(RELOAD_UI, token)) {
  201. wasStartedByReloadUI = true;
  202. token = skip(token);
  203. }
  204. select(token);
  205. } finally {
  206. wasStartedByReloadUI = false;
  207. }
  208. } catch (RuntimeException err) {
  209. GWT.log("Error parsing history token: " + token, err);
  210. Gerrit.display(token, new NotFoundScreen());
  211. }
  212. }
  213. private static void select(String token) {
  214. token = Gerrit.getUrlAliasMatcher().replace(token);
  215. if (matchPrefix(QUERY, token)) {
  216. query(token);
  217. } else if (matchPrefix("/Documentation/", token)) {
  218. docSearch(token);
  219. } else if (matchPrefix("/c/", token)) {
  220. change(token);
  221. } else if (matchPrefix("/x/", token)) {
  222. extension(token);
  223. } else if (matchExact(MINE, token)) {
  224. String defaultScreenToken = Gerrit.getDefaultScreenToken();
  225. if (defaultScreenToken != null && !MINE.equals(defaultScreenToken)) {
  226. select(defaultScreenToken);
  227. } else {
  228. Gerrit.display(token, mine());
  229. }
  230. } else if (matchPrefix("/dashboard/", token)) {
  231. dashboard(token);
  232. } else if (matchPrefix(PROJECTS, token)) {
  233. projects(token);
  234. } else if (matchExact(SETTINGS, token)
  235. || matchPrefix("/settings/", token)
  236. || matchExact(MY_GROUPS, token)
  237. || matchExact("register", token)
  238. || matchExact(REGISTER, token)
  239. || matchPrefix("/register/", token)
  240. || matchPrefix("/VE/", token)
  241. || matchPrefix("VE,", token)
  242. || matchPrefix("/SignInFailure,", token)) {
  243. settings(token);
  244. } else if (matchPrefix("/admin/", token)) {
  245. admin(token);
  246. } else {
  247. Gerrit.display(token, new NotFoundScreen());
  248. }
  249. }
  250. private static void query(String token) {
  251. String s = skip(token);
  252. int c = s.indexOf(',');
  253. Screen screen;
  254. if (c >= 0) {
  255. String prefix = s.substring(0, c);
  256. if (s.substring(c).equals(",n,z")) {
  257. // Respect legacy token with max sortkey.
  258. screen = new QueryScreen(prefix, 0);
  259. } else {
  260. screen = new QueryScreen(prefix, Integer.parseInt(s.substring(c + 1)));
  261. }
  262. } else {
  263. screen = new QueryScreen(s, 0);
  264. }
  265. Gerrit.display(token, screen);
  266. }
  267. private static Screen mine() {
  268. if (Gerrit.isSignedIn()) {
  269. return new AccountDashboardScreen(Gerrit.getUserAccount()._accountId());
  270. }
  271. Screen r = new AccountDashboardScreen(null);
  272. r.setRequiresSignIn(true);
  273. return r;
  274. }
  275. private static void dashboard(String token) {
  276. String rest = skip(token);
  277. if (rest.matches("[0-9]+")) {
  278. int accountId = Integer.parseInt(rest);
  279. Gerrit.display(token, new AccountDashboardScreen(accountId));
  280. return;
  281. }
  282. if (rest.equals("self")) {
  283. if (Gerrit.isSignedIn()) {
  284. Gerrit.display(token, new AccountDashboardScreen(Gerrit.getUserAccount()._accountId()));
  285. } else {
  286. Screen s = new AccountDashboardScreen(null);
  287. s.setRequiresSignIn(true);
  288. Gerrit.display(token, s);
  289. }
  290. return;
  291. }
  292. if (rest.startsWith("?")) {
  293. Gerrit.display(token, new CustomDashboardScreen(rest.substring(1)));
  294. return;
  295. }
  296. Gerrit.display(token, new NotFoundScreen());
  297. }
  298. private static void projects(String token) {
  299. String rest = skip(token);
  300. int c = rest.indexOf(DASHBOARDS);
  301. if (0 <= c) {
  302. final String project = URL.decodePathSegment(rest.substring(0, c));
  303. rest = rest.substring(c);
  304. if (matchPrefix(DASHBOARDS, rest)) {
  305. final String dashboardId = skip(rest);
  306. GerritCallback<DashboardInfo> cb =
  307. new GerritCallback<DashboardInfo>() {
  308. @Override
  309. public void onSuccess(DashboardInfo result) {
  310. if (matchPrefix("/dashboard/", result.url())) {
  311. String params = skip(result.url()).substring(1);
  312. ProjectDashboardScreen dash =
  313. new ProjectDashboardScreen(new Project.NameKey(project), params);
  314. Gerrit.display(token, dash);
  315. }
  316. }
  317. @Override
  318. public void onFailure(Throwable caught) {
  319. if ("default".equals(dashboardId) && RestApi.isNotFound(caught)) {
  320. Gerrit.display(
  321. PageLinks.toChangeQuery(
  322. PageLinks.projectQuery(new Project.NameKey(project))));
  323. } else {
  324. super.onFailure(caught);
  325. }
  326. }
  327. };
  328. if ("default".equals(dashboardId)) {
  329. DashboardList.getDefault(new Project.NameKey(project), cb);
  330. return;
  331. }
  332. c = dashboardId.indexOf(":");
  333. if (0 <= c) {
  334. final String ref = URL.decodeQueryString(dashboardId.substring(0, c));
  335. final String path = URL.decodeQueryString(dashboardId.substring(c + 1));
  336. DashboardList.get(new Project.NameKey(project), ref + ":" + path, cb);
  337. return;
  338. }
  339. }
  340. }
  341. Gerrit.display(token, new NotFoundScreen());
  342. }
  343. private static void change(String token) {
  344. String rest = skip(token);
  345. int c = rest.lastIndexOf(',');
  346. String panel = null;
  347. if (0 <= c) {
  348. panel = rest.substring(c + 1);
  349. rest = rest.substring(0, c);
  350. int at = panel.lastIndexOf('@');
  351. if (at > 0) {
  352. rest += panel.substring(at);
  353. panel = panel.substring(0, at);
  354. }
  355. }
  356. ProjectChangeId id = ProjectChangeId.create(rest);
  357. rest = rest.length() > id.identifierLength() ? rest.substring(id.identifierLength() + 1) : "";
  358. if (rest.isEmpty()) {
  359. FileTable.Mode mode = FileTable.Mode.REVIEW;
  360. if (panel != null && (panel.equals("edit") || panel.startsWith("edit/"))) {
  361. mode = FileTable.Mode.EDIT;
  362. panel = null;
  363. }
  364. Gerrit.display(
  365. token,
  366. panel == null
  367. ? new ChangeScreen(
  368. id.getProject(), id.getChangeId(), DiffObject.base(), null, false, mode)
  369. : new NotFoundScreen());
  370. return;
  371. }
  372. String psIdStr;
  373. int s = rest.indexOf('/');
  374. if (0 <= s) {
  375. psIdStr = rest.substring(0, s);
  376. rest = rest.substring(s + 1);
  377. } else {
  378. psIdStr = rest;
  379. rest = "";
  380. }
  381. DiffObject base = DiffObject.base();
  382. PatchSet.Id ps;
  383. int dotdot = psIdStr.indexOf("..");
  384. if (1 <= dotdot) {
  385. base = DiffObject.parse(id.getChangeId(), psIdStr.substring(0, dotdot));
  386. if (base == null) {
  387. Gerrit.display(token, new NotFoundScreen());
  388. }
  389. psIdStr = psIdStr.substring(dotdot + 2);
  390. }
  391. ps = toPsId(id.getChangeId(), psIdStr);
  392. if (!rest.isEmpty()) {
  393. DisplaySide side = DisplaySide.B;
  394. int line = 0;
  395. int at = rest.lastIndexOf('@');
  396. if (at > 0) {
  397. String l = rest.substring(at + 1);
  398. if (l.startsWith("a")) {
  399. side = DisplaySide.A;
  400. l = l.substring(1);
  401. }
  402. line = Integer.parseInt(l);
  403. rest = rest.substring(0, at);
  404. }
  405. Patch.Key p = new Patch.Key(ps, KeyUtil.decode(rest));
  406. patch(token, id.getProject(), base, p, side, line, panel);
  407. } else {
  408. if (panel == null) {
  409. Gerrit.display(
  410. token,
  411. new ChangeScreen(
  412. id.getProject(),
  413. id.getChangeId(),
  414. base,
  415. String.valueOf(ps.get()),
  416. false,
  417. FileTable.Mode.REVIEW));
  418. } else {
  419. Gerrit.display(token, new NotFoundScreen());
  420. }
  421. }
  422. }
  423. public static PatchSet.Id toPsId(Change.Id id, String psIdStr) {
  424. return new PatchSet.Id(id, psIdStr.equals("edit") ? 0 : Integer.parseInt(psIdStr));
  425. }
  426. private static void extension(String token) {
  427. ExtensionScreen view = new ExtensionScreen(skip(token));
  428. if (view.isFound()) {
  429. Gerrit.display(token, view);
  430. } else {
  431. Gerrit.display(token, new NotFoundScreen());
  432. }
  433. }
  434. private static void patch(
  435. String token,
  436. @Nullable Project.NameKey project,
  437. DiffObject base,
  438. Patch.Key id,
  439. DisplaySide side,
  440. int line,
  441. String panelType) {
  442. String panel = panelType;
  443. if (panel == null) {
  444. int c = token.lastIndexOf(',');
  445. panel = 0 <= c ? token.substring(c + 1) : "";
  446. }
  447. if ("".equals(panel) || /* DEPRECATED URL */ "cm".equals(panel)) {
  448. if (preferUnified()) {
  449. unified(token, project, base, id, side, line);
  450. } else {
  451. codemirror(token, base, project, id, side, line);
  452. }
  453. } else if ("sidebyside".equals(panel)) {
  454. codemirror(token, base, project, id, side, line);
  455. } else if ("unified".equals(panel)) {
  456. unified(token, project, base, id, side, line);
  457. } else if ("edit".equals(panel)) {
  458. if (!Patch.isMagic(id.get()) || Patch.COMMIT_MSG.equals(id.get())) {
  459. codemirrorForEdit(token, project, id, line);
  460. } else {
  461. Gerrit.display(token, new NotFoundScreen());
  462. }
  463. } else {
  464. Gerrit.display(token, new NotFoundScreen());
  465. }
  466. }
  467. private static boolean preferUnified() {
  468. return DiffView.UNIFIED_DIFF.equals(Gerrit.getUserPreferences().diffView())
  469. || (UserAgent.isPortrait() && UserAgent.isMobile());
  470. }
  471. private static void unified(
  472. final String token,
  473. final Project.NameKey project,
  474. final DiffObject base,
  475. final Patch.Key id,
  476. final DisplaySide side,
  477. final int line) {
  478. GWT.runAsync(
  479. new AsyncSplit(token) {
  480. @Override
  481. public void onSuccess() {
  482. Gerrit.display(
  483. token,
  484. new Unified(
  485. project, base, DiffObject.patchSet(id.getParentKey()), id.get(), side, line));
  486. }
  487. });
  488. }
  489. private static void codemirror(
  490. final String token,
  491. final DiffObject base,
  492. @Nullable final Project.NameKey project,
  493. final Patch.Key id,
  494. final DisplaySide side,
  495. final int line) {
  496. GWT.runAsync(
  497. new AsyncSplit(token) {
  498. @Override
  499. public void onSuccess() {
  500. Gerrit.display(
  501. token,
  502. new SideBySide(
  503. project, base, DiffObject.patchSet(id.getParentKey()), id.get(), side, line));
  504. }
  505. });
  506. }
  507. private static void codemirrorForEdit(
  508. final String token,
  509. @Nullable final Project.NameKey project,
  510. final Patch.Key id,
  511. final int line) {
  512. GWT.runAsync(
  513. new AsyncSplit(token) {
  514. @Override
  515. public void onSuccess() {
  516. Gerrit.display(token, new EditScreen(project, id, line));
  517. }
  518. });
  519. }
  520. private static void settings(String token) {
  521. GWT.runAsync(
  522. new AsyncSplit(token) {
  523. @Override
  524. public void onSuccess() {
  525. Gerrit.display(token, select());
  526. }
  527. private Screen select() {
  528. if (matchExact(SETTINGS, token)) {
  529. return new MyProfileScreen();
  530. }
  531. if (matchExact(SETTINGS_PREFERENCES, token)) {
  532. return new MyPreferencesScreen();
  533. }
  534. if (matchExact(SETTINGS_DIFF_PREFERENCES, token)) {
  535. return new MyDiffPreferencesScreen();
  536. }
  537. if (matchExact(SETTINGS_EDIT_PREFERENCES, token)) {
  538. return new MyEditPreferencesScreen();
  539. }
  540. if (matchExact(SETTINGS_PROJECTS, token)) {
  541. return new MyWatchedProjectsScreen();
  542. }
  543. if (matchExact(SETTINGS_CONTACT, token)) {
  544. return new MyContactInformationScreen();
  545. }
  546. if (matchExact(SETTINGS_SSHKEYS, token)) {
  547. return new MySshKeysScreen();
  548. }
  549. if (matchExact(SETTINGS_GPGKEYS, token) && Gerrit.info().gerrit().editGpgKeys()) {
  550. return new MyGpgKeysScreen();
  551. }
  552. if (matchExact(SETTINGS_WEBIDENT, token)) {
  553. return new MyIdentitiesScreen();
  554. }
  555. if (matchExact(SETTINGS_HTTP_PASSWORD, token)) {
  556. return new MyPasswordScreen();
  557. }
  558. if (matchExact(SETTINGS_OAUTH_TOKEN, token) && Gerrit.info().auth().isOAuth()) {
  559. return new MyOAuthTokenScreen();
  560. }
  561. if (matchExact(MY_GROUPS, token) || matchExact(SETTINGS_MYGROUPS, token)) {
  562. return new MyGroupsScreen();
  563. }
  564. if (matchExact(SETTINGS_AGREEMENTS, token)
  565. && Gerrit.info().auth().useContributorAgreements()) {
  566. return new MyAgreementsScreen();
  567. }
  568. if (matchExact(REGISTER, token)
  569. || matchExact("/register/", token)
  570. || matchExact("register", token)) {
  571. return new RegisterScreen(MINE);
  572. } else if (matchPrefix("/register/", token)) {
  573. return new RegisterScreen("/" + skip(token));
  574. }
  575. if (matchPrefix("/VE/", token) || matchPrefix("VE,", token)) {
  576. return new ValidateEmailScreen(skip(token));
  577. }
  578. if (matchExact(SETTINGS_NEW_AGREEMENT, token)) {
  579. return new NewAgreementScreen();
  580. }
  581. if (matchPrefix(SETTINGS_NEW_AGREEMENT + "/", token)) {
  582. return new NewAgreementScreen(skip(token));
  583. }
  584. if (matchPrefix(SETTINGS_EXTENSION, token)) {
  585. ExtensionSettingsScreen view = new ExtensionSettingsScreen(skip(token));
  586. if (view.isFound()) {
  587. return view;
  588. }
  589. return new NotFoundScreen();
  590. }
  591. return new NotFoundScreen();
  592. }
  593. });
  594. }
  595. private static void admin(String token) {
  596. GWT.runAsync(
  597. new AsyncSplit(token) {
  598. @Override
  599. public void onSuccess() {
  600. if (matchExact(ADMIN_GROUPS, token) || matchExact("/admin/groups", token)) {
  601. Gerrit.display(token, new GroupListScreen());
  602. } else if (matchPrefix(ADMIN_GROUPS, token)) {
  603. String rest = skip(token);
  604. if (rest.startsWith("?")) {
  605. Gerrit.display(token, new GroupListScreen(rest.substring(1)));
  606. } else {
  607. group();
  608. }
  609. } else if (matchPrefix("/admin/groups", token)) {
  610. String rest = skip(token);
  611. if (rest.startsWith("?")) {
  612. Gerrit.display(token, new GroupListScreen(rest.substring(1)));
  613. }
  614. } else if (matchExact(ADMIN_PROJECTS, token) || matchExact("/admin/projects", token)) {
  615. Gerrit.display(token, new ProjectListScreen());
  616. } else if (matchPrefix(ADMIN_PROJECTS, token)) {
  617. String rest = skip(token);
  618. if (rest.startsWith("?")) {
  619. Gerrit.display(token, new ProjectListScreen(rest.substring(1)));
  620. } else {
  621. Gerrit.display(token, selectProject());
  622. }
  623. } else if (matchPrefix("/admin/projects", token)) {
  624. String rest = skip(token);
  625. if (rest.startsWith("?")) {
  626. Gerrit.display(token, new ProjectListScreen(rest.substring(1)));
  627. }
  628. } else if (matchPrefix(ADMIN_PLUGINS, token) || matchExact("/admin/plugins", token)) {
  629. Gerrit.display(token, new PluginListScreen());
  630. } else if (matchExact(ADMIN_CREATE_PROJECT, token)
  631. || matchExact("/admin/create-project", token)) {
  632. Gerrit.display(token, new CreateProjectScreen());
  633. } else if (matchExact(ADMIN_CREATE_GROUP, token)
  634. || matchExact("/admin/create-group", token)) {
  635. Gerrit.display(token, new CreateGroupScreen());
  636. } else {
  637. Gerrit.display(token, new NotFoundScreen());
  638. }
  639. }
  640. private void group() {
  641. final String panel;
  642. final String group;
  643. if (matchPrefix("/admin/groups/uuid-", token)) {
  644. String p = skip(token);
  645. int c = p.indexOf(',');
  646. if (c < 0) {
  647. group = p;
  648. panel = null;
  649. } else {
  650. group = p.substring(0, c);
  651. panel = p.substring(c + 1);
  652. }
  653. } else if (matchPrefix(ADMIN_GROUPS, token)) {
  654. String p = skip(token);
  655. int c = p.indexOf(',');
  656. if (c < 0) {
  657. group = p;
  658. panel = null;
  659. } else {
  660. group = p.substring(0, c);
  661. panel = p.substring(c + 1);
  662. }
  663. } else {
  664. Gerrit.display(token, new NotFoundScreen());
  665. return;
  666. }
  667. GroupApi.getGroupDetail(
  668. group,
  669. new GerritCallback<GroupInfo>() {
  670. @Override
  671. public void onSuccess(GroupInfo group) {
  672. if (panel == null || panel.isEmpty()) {
  673. // The token does not say which group screen should be shown,
  674. // as default for internal groups show the members, as default
  675. // for external and system groups show the info screen (since
  676. // for external and system groups the members cannot be
  677. // shown in the web UI).
  678. //
  679. if (AccountGroup.isInternalGroup(group.getGroupUUID())) {
  680. String newToken = toGroup(group.getGroupId(), AccountGroupScreen.MEMBERS);
  681. Gerrit.display(newToken, new AccountGroupMembersScreen(group, newToken));
  682. } else {
  683. String newToken = toGroup(group.getGroupId(), AccountGroupScreen.INFO);
  684. Gerrit.display(newToken, new AccountGroupInfoScreen(group, newToken));
  685. }
  686. } else if (AccountGroupScreen.INFO.equals(panel)) {
  687. Gerrit.display(token, new AccountGroupInfoScreen(group, token));
  688. } else if (AccountGroupScreen.MEMBERS.equals(panel)) {
  689. Gerrit.display(token, new AccountGroupMembersScreen(group, token));
  690. } else if (AccountGroupScreen.AUDIT_LOG.equals(panel)) {
  691. Gerrit.display(token, new AccountGroupAuditLogScreen(group, token));
  692. } else {
  693. Gerrit.display(token, new NotFoundScreen());
  694. }
  695. }
  696. });
  697. }
  698. private Screen selectProject() {
  699. if (matchPrefix(ADMIN_PROJECTS, token)) {
  700. String rest = skip(token);
  701. int c = rest.lastIndexOf(',');
  702. if (c < 0) {
  703. return new ProjectInfoScreen(Project.NameKey.parse(rest));
  704. } else if (c == 0) {
  705. return new NotFoundScreen();
  706. }
  707. int q = rest.lastIndexOf('?');
  708. if (q > 0 && rest.lastIndexOf(',', q) > 0) {
  709. c = rest.substring(0, q - 1).lastIndexOf(',');
  710. }
  711. Project.NameKey k = Project.NameKey.parse(rest.substring(0, c));
  712. String panel = rest.substring(c + 1);
  713. if (ProjectScreen.INFO.equals(panel)) {
  714. return new ProjectInfoScreen(k);
  715. }
  716. if (ProjectScreen.BRANCHES.equals(panel)
  717. || matchPrefix(ProjectScreen.BRANCHES, panel)) {
  718. return new ProjectBranchesScreen(k);
  719. }
  720. if (ProjectScreen.TAGS.equals(panel) || matchPrefix(ProjectScreen.TAGS, panel)) {
  721. return new ProjectTagsScreen(k);
  722. }
  723. if (ProjectScreen.ACCESS.equals(panel)) {
  724. return new ProjectAccessScreen(k);
  725. }
  726. if (ProjectScreen.DASHBOARDS.equals(panel)) {
  727. return new ProjectDashboardsScreen(k);
  728. }
  729. }
  730. return new NotFoundScreen();
  731. }
  732. });
  733. }
  734. private static boolean matchExact(String want, String token) {
  735. return token.equals(want);
  736. }
  737. private static int prefixlen;
  738. private static boolean matchPrefix(String want, String token) {
  739. if (token.startsWith(want)) {
  740. prefixlen = want.length();
  741. return true;
  742. }
  743. return false;
  744. }
  745. private static String skip(String token) {
  746. return token.substring(prefixlen);
  747. }
  748. private abstract static class AsyncSplit implements RunAsyncCallback {
  749. private final boolean isReloadUi;
  750. protected final String token;
  751. protected AsyncSplit(String token) {
  752. this.isReloadUi = wasStartedByReloadUI;
  753. this.token = token;
  754. }
  755. @Override
  756. public final void onFailure(Throwable reason) {
  757. if (!isReloadUi && "HTTP download failed with status 404".equals(reason.getMessage())) {
  758. // The server was upgraded since we last download the main script,
  759. // so the pointers to the splits aren't valid anymore. Force the
  760. // page to reload itself and pick up the new code.
  761. //
  762. Gerrit.upgradeUI(token);
  763. } else {
  764. new ErrorDialog(reason).center();
  765. }
  766. }
  767. }
  768. private static void docSearch(String token) {
  769. GWT.runAsync(
  770. new AsyncSplit(token) {
  771. @Override
  772. public void onSuccess() {
  773. Gerrit.display(token, new DocScreen(skip(token)));
  774. }
  775. });
  776. }
  777. }