com.google.api.explorer.client.base.http.crossdomain.CrossDomainRequestBuilder.java Source code

Java tutorial

Introduction

Here is the source code for com.google.api.explorer.client.base.http.crossdomain.CrossDomainRequestBuilder.java

Source

/*
 * Copyright (C) 2011 Google Inc.
 *
 * 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.api.explorer.client.base.http.crossdomain;

import com.google.api.explorer.client.base.ApiRequest;
import com.google.api.explorer.client.base.ApiResponse;
import com.google.common.annotations.VisibleForTesting;
import com.google.common.collect.Lists;
import com.google.gwt.core.client.Callback;
import com.google.gwt.core.client.JavaScriptObject;
import com.google.gwt.core.client.ScriptInjector;
import com.google.gwt.user.client.rpc.AsyncCallback;

import java.util.List;

/**
 * Builds requests to make to an cross-domain proxy iframe.
 *
 * <p>
 * This consists of adding a <script> tag to the page to load the JS library to
 * make cross-domain requests to the server.
 * </p>
 *
 * @author jasonhall@google.com (Jason Hall)
 */
public class CrossDomainRequestBuilder {

    private static final String JS_CLIENT_URL = "https://apis.google.com/js/client.js?onload=__apis_explorer_load_callback";

    private int timeoutMillis;
    private List<OutstandingRequest> outstandingRequests = Lists.newArrayList();

    private static native boolean isScriptLoaded() /*-{
                                                   return !!$wnd.googleapis && !!$wnd.googleapis.newHttpRequest;
                                                   }-*/;

    @VisibleForTesting
    protected static native void addLoadCallback(CrossDomainRequestBuilder builder) /*-{
                                                                                    $wnd.__apis_explorer_load_callback = function() {
                                                                                    builder.
                                                                                    @com.google.api.explorer.client.base.http.crossdomain.CrossDomainRequestBuilder::scriptFinishedLoading()();
                                                                                    };
                                                                                    }-*/;

    public void scriptFinishedLoading() {
        setBaseUrl();

        for (OutstandingRequest request : outstandingRequests) {
            doMakeRequest(request.request, request.xdr);
        }
    }

    public void setTimeoutMillis(int timeoutMillis) {
        this.timeoutMillis = timeoutMillis;
    }

    public CrossDomainRequest makeRequest(final ApiRequest request, AsyncCallback<ApiResponse> callback) {
        final CrossDomainRequest xdr = new CrossDomainRequest(callback, timeoutMillis);

        /** Adds a script tag to the page to load the JS library used to make requests. */
        if (!isScriptLoaded()) {
            outstandingRequests.add(new OutstandingRequest(request, xdr));

            // If we are the only request waiting, it is our responsibility to load the library.
            if (outstandingRequests.size() == 1) {
                addLoadCallback(this);
                ScriptInjector.fromUrl(JS_CLIENT_URL).setWindow(ScriptInjector.TOP_WINDOW)
                        .setCallback(new Callback<Void, Exception>() {
                            @Override
                            public void onFailure(Exception e) {
                                throw new RuntimeException(e);
                            }

                            @Override
                            public void onSuccess(Void arg0) {
                                // Intentionally blank, callback will be invoked automatically
                            }
                        }).inject();
            }
        } else {
            doMakeRequest(request, xdr);
        }
        return xdr;
    }

    private <T> void doMakeRequest(ApiRequest request, final CrossDomainRequest xdr) {
        JavaScriptObject jso = CrossDomainRequest.convertRequest(request);
        xdr.sendRequest(jso);
    }

    private static native void setBaseUrl() /*-{
                                            var proxy = @com.google.api.explorer.client.base.Config::baseUrl + '/static/proxy.html';
                                            $wnd.gapi.config.update('googleapis.config/proxy', proxy);
                                            }-*/;

    private static class OutstandingRequest {

        public final ApiRequest request;
        public final CrossDomainRequest xdr;

        public OutstandingRequest(ApiRequest request, CrossDomainRequest xdr) {
            this.request = request;
            this.xdr = xdr;
        }
    }
}