GWT UI: Use ChangeQuery endpoint if project is null

We will soon start to deprecate all change ID patterns except
project~number. Therefore, if the user provided a URL without a project,
we use the query endpoint instead of just calling /changes/<value> to
ensure supplying an old ID as part of the URL will continue to work even
when old IDs are removed from the UI.

Change-Id: Ibe822721046a65f6daf82645b4efce676a420d3e
diff --git a/gerrit-gwtui/src/main/java/com/google/gerrit/client/change/ChangeScreen.java b/gerrit-gwtui/src/main/java/com/google/gerrit/client/change/ChangeScreen.java
index 039948d..b57545b 100644
--- a/gerrit-gwtui/src/main/java/com/google/gerrit/client/change/ChangeScreen.java
+++ b/gerrit-gwtui/src/main/java/com/google/gerrit/client/change/ChangeScreen.java
@@ -26,6 +26,7 @@
 import com.google.gerrit.client.changes.ChangeApi;
 import com.google.gerrit.client.changes.ChangeList;
 import com.google.gerrit.client.changes.CommentInfo;
+import com.google.gerrit.client.changes.QueryScreen;
 import com.google.gerrit.client.changes.RevisionInfoCache;
 import com.google.gerrit.client.changes.StarredChanges;
 import com.google.gerrit.client.changes.Util;
@@ -282,11 +283,46 @@
   @Override
   protected void onLoad() {
     super.onLoad();
+    loadChangeScreen();
+  }
+
+  private void loadChangeScreen() {
+    if (project == null) {
+      // Load the project if it is not 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.
+      String query = "change:" + changeId.get();
+      ChangeList.query(
+          query,
+          Collections.emptySet(),
+          new AsyncCallback<ChangeList>() {
+            @Override
+            public void onSuccess(ChangeList result) {
+              if (result.length() == 0) {
+                Gerrit.display(getToken(), new NotFoundScreen());
+              } else if (result.length() > 1) {
+                Gerrit.display(PageLinks.toChangeQuery(query), QueryScreen.forQuery(query));
+              } else {
+                // Initialize current screen with newly obtained project
+                project = result.get(0).projectNameKey();
+                loadChangeScreen();
+              }
+            }
+
+            @Override
+            public void onFailure(Throwable caught) {
+              GerritCallback.showFailure(caught);
+            }
+          });
+
+      return;
+    }
     CallbackGroup group = new CallbackGroup();
     if (Gerrit.isSignedIn()) {
       ChangeList.query(
           "change:" + changeId.get() + " has:draft",
-          Collections.<ListChangesOption>emptySet(),
+          Collections.emptySet(),
           group.add(
               new AsyncCallback<ChangeList>() {
                 @Override
@@ -318,15 +354,6 @@
               @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();