Ejemplo n.º 1
0
  @Override
  public void requestSuggestions(final Request request, final Callback callback) {
    if (current != null) {
      pending_req = request;
      pending_cb = callback;
      return;
    }
    current = callback;
    {
      final String this_query = request.getQuery();
      // Check if we can serve this from our local cache, without even talking
      // to the server.  This is possible if either of those is true:
      //   1. We've already seen this query recently.
      //   2. This new query precedes another one and the user basically just
      //      typed another letter, so if the new query is "less than" the last
      //      result we got from the server, we know we already cached the full
      //      range of results covering the new request.
      if ((last_query != null
              && last_query.compareTo(this_query) <= 0
              && this_query.compareTo(last_suggestion) < 0)
          || queries_seen.check(this_query)) {
        current = null;
        cache.requestSuggestions(request, callback);
        return;
      }
      last_query = this_query;
    }

    final RequestBuilder builder =
        new RequestBuilder(RequestBuilder.GET, SUGGEST_URL + type + "&q=" + last_query);
    try {
      builder.sendRequest(
          null,
          new RequestCallback() {
            public void onError(final com.google.gwt.http.client.Request r, final Throwable e) {
              current = null; // Something bad happened, drop the current request.
              if (pending_req != null) { // But if we have another waiting...
                requestSuggestions(pending_req, pending_cb); // ... try it now.
              }
            }

            // Need to use fully-qualified names as this class inherits already
            // from a pair of inner classes called Request / Response :-/
            public void onResponseReceived(
                final com.google.gwt.http.client.Request r,
                final com.google.gwt.http.client.Response response) {
              if (response.getStatusCode() == com.google.gwt.http.client.Response.SC_OK) {
                final JSONValue json = JSONParser.parse(response.getText());
                // In case this request returned nothing, we pretend the last
                // suggestion ended with the largest character possible, so we
                // won't send more requests to the server if the user keeps
                // adding extra characters.
                last_suggestion = last_query + "\377";
                if (json != null && json.isArray() != null) {
                  final JSONArray results = json.isArray();
                  final int n = Math.min(request.getLimit(), results.size());
                  for (int i = 0; i < n; i++) {
                    final JSONValue suggestion = results.get(i);
                    if (suggestion == null || suggestion.isString() == null) {
                      continue;
                    }
                    final String suggestionstr = suggestion.isString().stringValue();
                    last_suggestion = suggestionstr;
                    cache.add(suggestionstr);
                  }
                  // Is this response still relevant to what the requester wants?
                  if (requester.getText().startsWith(last_query)) {
                    cache.requestSuggestions(request, callback);
                    pending_req = null;
                    pending_cb = null;
                  }
                }
              }
              current = null; // Regardless of what happened above, this is done.
              if (pending_req != null) {
                final Request req = pending_req;
                final Callback cb = pending_cb;
                pending_req = null;
                pending_cb = null;
                requestSuggestions(req, cb);
              }
            }
          });
    } catch (RequestException ignore) {
    }
  }