diff --git a/gerrit-gwtui/src/main/java/com/google/gerrit/client/admin/AccountGroupInfoScreen.java b/gerrit-gwtui/src/main/java/com/google/gerrit/client/admin/AccountGroupInfoScreen.java index f6c00025d9..12c364c184 100644 --- a/gerrit-gwtui/src/main/java/com/google/gerrit/client/admin/AccountGroupInfoScreen.java +++ b/gerrit-gwtui/src/main/java/com/google/gerrit/client/admin/AccountGroupInfoScreen.java @@ -21,7 +21,7 @@ import com.google.gerrit.client.groups.GroupInfo; import com.google.gerrit.client.rpc.GerritCallback; import com.google.gerrit.client.ui.AccountGroupSuggestOracle; import com.google.gerrit.client.ui.OnEditEnabler; -import com.google.gerrit.client.ui.RPCSuggestOracle; +import com.google.gerrit.client.ui.RemoteSuggestOracle; import com.google.gerrit.client.ui.SmallHeading; import com.google.gerrit.reviewdb.client.AccountGroup; import com.google.gwt.event.dom.client.ClickEvent; @@ -120,7 +120,7 @@ public class AccountGroupInfoScreen extends AccountGroupScreen { ownerTxtBox = new NpTextBox(); ownerTxtBox.setVisibleLength(60); final AccountGroupSuggestOracle accountGroupOracle = new AccountGroupSuggestOracle(); - ownerTxt = new SuggestBox(new RPCSuggestOracle( + ownerTxt = new SuggestBox(new RemoteSuggestOracle( accountGroupOracle), ownerTxtBox); ownerTxt.setStyleName(Gerrit.RESOURCES.css().groupOwnerTextBox()); ownerPanel.add(ownerTxt); diff --git a/gerrit-gwtui/src/main/java/com/google/gerrit/client/admin/GroupReferenceBox.java b/gerrit-gwtui/src/main/java/com/google/gerrit/client/admin/GroupReferenceBox.java index a76638e04a..1c9f73dbab 100644 --- a/gerrit-gwtui/src/main/java/com/google/gerrit/client/admin/GroupReferenceBox.java +++ b/gerrit-gwtui/src/main/java/com/google/gerrit/client/admin/GroupReferenceBox.java @@ -15,7 +15,7 @@ package com.google.gerrit.client.admin; import com.google.gerrit.client.ui.AccountGroupSuggestOracle; -import com.google.gerrit.client.ui.RPCSuggestOracle; +import com.google.gerrit.client.ui.RemoteSuggestOracle; import com.google.gerrit.common.data.GroupReference; import com.google.gerrit.reviewdb.client.Project; import com.google.gwt.editor.client.LeafValueEditor; @@ -53,7 +53,7 @@ public class GroupReferenceBox extends Composite implements textBox = new NpTextBox(); oracle = new AccountGroupSuggestOracle(); suggestBox = new SuggestBox( // - new RPCSuggestOracle(oracle), // + new RemoteSuggestOracle(oracle), // textBox, // suggestions); initWidget(suggestBox); diff --git a/gerrit-gwtui/src/main/java/com/google/gerrit/client/change/ReviewerSuggestOracle.java b/gerrit-gwtui/src/main/java/com/google/gerrit/client/change/ReviewerSuggestOracle.java index 904e43a34c..7af247a233 100644 --- a/gerrit-gwtui/src/main/java/com/google/gerrit/client/change/ReviewerSuggestOracle.java +++ b/gerrit-gwtui/src/main/java/com/google/gerrit/client/change/ReviewerSuggestOracle.java @@ -25,9 +25,9 @@ import com.google.gerrit.client.ui.SuggestAfterTypingNCharsOracle; import com.google.gerrit.reviewdb.client.Change; import com.google.gwt.core.client.JavaScriptObject; import com.google.gwt.core.client.JsArray; -import com.google.gwt.user.client.ui.SuggestOracle; import java.util.ArrayList; +import java.util.Collections; import java.util.List; /** REST API based suggestion Oracle for reviewers. */ @@ -35,17 +35,22 @@ public class ReviewerSuggestOracle extends SuggestAfterTypingNCharsOracle { private Change.Id changeId; @Override - protected void _onRequestSuggestions(final Request req, final Callback callback) { - ChangeApi.suggestReviewers(changeId.get(), req.getQuery(), - req.getLimit()).get(new GerritCallback>() { + protected void _onRequestSuggestions(final Request req, final Callback cb) { + ChangeApi.suggestReviewers(changeId.get(), req.getQuery(), req.getLimit()) + .get(new GerritCallback>() { @Override public void onSuccess(JsArray result) { - final List r = - new ArrayList<>(result.length()); - for (final SuggestReviewerInfo reviewer : Natives.asList(result)) { + List r = new ArrayList<>(result.length()); + for (SuggestReviewerInfo reviewer : Natives.asList(result)) { r.add(new RestReviewerSuggestion(reviewer)); } - callback.onSuggestionsReady(req, new Response(r)); + cb.onSuggestionsReady(req, new Response(r)); + } + + @Override + public void onFailure(Throwable err) { + List r = Collections.emptyList(); + cb.onSuggestionsReady(req, new Response(r)); } }); } @@ -54,7 +59,7 @@ public class ReviewerSuggestOracle extends SuggestAfterTypingNCharsOracle { this.changeId = changeId; } - private static class RestReviewerSuggestion implements SuggestOracle.Suggestion { + private static class RestReviewerSuggestion implements Suggestion { private final SuggestReviewerInfo reviewer; RestReviewerSuggestion(final SuggestReviewerInfo reviewer) { diff --git a/gerrit-gwtui/src/main/java/com/google/gerrit/client/change/Reviewers.java b/gerrit-gwtui/src/main/java/com/google/gerrit/client/change/Reviewers.java index 48907e2ef1..091cf66852 100644 --- a/gerrit-gwtui/src/main/java/com/google/gerrit/client/change/Reviewers.java +++ b/gerrit-gwtui/src/main/java/com/google/gerrit/client/change/Reviewers.java @@ -28,6 +28,7 @@ import com.google.gerrit.client.rpc.NativeMap; import com.google.gerrit.client.rpc.NativeString; import com.google.gerrit.client.rpc.Natives; import com.google.gerrit.client.ui.HintTextBox; +import com.google.gerrit.client.ui.RemoteSuggestOracle; import com.google.gerrit.reviewdb.client.Change; import com.google.gwt.core.client.GWT; import com.google.gwt.core.client.JavaScriptObject; @@ -82,7 +83,9 @@ public class Reviewers extends Composite { Reviewers() { reviewerSuggestOracle = new ReviewerSuggestOracle(); nameTxtBox = new HintTextBox(); - suggestBox = new SuggestBox(reviewerSuggestOracle, nameTxtBox); + suggestBox = new SuggestBox( + new RemoteSuggestOracle(reviewerSuggestOracle), + nameTxtBox); initWidget(uiBinder.createAndBindUi(this)); nameTxtBox.setVisibleLength(55); diff --git a/gerrit-gwtui/src/main/java/com/google/gerrit/client/ui/AddMemberBox.java b/gerrit-gwtui/src/main/java/com/google/gerrit/client/ui/AddMemberBox.java index 80d4a7bcd0..11e7b13494 100644 --- a/gerrit-gwtui/src/main/java/com/google/gerrit/client/ui/AddMemberBox.java +++ b/gerrit-gwtui/src/main/java/com/google/gerrit/client/ui/AddMemberBox.java @@ -42,7 +42,7 @@ public class AddMemberBox extends Composite { addPanel = new FlowPanel(); addMember = new Button(buttonLabel); nameTxtBox = new HintTextBox(); - nameTxt = new SuggestBox(new RPCSuggestOracle( + nameTxt = new SuggestBox(new RemoteSuggestOracle( suggestOracle), nameTxtBox); nameTxt.setStyleName(Gerrit.RESOURCES.css().addMemberTextBox()); diff --git a/gerrit-gwtui/src/main/java/com/google/gerrit/client/ui/RPCSuggestOracle.java b/gerrit-gwtui/src/main/java/com/google/gerrit/client/ui/RPCSuggestOracle.java deleted file mode 100644 index be58080bc5..0000000000 --- a/gerrit-gwtui/src/main/java/com/google/gerrit/client/ui/RPCSuggestOracle.java +++ /dev/null @@ -1,59 +0,0 @@ -// Copyright (C) 2010 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.ui; - -import com.google.gwt.user.client.ui.SuggestOracle; - -/** This class will proxy SuggestOracle requests to another SuggestOracle - * while keeping track of the latest request. Any repsonse that belongs - * to a request which is not the latest request will be dropped to prevent - * invalid deliveries. - */ - -public class RPCSuggestOracle extends SuggestOracle { - - private SuggestOracle oracle; - private SuggestOracle.Request request; - private SuggestOracle.Callback callback; - private SuggestOracle.Callback myCallback = new SuggestOracle.Callback() { - @Override - public void onSuggestionsReady(SuggestOracle.Request req, - SuggestOracle.Response response) { - if (request == req) { - callback.onSuggestionsReady(req, response); - request = null; - callback = null; - } - } - }; - - - public RPCSuggestOracle(SuggestOracle ora) { - oracle = ora; - } - - @Override - public void requestSuggestions(SuggestOracle.Request req, - SuggestOracle.Callback cb) { - request = req; - callback = cb; - oracle.requestSuggestions(req, myCallback); - } - - @Override - public boolean isDisplayStringHTML() { - return oracle.isDisplayStringHTML(); - } -} diff --git a/gerrit-gwtui/src/main/java/com/google/gerrit/client/ui/RemoteSuggestOracle.java b/gerrit-gwtui/src/main/java/com/google/gerrit/client/ui/RemoteSuggestOracle.java new file mode 100644 index 0000000000..93039ad1f2 --- /dev/null +++ b/gerrit-gwtui/src/main/java/com/google/gerrit/client/ui/RemoteSuggestOracle.java @@ -0,0 +1,79 @@ +// Copyright (C) 2010 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.ui; + +import com.google.gwt.user.client.ui.SuggestOracle; + +/** + * Delegates to a slow SuggestOracle, such as a remote server API. + *

+ * A response is only supplied to the UI if no requests were made after the + * oracle begin that request. + *

+ * When a request is made while the delegate is still processing a prior request + * all intermediate requests are discarded and the most recent request is + * queued. The pending request's response is discarded and the most recent + * request is started. + */ +public class RemoteSuggestOracle extends SuggestOracle { + private final SuggestOracle oracle; + private Query query; + + public RemoteSuggestOracle(SuggestOracle src) { + oracle = src; + } + + @Override + public void requestSuggestions(Request req, Callback cb) { + Query q = new Query(req, cb); + if (query == null) { + q.start(); + } + query = q; + } + + @Override + public boolean isDisplayStringHTML() { + return oracle.isDisplayStringHTML(); + } + + private class Query implements Callback { + final Request request; + final Callback callback; + + Query(Request req, Callback cb) { + request = req; + callback = cb; + } + + void start() { + oracle.requestSuggestions(request, this); + } + + @Override + public void onSuggestionsReady(Request req, Response res) { + if (query == this) { + // No new request was started while this query was running. + // Propose this request's response as the suggestions. + query = null; + callback.onSuggestionsReady(req, res); + } else { + // Another query came in while this one was running. Skip + // this response and start the most recent query. + query.start(); + } + } + } +}