Revision: 7267
Author: [email protected]
Date: Mon Dec  7 16:46:41 2009
Log: Adding retries for async reloading.

http://code.google.com/p/google-web-toolkit/source/detail?r=7267

Added:
   
/branches/snapshot-2009.10.23-r6446/user/src/com/google/gwt/core/AsyncFragmentLoader.gwt.xml
   
/branches/snapshot-2009.10.23-r6446/user/src/com/google/gwt/core/client/impl/XhrLoadingStrategy.java
   
/branches/snapshot-2009.10.23-r6446/user/test/com/google/gwt/core/client/impl/XhrLoadingStrategyTest.java
Modified:
   
/branches/snapshot-2009.10.23-r6446/user/src/com/google/gwt/core/Core.gwt.xml
   
/branches/snapshot-2009.10.23-r6446/user/src/com/google/gwt/core/client/impl/AsyncFragmentLoader.java
   
/branches/snapshot-2009.10.23-r6446/user/test/com/google/gwt/core/CoreSuite.java

=======================================
--- /dev/null
+++  
/branches/snapshot-2009.10.23-r6446/user/src/com/google/gwt/core/AsyncFragmentLoader.gwt.xml
     
Mon Dec  7 16:46:41 2009
@@ -0,0 +1,29 @@
+<!--                                                                         
-->
+<!-- Copyright 2008 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   -->
+<!-- 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. License for the specific language governing permissions  
and   -->
+<!-- limitations under the  
License.                                         -->
+
+<!-- Types associated with GWT.runAsync() and its fragment  
loader           -->
+<module>
+
+  <replace-with class="com.google.gwt.core.client.impl.XhrLoadingStrategy">
+    <when-type-is
+         
class="com.google.gwt.core.client.impl.AsyncFragmentLoader.LoadingStrategy"/>
+  </replace-with>
+
+  <replace-with
+       
class="com.google.gwt.core.client.impl.AsyncFragmentLoader.StandardLogger">
+    <when-type-is
+         
class="com.google.gwt.core.client.impl.AsyncFragmentLoader.Logger"/>
+  </replace-with>
+
+</module>
=======================================
--- /dev/null
+++  
/branches/snapshot-2009.10.23-r6446/user/src/com/google/gwt/core/client/impl/XhrLoadingStrategy.java
     
Mon Dec  7 16:46:41 2009
@@ -0,0 +1,240 @@
+/*
+ * Copyright 2009 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.gwt.core.client.impl;
+
+import  
com.google.gwt.core.client.impl.AsyncFragmentLoader.HttpDownloadFailure;
+import  
com.google.gwt.core.client.impl.AsyncFragmentLoader.HttpInstallFailure;
+import  
com.google.gwt.core.client.impl.AsyncFragmentLoader.LoadErrorHandler;
+import com.google.gwt.core.client.impl.AsyncFragmentLoader.LoadingStrategy;
+import com.google.gwt.xhr.client.ReadyStateChangeHandler;
+import com.google.gwt.xhr.client.XMLHttpRequest;
+
+/**
+ * The standard loading strategy used in a web browser.
+ */
+public class XhrLoadingStrategy implements LoadingStrategy {
+
+  /**
+   * A {...@link MockableXMLHttpRequest} that is really just a vanilla
+   * XMLHttpRequest.  This wrapper (and thus {...@code  
MockableXMLHttpRequest) is
+   * needed because so much of {...@link XMLHttpRequest} is final, which in  
turn
+   * is because it extends {...@code JavaScriptObject} and is subject to its
+   * restrictions.
+   *
+   * It is important that these methods be simple enough to be inlined  
away.
+   */
+  class DelegatingXMLHttpRequest implements MockableXMLHttpRequest {
+    private final XMLHttpRequest delegate;
+
+    public DelegatingXMLHttpRequest(XMLHttpRequest xmlHttpRequest) {
+      delegate = xmlHttpRequest;
+    }
+
+    public void clearOnReadyStateChange() {
+      delegate.clearOnReadyStateChange();
+    }
+
+    public int getReadyState() {
+      return delegate.getReadyState();
+    }
+
+    public String getResponseText() {
+      return delegate.getResponseText();
+    }
+
+    public int getStatus() {
+      return delegate.getStatus();
+    }
+
+    public String getStatusText() {
+      return delegate.getStatusText();
+    }
+
+    public void open(String method, String url) {
+      delegate.open(method, url);
+    }
+
+    public void send() {
+      delegate.send();
+    }
+
+    public void setOnReadyStateChange(ReadyStateChangeHandler handler) {
+      delegate.setOnReadyStateChange(handler);
+    }
+
+    public void setRequestHeader(String header, String value) {
+      delegate.setRequestHeader(header, value);
+    }
+  }
+
+  /**
+   * Delegates to the real XMLHttpRequest, except in test when we make a  
mock
+   * to jump through error/retry hoops.
+   */
+  interface MockableXMLHttpRequest {
+    void clearOnReadyStateChange();
+    int getReadyState();
+    String getResponseText();
+    int getStatus();
+    String getStatusText();
+    void open(String method, String url);
+    void send();
+    void setOnReadyStateChange(ReadyStateChangeHandler handler);
+    void setRequestHeader(String header, String value);
+  }
+
+  /**
+   * Since LoadingStrategy must support concurrent requests, including  
figuring
+   * which is which in the onLoadError handling, we need to keep track of  
this
+   * data for each outstanding request, which we index by xhr object.
+   */
+  protected class RequestData {
+    String url;
+    int retryCount;
+    LoadErrorHandler errorHandler = null;
+
+    public RequestData(String url, LoadErrorHandler errorHandler) {
+      this.url = url;
+      this.errorHandler = errorHandler;
+      this.retryCount = 0;
+    }
+  }
+
+  static final String HTTP_GET = "GET";
+
+  /**
+   * Some UA's like Safari will have a "0" status code when loading from  
file:
+   * URLs. Additionally, the "0" status code is used sometimes if the  
server
+   * does not respond, e.g. if there is a connection refused.
+   */
+  static final int HTTP_STATUS_NON_HTTP = 0;
+
+  static final int HTTP_STATUS_OK = 200;
+
+  /**
+   * For error logging, max length of fragment response text to include in
+   * failed-to-install exception message.
+   */
+  private static final int MAX_LOG_LENGTH = 200;
+
+  /**
+   * Number of retry attempts for a single fragment.  If a fragment  
download
+   * fails, we try again this many times before "really" failing out to  
user
+   * error-handling code.  If a fragment downloads but doesn't install, we
+   * don't retry at all.
+   */
+  private static final int MAX_RETRY_COUNT = 3;
+
+  public void startLoadingFragment(int fragment,
+      final LoadErrorHandler loadErrorHandler) {
+    String url = gwtStartLoadingFragment(fragment, loadErrorHandler);
+    if (url == null) {
+      // The download has already started; nothing more to do
+      return;
+    }
+
+    RequestData request = new RequestData(url, loadErrorHandler);
+    tryLoad(request);
+  }
+
+  /**
+   * Overridable for tests.
+   */
+  protected MockableXMLHttpRequest createXhr() {
+    return new DelegatingXMLHttpRequest(XMLHttpRequest.create());
+  }
+
+  /**
+   * Call the linker-supplied <code>__gwtInstallCode</code> method. See the
+   * {...@link AsyncFragmentLoader class comment} for more details.
+   */
+  protected native void gwtInstallCode(String text) /*-{
+    __gwtInstallCode(text);
+  }-*/;
+
+  /**
+   * Call the linker-supplied __gwtStartLoadingFragment function. It should
+   * either start the download and return null or undefined, or it should
+   * return a URL that should be downloaded to get the code. If it starts  
the
+   * download itself, it can synchronously load it, e.g. from cache, if  
that
+   * makes sense.
+   */
+  protected native String gwtStartLoadingFragment(int fragment,
+      LoadErrorHandler loadErrorHandler) /*-{
+    function loadFailed(e) {
+       
loaderrorhandl...@com.google.gwt.core.client.impl.asyncfragmentloader$loaderrorhandler::loadFailed(Ljava/lang/Throwable;)(e);
+    }
+    return __gwtStartLoadingFragment(fragment, loadFailed);
+  }-*/;
+
+  /**
+   * Error recovery from loading or installing code.
+   * @param request the requestData of this request
+   * @param e exception of the error
+   * @param mayRetry {...@code true} if retrying might be helpful
+   */
+  protected void onLoadError(RequestData request, Throwable e, boolean  
mayRetry) {
+    if (mayRetry) {
+      request.retryCount++;
+      if (request.retryCount < MAX_RETRY_COUNT) {
+        tryLoad(request);
+        return;
+      }
+    }
+    request.errorHandler.loadFailed(e);
+  }
+
+  /**
+   * Makes a single load-and-install attempt.
+   */
+  protected void tryLoad(final RequestData request) {
+    final MockableXMLHttpRequest xhr = createXhr();
+
+    xhr.open(HTTP_GET, request.url);
+    if (request.retryCount > 0) {
+      // disable caching if we have to retry; one cause could be bad cache
+      xhr.setRequestHeader("Cache-Control", "no-cache");
+    }
+
+    xhr.setOnReadyStateChange(new ReadyStateChangeHandler() {
+      public void onReadyStateChange(XMLHttpRequest ignored) {
+        if (xhr.getReadyState() == XMLHttpRequest.DONE) {
+          xhr.clearOnReadyStateChange();
+          if ((xhr.getStatus() == HTTP_STATUS_OK || xhr.getStatus() ==  
HTTP_STATUS_NON_HTTP)
+              && xhr.getResponseText() != null
+              && xhr.getResponseText().length() != 0) {
+            try {
+              gwtInstallCode(xhr.getResponseText());
+            } catch (RuntimeException e) {
+              String textIntro = xhr.getResponseText();
+              if (textIntro != null && textIntro.length() >  
MAX_LOG_LENGTH) {
+                textIntro = textIntro.substring(0, MAX_LOG_LENGTH) + "...";
+              }
+              onLoadError(request,
+                  new HttpInstallFailure(request.url, textIntro, e),  
false);
+            }
+          } else {
+            onLoadError(request,
+                new HttpDownloadFailure(request.url, xhr.getStatus(),
+                    xhr.getStatusText()), true);
+          }
+        }
+      }
+    });
+
+    xhr.send();
+  }
+}
=======================================
--- /dev/null
+++  
/branches/snapshot-2009.10.23-r6446/user/test/com/google/gwt/core/client/impl/XhrLoadingStrategyTest.java
        
Mon Dec  7 16:46:41 2009
@@ -0,0 +1,277 @@
+/*
+ * Copyright 2009 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.gwt.core.client.impl;
+
+import  
com.google.gwt.core.client.impl.AsyncFragmentLoader.LoadErrorHandler;
+import  
com.google.gwt.core.client.impl.XhrLoadingStrategy.MockableXMLHttpRequest;
+import com.google.gwt.xhr.client.ReadyStateChangeHandler;
+
+import junit.framework.TestCase;
+
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.HashMap;
+
+/**
+ * Tests the default loading strategy and its retry behavior.
+ */
+public class XhrLoadingStrategyTest extends TestCase {
+
+  static class MockXhr implements MockableXMLHttpRequest {
+    public static final String SUCCESSFUL_RESPONSE_TEXT =
+        "successful response text";
+    public static final String INSTALL_FAILED_RESPONSE_TEXT =
+        "install failed response text";
+
+    private ReadyStateChangeHandler handler;
+    private int httpStatus;
+    private int state;
+    private String statusText;
+    private String text;
+    private HashMap<String,String> headers;
+
+    public MockXhr(int status, String statusText, boolean loads,
+        boolean installs, String... headers) {
+      this.httpStatus = status;
+      this.statusText = statusText;
+      if (installs) {
+        text = SUCCESSFUL_RESPONSE_TEXT;
+      } else if (loads) {
+        text = INSTALL_FAILED_RESPONSE_TEXT;
+      } else {
+        text = null;
+      }
+      handler = null;
+      state = 0;
+      assert headers.length % 2 == 0;
+      this.headers = new HashMap<String,String>();
+      for (int i = 0; i < headers.length; i += 2) {
+        this.headers.put(headers[i], headers[i + 1]);
+      }
+    }
+
+    public void clearOnReadyStateChange() {
+      handler = null;
+    }
+
+    public int getReadyState() {
+      return state;
+    }
+
+    public String getResponseText() {
+      return state > 3 ? text : null;
+    }
+
+    public int getStatus() {
+      return state > 1 ? httpStatus : 0;
+    }
+
+    public String getStatusText() {
+      return state > 1 ? statusText : null;
+    }
+
+    public void open(String method, String url) {
+      state = 1;
+    }
+
+    public void send() {
+      state = 4;
+      if (headers.size() != 0) {
+        throw new IllegalStateException("not all expected headers set");
+      }
+      if (handler != null) {
+        // TODO(fabbott): this is brittle, but I don't have a better idea.
+        // The problem is that onReadyStateChange takes a REAL  
XMLHttpRequest,
+        // which I can't mock because it's all final.  I don't want to open
+        // ReadyStateChangeHandler's long-standing API to let it take a
+        // non-real XMLHttpRequest, just for my wee test here, so instead I
+        // admit that null works 'cause the handler won't *use* its  
argument.
+        handler.onReadyStateChange(null);
+      }
+    }
+
+    public void setOnReadyStateChange(ReadyStateChangeHandler handler) {
+      this.handler = handler;
+    }
+
+    public void setRequestHeader(String header, String value) {
+      String val = headers.get(header);
+      if (val == null) {
+        throw new IllegalArgumentException("set of unexpected header "
+            + header);
+      }
+      if (!val.equals(value)) {
+        throw new IllegalArgumentException("set of header "
+            + header + " to unexpected value " + value + ", not " + val);
+      }
+      headers.remove(header);
+    }
+  }
+
+  /**
+   * {...@link XhrLoadingStrategy}, but without actual live XHRs.
+   */
+  static class MockXhrLoadingStrategy extends XhrLoadingStrategy {
+    private static final String FRAGMENT_URL  
= "http://nowhere.net/fragment";;
+    private ArrayList<MockXhr> xhrs;
+
+    public MockXhrLoadingStrategy(MockXhr... input) {
+      xhrs = new ArrayList<MockXhr>(Arrays.asList(input));
+    }
+
+    public void assertDone() {
+      if (xhrs.size() != 0) {
+        throw new IllegalStateException("leftover createXhr() data" +
+        " (too few load retries?)");
+      }
+    }
+
+    /**
+     * Test stub; install succeeds unless text says otherwise.
+     */
+    @Override
+    protected void gwtInstallCode(String text) {
+      if (MockXhr.INSTALL_FAILED_RESPONSE_TEXT.equals(text)) {
+        throw new RuntimeException(text);
+      }
+    }
+
+    /**
+     * Test stub; bypass the JSNI, but we're returning a (mock) URL.
+     */
+    @Override
+    protected String gwtStartLoadingFragment(int fragment,
+        LoadErrorHandler loadErrorHandler) {
+      return FRAGMENT_URL;
+    }
+
+    @Override
+    protected MockableXMLHttpRequest createXhr() {
+      if (xhrs.size() == 0) {
+        throw new IllegalStateException("createXhr() underflow" +
+            " (too many load retries?)");
+      }
+      return xhrs.remove(0);
+    }
+  }
+
+  /**
+   * Basic succeeds-on-first-try case.
+   */
+  public void testNoRetrySucceeds() {
+    MockXhrLoadingStrategy xls = new MockXhrLoadingStrategy(
+        new MockXhr(200, "200 Ok", true, true));
+    xls.startLoadingFragment(1, new LoadErrorHandler() {
+      public void loadFailed(Throwable reason) {
+        fail();
+      }
+    });
+    xls.assertDone();
+  }
+
+  /**
+   * Fails irrevocably on first try; doesn't retry.
+   */
+  public void testNoRetryFails() {
+    final boolean loadFailedCalled[] = new boolean[1];
+    loadFailedCalled[0] = false;
+    MockXhrLoadingStrategy xls = new MockXhrLoadingStrategy(
+        new MockXhr(200, "Ok", true, false));
+    xls.startLoadingFragment(1, new LoadErrorHandler() {
+      public void loadFailed(Throwable reason) {
+        loadFailedCalled[0] = true;
+      }
+    });
+    xls.assertDone();
+    if (!loadFailedCalled[0]) {
+      fail("should have failed to install, but didn't");
+    }
+  }
+
+  /**
+   * Needs some retries, but succeeds.
+   */
+  public void testRetrySucceeds() {
+    MockXhrLoadingStrategy xls = new MockXhrLoadingStrategy(
+        new MockXhr(0, "Could not connect", false, false),
+        new MockXhr(200, "Ok", true, true, "Cache-Control", "no-cache"));
+    xls.startLoadingFragment(1, new LoadErrorHandler() {
+      public void loadFailed(Throwable reason) {
+        fail();
+      }
+    });
+    xls.assertDone();
+  }
+
+  /**
+   * Needs retries, and never succeeds.
+   */
+  public void testRetryFails() {
+    final boolean loadFailedCalled[] = new boolean[1];
+    loadFailedCalled[0] = false;
+    MockXhrLoadingStrategy xls = new MockXhrLoadingStrategy(
+        new MockXhr(0, "Could not connect", false, false),
+        new MockXhr(0, "Could not connect", false, false,
+            "Cache-Control", "no-cache"),
+        new MockXhr(0, "Could not connect", false, false,
+            "Cache-Control", "no-cache"));
+    xls.startLoadingFragment(1, new LoadErrorHandler() {
+      public void loadFailed(Throwable reason) {
+        loadFailedCalled[0] = true;
+      }
+    });
+    xls.assertDone();
+    if (!loadFailedCalled[0]) {
+      fail("should have failed to install, but didn't");
+    }
+  }
+
+  /**
+   * A bizarre case we've seen in the wild...
+   */
+  public void testNull200Case() {
+    MockXhrLoadingStrategy xls = new MockXhrLoadingStrategy(
+        new MockXhr(200, "Ok", false, false),
+        new MockXhr(200, "Ok", false, false,
+            "Cache-Control", "no-cache"),
+        new MockXhr(200, "Ok", true, true,
+            "Cache-Control", "no-cache"));
+    xls.startLoadingFragment(1, new LoadErrorHandler() {
+      public void loadFailed(Throwable reason) {
+        fail();
+      }
+    });
+    xls.assertDone();
+  }
+
+  /**
+   * Check some HTTP status codes....
+   */
+  public void testRetryCodes() {
+    MockXhrLoadingStrategy xls = new MockXhrLoadingStrategy(
+        new MockXhr(500, "Server Error", false, false),
+        new MockXhr(404, "Not Found", false, false,
+            "Cache-Control", "no-cache"),
+        new MockXhr(200, "Ok", true, true,
+            "Cache-Control", "no-cache"));
+    xls.startLoadingFragment(1, new LoadErrorHandler() {
+      public void loadFailed(Throwable reason) {
+        fail();
+      }
+    });
+    xls.assertDone();
+  }
+}
=======================================
---  
/branches/snapshot-2009.10.23-r6446/user/src/com/google/gwt/core/Core.gwt.xml   
 
Mon Aug 17 09:47:48 2009
+++  
/branches/snapshot-2009.10.23-r6446/user/src/com/google/gwt/core/Core.gwt.xml   
 
Mon Dec  7 16:46:41 2009
@@ -23,6 +23,7 @@
    <inherits name="com.google.gwt.xhr.XMLHttpRequest" />
    <inherits name="com.google.gwt.core.CompilerParameters" />
    <inherits name="com.google.gwt.core.EmulateJsStack" />
+  <inherits name="com.google.gwt.core.AsyncFragmentLoader" />

    <super-source path="translatable" />

@@ -37,4 +38,5 @@

    <add-linker name="soycReport" />
    <add-linker name="symbolMaps" />
+
  </module>
=======================================
---  
/branches/snapshot-2009.10.23-r6446/user/src/com/google/gwt/core/client/impl/AsyncFragmentLoader.java
    
Wed Oct 21 13:20:55 2009
+++  
/branches/snapshot-2009.10.23-r6446/user/src/com/google/gwt/core/client/impl/AsyncFragmentLoader.java
    
Mon Dec  7 16:46:41 2009
@@ -16,8 +16,6 @@
  package com.google.gwt.core.client.impl;

  import com.google.gwt.core.client.JavaScriptObject;
-import com.google.gwt.xhr.client.ReadyStateChangeHandler;
-import com.google.gwt.xhr.client.XMLHttpRequest;

  import java.util.ArrayList;
  import java.util.HashMap;
@@ -153,11 +151,12 @@
    /**
     * An exception indicating than at HTTP download failed.
     */
-  private static class HttpDownloadFailure extends RuntimeException {
+  static class HttpDownloadFailure extends RuntimeException {
      private final int statusCode;

-    public HttpDownloadFailure(int statusCode) {
-      super("HTTP download failed with status " + statusCode);
+    public HttpDownloadFailure(String url, int statusCode, String  
statusText) {
+      super("Download of " + url + " failed with status " + statusCode  
+ "("
+          + statusText + ")");
        this.statusCode = statusCode;
      }

@@ -165,6 +164,16 @@
        return statusCode;
      }
    }
+
+  /**
+   * An exception indicating than at HTTP download succeeded, but  
installing
+   * its body failed.
+   */
+  static class HttpInstallFailure extends RuntimeException {
+    public HttpInstallFailure(String url, String text, Throwable  
rootCause) {
+      super("Install of " + url + " failed with text " + text, rootCause);
+    }
+  }

    /**
     * Handles a failure to download a fragment in the initial sequence.
@@ -261,90 +270,15 @@
        return !!$stats;
      }-*/;
    }
-
-  /**
-   * The standard loading strategy used in a web browser.
-   */
-  private static class XhrLoadingStrategy implements LoadingStrategy {
-    public void startLoadingFragment(int fragment,
-        final LoadErrorHandler loadErrorHandler) {
-      String fragmentUrl = gwtStartLoadingFragment(fragment,  
loadErrorHandler);
-
-      if (fragmentUrl == null) {
-        // The download has already started; nothing more to do
-        return;
-      }
-
-      // use XHR to download it
-
-      final XMLHttpRequest xhr = XMLHttpRequest.create();
-
-      xhr.open(HTTP_GET, fragmentUrl);
-
-      xhr.setOnReadyStateChange(new ReadyStateChangeHandler() {
-        public void onReadyStateChange(XMLHttpRequest ignored) {
-          if (xhr.getReadyState() == XMLHttpRequest.DONE) {
-            xhr.clearOnReadyStateChange();
-            if ((xhr.getStatus() == HTTP_STATUS_OK || xhr.getStatus() ==  
HTTP_STATUS_NON_HTTP)
-                && xhr.getResponseText() != null
-                && xhr.getResponseText().length() != 0) {
-              try {
-                gwtInstallCode(xhr.getResponseText());
-              } catch (RuntimeException e) {
-                loadErrorHandler.loadFailed(e);
-              }
-            } else {
-              loadErrorHandler.loadFailed(new HttpDownloadFailure(
-                  xhr.getStatus()));
-            }
-          }
-        }
-      });
-
-      xhr.send();
-    }
-
-    /**
-     * Call the linker-supplied <code>__gwtInstallCode</code> method. See  
the
-     * {...@link AsyncFragmentLoader class comment} for more details.
-     */
-    private native void gwtInstallCode(String text) /*-{
-      __gwtInstallCode(text);
-    }-*/;
-
-    /**
-     * Call the linker-supplied __gwtStartLoadingFragment function. It  
should
-     * either start the download and return null or undefined, or it  
should return
-     * a URL that should be downloaded to get the code. If it starts the  
download
-     * itself, it can synchronously load it, e.g. from cache, if that  
makes sense.
-     */
-    private native String gwtStartLoadingFragment(int fragment,
-        LoadErrorHandler loadErrorHandler) /*-{
-      function loadFailed(e) {
-         
loaderrorhandl...@com.google.gwt.core.client.impl.asyncfragmentloader$loaderrorhandler::loadFailed(Ljava/lang/Throwable;)(e);
-      }
-      return __gwtStartLoadingFragment(fragment, loadFailed);
-    }-*/;
-  }

    /**
     * The standard instance of AsyncFragmentLoader used in a web browser.  
The
     * parameters to this call are filled in by
     * {...@link com.google.gwt.dev.jjs.impl.ReplaceRunAsyncs}.
     */
-  public static AsyncFragmentLoader BROWSER_LOADER = new  
AsyncFragmentLoader(1,
-      new int[] {}, new XhrLoadingStrategy(), new StandardLogger());
-
-  private static final String HTTP_GET = "GET";
-
-  /**
-   * Some UA's like Safari will have a "0" status code when loading from  
file:
-   * URLs. Additionally, the "0" status code is used sometimes if the  
server
-   * does not respond, e.g. if there is a connection refused.
-   */
-  private static final int HTTP_STATUS_NON_HTTP = 0;
-
-  private static final int HTTP_STATUS_OK = 200;
+  public static AsyncFragmentLoader BROWSER_LOADER =
+      new AsyncFragmentLoader(1, new int[] {}, // compiler replaces these  
two
+          new XhrLoadingStrategy(), new StandardLogger());

    /**
     * A helper static method that invokes
=======================================
---  
/branches/snapshot-2009.10.23-r6446/user/test/com/google/gwt/core/CoreSuite.java
         
Wed Nov 11 20:06:00 2009
+++  
/branches/snapshot-2009.10.23-r6446/user/test/com/google/gwt/core/CoreSuite.java
         
Mon Dec  7 16:46:41 2009
@@ -23,6 +23,7 @@
  import com.google.gwt.core.client.impl.EmulatedStackTraceTest;
  import com.google.gwt.core.client.impl.SchedulerImplTest;
  import com.google.gwt.core.client.impl.StackTraceCreatorTest;
+import com.google.gwt.core.client.impl.XhrLoadingStrategyTest;
  import com.google.gwt.junit.tools.GWTTestSuite;

  import junit.framework.Test;
@@ -42,6 +43,7 @@
      suite.addTestSuite(StackTraceCreatorTest.class);
      suite.addTestSuite(EmulatedStackTraceTest.class);
      suite.addTestSuite(AsyncFragmentLoaderTest.class);
+    suite.addTestSuite(XhrLoadingStrategyTest.class);
      suite.addTestSuite(SchedulerImplTest.class);
      // $JUnit-END$

-- 
http://groups.google.com/group/Google-Web-Toolkit-Contributors

Reply via email to