]> source.dussan.org Git - gwtquery.git/commitdiff
Extract helper classes from the Deferred class, so as we dont get compilation errors...
authorManuel Carrasco Moñino <manuel.carrasco.m@gmail.com>
Mon, 18 Mar 2013 11:48:01 +0000 (12:48 +0100)
committerManuel Carrasco Moñino <manuel.carrasco.m@gmail.com>
Mon, 18 Mar 2013 11:48:01 +0000 (12:48 +0100)
13 files changed:
gwtquery-core/src/main/java/com/google/gwt/query/client/GQuery.java
gwtquery-core/src/main/java/com/google/gwt/query/client/LazyGQuery.java
gwtquery-core/src/main/java/com/google/gwt/query/client/plugins/Deferred.java [deleted file]
gwtquery-core/src/main/java/com/google/gwt/query/client/plugins/ajax/Ajax.java
gwtquery-core/src/main/java/com/google/gwt/query/client/plugins/callbacks/Callbacks.java [deleted file]
gwtquery-core/src/main/java/com/google/gwt/query/client/plugins/deferred/Callbacks.java [new file with mode: 0644]
gwtquery-core/src/main/java/com/google/gwt/query/client/plugins/deferred/Deferred.java [new file with mode: 0644]
gwtquery-core/src/main/java/com/google/gwt/query/client/plugins/deferred/PromiseFunction.java [new file with mode: 0644]
gwtquery-core/src/main/java/com/google/gwt/query/client/plugins/deferred/PromiseJsonpReqBuilder.java [new file with mode: 0644]
gwtquery-core/src/main/java/com/google/gwt/query/client/plugins/deferred/PromiseRF.java [new file with mode: 0644]
gwtquery-core/src/main/java/com/google/gwt/query/client/plugins/deferred/PromiseRPC.java [new file with mode: 0644]
gwtquery-core/src/main/java/com/google/gwt/query/client/plugins/deferred/PromiseReqBuilder.java [new file with mode: 0644]
gwtquery-core/src/test/java/com/google/gwt/query/client/GQueryDeferredTestGwt.java

index bdd1e7998e9db3f161655ab206e5406554083331..36a6647f080dd1273648cbdee51f8f7f9de8e8a8 100644 (file)
@@ -51,13 +51,13 @@ import com.google.gwt.query.client.js.JsNodeArray;
 import com.google.gwt.query.client.js.JsObjectArray;
 import com.google.gwt.query.client.js.JsRegexp;
 import com.google.gwt.query.client.js.JsUtils;
-import com.google.gwt.query.client.plugins.Deferred;
 import com.google.gwt.query.client.plugins.Effects;
 import com.google.gwt.query.client.plugins.Events;
 import com.google.gwt.query.client.plugins.Plugin;
 import com.google.gwt.query.client.plugins.Widgets;
 import com.google.gwt.query.client.plugins.ajax.Ajax;
 import com.google.gwt.query.client.plugins.ajax.Ajax.Settings;
+import com.google.gwt.query.client.plugins.deferred.Deferred;
 import com.google.gwt.query.client.plugins.effects.PropertiesAnimation.Easing;
 import com.google.gwt.query.client.plugins.events.EventsListener;
 import com.google.gwt.query.client.plugins.widgets.WidgetsUtils;
index 68d0a1731bab82043d5b19cadc91b7019a584540..6b5113e29e0e96919b054f0d5767ca0e74e4759e 100644 (file)
@@ -48,13 +48,13 @@ import com.google.gwt.query.client.js.JsNodeArray;
 import com.google.gwt.query.client.js.JsObjectArray;
 import com.google.gwt.query.client.js.JsRegexp;
 import com.google.gwt.query.client.js.JsUtils;
-import com.google.gwt.query.client.plugins.Deferred;
 import com.google.gwt.query.client.plugins.Effects;
 import com.google.gwt.query.client.plugins.Events;
 import com.google.gwt.query.client.plugins.Plugin;
 import com.google.gwt.query.client.plugins.Widgets;
 import com.google.gwt.query.client.plugins.ajax.Ajax;
 import com.google.gwt.query.client.plugins.ajax.Ajax.Settings;
+import com.google.gwt.query.client.plugins.deferred.Deferred;
 import com.google.gwt.query.client.plugins.effects.PropertiesAnimation.Easing;
 import com.google.gwt.query.client.plugins.events.EventsListener;
 import com.google.gwt.query.client.plugins.widgets.WidgetsUtils;
diff --git a/gwtquery-core/src/main/java/com/google/gwt/query/client/plugins/Deferred.java b/gwtquery-core/src/main/java/com/google/gwt/query/client/plugins/Deferred.java
deleted file mode 100644 (file)
index c868398..0000000
+++ /dev/null
@@ -1,442 +0,0 @@
-/*
- * Copyright 2013, The gwtquery team.
- *
- * 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.query.client.plugins;
-
-import static com.google.gwt.query.client.Promise.PENDING;
-import static com.google.gwt.query.client.Promise.REJECTED;
-import static com.google.gwt.query.client.Promise.RESOLVED;
-
-import java.util.Set;
-
-import javax.validation.ConstraintViolation;
-
-import com.google.gwt.http.client.Request;
-import com.google.gwt.http.client.RequestBuilder;
-import com.google.gwt.http.client.RequestCallback;
-import com.google.gwt.http.client.RequestException;
-import com.google.gwt.http.client.Response;
-import com.google.gwt.jsonp.client.JsonpRequestBuilder;
-import com.google.gwt.query.client.Function;
-import com.google.gwt.query.client.GQuery;
-import com.google.gwt.query.client.Promise;
-import com.google.gwt.query.client.plugins.callbacks.Callbacks;
-import com.google.gwt.user.client.rpc.AsyncCallback;
-import com.google.web.bindery.requestfactory.shared.Receiver;
-import com.google.web.bindery.requestfactory.shared.ServerFailure;
-
-/**
- * Implementation of jQuery.Deferred for gwtquery.
- */
-public class Deferred extends GQuery implements Promise.Deferred {
-  
-  /**
-   * Utility class used to create customized promises which can manipulate
-   * the associated deferred object.
-   * <pre>
-   *    Promise doSomething = new PromiseFunction() {
-   *      @Override
-   *      public void f(Deferred dfd) {
-   *        dfd.notify("hi");
-   *        dfd.resolve("done");
-   *      }
-   *    };
-   *    
-   *    doSomething.progress(new Function() {
-   *      public void f() {
-   *        String hi = arguments(0);
-   *      }
-   *    }).done(new Function() {
-   *      public void f() {
-   *        String done = arguments(0);
-   *      }
-   *    });
-   * </pre>
-   */
-  public static abstract class PromiseFunction extends DeferredPromiseImpl {
-    public PromiseFunction() {
-      f(dfd);
-    }
-    
-    /**
-     * This function is called once when the promise is created and the
-     * new deferred is available.
-     */
-    public abstract void f(Deferred dfd);
-  }
-  
-  /**
-   * Utility class used to create promises for RequestBuilder.
-   * <pre>
-   *        RequestBuilder builder = new RequestBuilder(RequestBuilder.GET, "http://127.0.0.1:8888/whatever");
-   *        PromiseRequest gettingResponse = new PromiseReqBuilder(builder);
-   *        
-   *        gettingResponse.fail(new Function() {
-   *          public void f() {
-   *            Throwable exception = arguments(0);
-   *          }
-   *        }).done(new Function() {
-   *          public void f() {
-   *            Response response = arguments(0);
-   *          }
-   *        });
-   * </pre>
-   */
-  public static class PromiseReqBuilder extends DeferredPromiseImpl implements RequestCallback {
-    public PromiseReqBuilder(RequestBuilder builder) {
-      builder.setCallback(this);
-      try {
-        builder.send();
-      } catch (RequestException e) {
-        onError(null, e);
-      }
-    }
-
-    public void onError(Request request, Throwable exception) {
-      dfd.reject(exception, request);
-    }
-
-    public void onResponseReceived(Request request, Response response) {
-      int status = response.getStatusCode();
-      if (status <= 0 || status >= 400) {
-        String statusText = status <= 0 ? "Bad CORS" : response.getStatusText();
-        onError(request, new RequestException("HTTP ERROR: " + status + " " + statusText + "\n" + response.getText()));
-      } else {
-        dfd.resolve(response, request);
-      }
-    }
-  }
-  
-  /**
-   * Utility class used to create promises for JsonpRequestBuilder.
-   * <pre>
-   *    Promise p = new PromiseJsonpReqBuilder(url, 4000);
-   *    
-   *    p.done(new Function() {
-   *      public void f() {
-   *        Properties p = arguments(0);
-   *      }
-   *    }).fail(new Function() {
-   *      public void f() {
-   *        Throwable error = arguments(0);
-   *      }
-   *    });
-   * </pre>
-   */
-  public static class PromiseJsonpReqBuilder extends DeferredPromiseImpl {
-    public PromiseJsonpReqBuilder(String url) {
-      this(url, null, 0);
-    }
-
-    public PromiseJsonpReqBuilder(String url, int timeout) {
-      this(url, null, timeout);
-    }
-
-    public PromiseJsonpReqBuilder(String url, String callbackParam, int timeout) {
-      JsonpRequestBuilder builder = new JsonpRequestBuilder();
-      if (timeout > 0) {
-        builder.setTimeout(timeout);
-      }
-      if (callbackParam != null) {
-        builder.setCallbackParam(callbackParam);
-      }
-      send(builder, url, new AsyncCallback<Object>() {
-        public void onFailure(Throwable caught) {
-          dfd.reject(caught);
-        }
-
-        public void onSuccess(Object result) {
-          dfd.resolve(result);
-        }
-      });
-    }
-
-    // Using jsni because method send in JsonpRequestBuilder is private
-    private final native void send(JsonpRequestBuilder bld, String url, AsyncCallback<?> cb) /*-{
-      bld.@com.google.gwt.jsonp.client.JsonpRequestBuilder::send(Ljava/lang/String;Lcom/google/gwt/user/client/rpc/AsyncCallback;Z)(url,cb,false);
-    }-*/;
-  }
-
-  /**
-   * Utility class used to create promises for RequestFactory services.
-   * <pre>
-   *    Request<SessionProxy> req1 = loginFact.api().login(null, null);
-   *    Request<UserProxy> req2 = srvFact.api().getCurrentUser();
-   *    
-   *    Promise requestingAll = Deferred.when(new PromiseRF(req1), new PromiseRF(req2);
-   *    
-   *    requestingAll.done(new Function() {
-   *        public void f() {
-   *          SessionProxy session = arguments(0, 0);
-   *          UserProxy user = arguments(1, 0);
-   *        }
-   *      })
-   *      .fail(new Function() {
-   *        public void f() {
-   *          ServerFailure failure = arguments(0);
-   *        }
-   *      }); 
-   * </pre>
-   */
-  public static class PromiseRF extends DeferredPromiseImpl {
-    public <T> PromiseRF(com.google.web.bindery.requestfactory.shared.Request<T> request) {
-      request.fire(new Receiver<T>() {
-        public void onConstraintViolation(Set<ConstraintViolation<?>> violations) {
-          dfd.reject(new ServerFailure("ConstraintViolation"), violations);
-        }
-
-        public void onFailure(ServerFailure error) {
-          dfd.reject(error);
-        }
-
-        public void onSuccess(T response) {
-          dfd.resolve(response);
-        }
-      });
-    }
-  }
-  
-  /**
-   * Utility class used to create promises for RPC services.
-   * <pre>
-   *        PromiseRPC<String> greeting = new PromiseRPC<String>();
-   *        
-   *        GreetingServiceAsync greetingService = GWT.create(GreetingService.class);
-   *        greetingService.greetServer("hi", greeting);
-   *        
-   *        greeting.fail(new Function(){
-   *          public void f() {
-   *            Throwable error = arguments(0);
-   *          }
-   *        }).done(new Function(){
-   *          public void f() {
-   *            String response = arguments(0);
-   *          }
-   *        });
-   * </pre>
-   */
-  public static class PromiseRPC<T> extends DeferredPromiseImpl implements AsyncCallback<T> {
-    public void onFailure(Throwable caught) {
-      dfd.reject(caught);
-    }
-
-    public void onSuccess(T result) {
-      dfd.resolve(result);
-    }
-  }
-
-  
-  /**
-   * Implementation of the Promise interface which is used internally by Deferred.
-   */
-  private static class DeferredPromiseImpl implements Promise {
-    com.google.gwt.query.client.plugins.Deferred dfd;
-    
-    protected DeferredPromiseImpl() {
-      dfd = new com.google.gwt.query.client.plugins.Deferred();
-    }
-
-    protected DeferredPromiseImpl(com.google.gwt.query.client.plugins.Deferred o) {
-      dfd = o;
-    }
-    
-    public Promise always(Function... f) {
-      return done(f).fail(f);
-    }
-
-    public Promise done(Function... f) {
-      dfd.resolve.add(f);
-      return this;
-    }
-    
-    public Promise fail(Function... f) {
-      dfd.reject.add(f);
-      return this;
-    }
-
-    public Promise pipe(Function... f) {
-      return then(f);
-    }
-    
-    public Promise progress(Function... f) {
-      dfd.notify.add(f);
-      return this;
-    }
-    
-    public String state() {
-      return dfd.state;
-    }
-    
-    public Promise then(Function... f) {
-      assert f.length < 4 : "Promise.then: Too much arguments";
-      switch (f.length) {
-        case 3: progress(f[2]);
-        case 2: fail(f[1]);
-        case 1: done(f[0]);
-      }
-      return this;
-    }
-  }
-  
-  /**
-   * Internal Deferred class used to combine a set of subordinate promises. 
-   */
-  private static class WhenDeferredImpl extends Deferred {
-    /**
-     * Internal function used to track whether all deferred 
-     * subordinates are resolved. 
-     */
-    private class DoneFnc extends Function {
-      final int idx;
-
-      public DoneFnc(int i, Deferred d) {
-        idx = i; 
-      }
-
-      public Object f(Object... args) {
-        values[idx] = args;
-        if (--remaining == 0) {
-          WhenDeferredImpl.this.resolve(values);
-        }
-        return true;
-      }
-    }
-    
-    private Function failFnc = new Function() {
-      public Object f(Object... o) {
-        WhenDeferredImpl.this.reject(o);
-        return true;
-      }
-    };
-    
-    private Function progressFnc = new Function() {
-      public Object f(Object... o) {
-        WhenDeferredImpl.this.notify(o);
-        return true;
-      }
-    };
-    
-    // Remaining counter
-    private int remaining;
-    
-    // An indexed array with the fired values of all subordinated
-    private final Object[] values;
-    
-    public WhenDeferredImpl(Promise[] sub) {
-      int l = remaining = sub.length;
-      values = new Object[l];
-      for (int i = 0; i < l; i++) {
-        sub[i].done(new DoneFnc(i, this)).progress(progressFnc).fail(failFnc);
-      }
-    }
-  }
-  
-  // Register Deferred as a GQuery plugin
-  public static final Class<Deferred> Deferred = GQuery.registerPlugin(
-      Deferred.class, new Plugin<Deferred>() {
-        public Deferred init(GQuery gq) {
-          return new Deferred(gq);
-        }
-      });
-  
-  public static Promise when(Promise... d) {
-    final int n = d.length;
-    switch (n) {
-      case 1:
-        return d[0];
-      case 0:
-        return new Deferred().resolve().promise();
-      default:
-        return new WhenDeferredImpl(d).promise();
-    }
-  }
-  
-  private Callbacks notify = new Callbacks("memory");
-  
-  private Promise promise = null;
-  
-  private Callbacks reject = new Callbacks("once memory");
-  
-  private Callbacks resolve = new Callbacks("once memory");
-  
-  private String state = PENDING;
-  
-  public Deferred() {
-    this(null);
-  }
-  
-  protected Deferred(GQuery gq) {
-    super(gq);
-    resolve.add(new Function() {
-      public void f() {
-        state = RESOLVED;
-        resolve.disable();
-        notify.lock();
-      }
-    });
-
-    reject.add(new Function() {
-      public void f() {
-        state = REJECTED;
-        reject.disable();
-        notify.lock();
-      }
-    });
-  }
-  
-  /**
-   * Call the progressCallbacks on a Deferred object with the given args.
-   */
-  public Deferred notify(Object... o) {
-    notify.fire(o);
-    return this;
-  }
-
-  /**
-   * Return a Deferred’s Promise object.
-   */
-  public Promise promise() {
-    if (promise == null) {
-      promise = new DeferredPromiseImpl(this);
-    }
-    return promise;
-  }
-  
-  /**
-   * Reject a Deferred object and call any failCallbacks with the given args.
-   */
-  public Deferred reject(Object... o) {
-    reject.fire(o);
-    return this;
-  }
-  
-  /**
-   * Resolve a Deferred object and call any doneCallbacks with the given args.
-   */
-  public Deferred resolve(Object... o) {
-    resolve.fire(o);
-    return this;
-  }
-
-  // private, used from jsni because it does not handles variable arguments
-  @SuppressWarnings("unused")
-  private void err(Object o) {
-    reject(o);
-  }
-  
-  // private, used from jsni because it does not handles variable arguments
-  @SuppressWarnings("unused")
-  private void ok(Object o) {
-    resolve(o);
-  }
-}
index 323eb728e7efaf0eaae6f6f32f2f03ace807876c..8d2ed1dcc8c2a9382eee7a8388eb10fe63d5c651 100644 (file)
@@ -11,10 +11,10 @@ import com.google.gwt.query.client.Promise;
 import com.google.gwt.query.client.Properties;
 import com.google.gwt.query.client.builders.JsonBuilder;
 import com.google.gwt.query.client.js.JsUtils;
-import com.google.gwt.query.client.plugins.Deferred;
-import com.google.gwt.query.client.plugins.Deferred.PromiseJsonpReqBuilder;
-import com.google.gwt.query.client.plugins.Deferred.PromiseReqBuilder;
 import com.google.gwt.query.client.plugins.Plugin;
+import com.google.gwt.query.client.plugins.deferred.Deferred;
+import com.google.gwt.query.client.plugins.deferred.PromiseJsonpReqBuilder;
+import com.google.gwt.query.client.plugins.deferred.PromiseReqBuilder;
 import com.google.gwt.user.client.ui.FormPanel;
 
 /**
@@ -318,7 +318,7 @@ public class Ajax extends GQuery {
   public static Promise getJSONP(String url, Function success, Function error, int timeout) {
     return new PromiseJsonpReqBuilder(url, null, timeout)
        .done(success)
-       .fail(error == null ? success : error);
+       .fail(error);
   }
 
   public static Promise post(String url, Properties data, final Function onSuccess) {
diff --git a/gwtquery-core/src/main/java/com/google/gwt/query/client/plugins/callbacks/Callbacks.java b/gwtquery-core/src/main/java/com/google/gwt/query/client/plugins/callbacks/Callbacks.java
deleted file mode 100644 (file)
index c7b4fb8..0000000
+++ /dev/null
@@ -1,188 +0,0 @@
-/*
- * Copyright 2013, The gwtquery team.
- *
- * 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.query.client.plugins.callbacks;
-
-import com.google.gwt.core.shared.GWT;
-import com.google.gwt.query.client.Function;
-import com.google.gwt.query.client.Properties;
-import com.google.gwt.query.client.builders.JsonBuilder;
-import com.google.gwt.query.client.js.JsObjectArray;
-
-/**
- * Implementation of jQuery.Callbacks for gwtquery.
- */
-public class Callbacks {
-  
-  /**
-   * Iterface used for callbacks which could cancel the execution 
-   * when returning false;
-   *
-   */
-  public static interface Callback {
-    /**
-     * Return false to avoid executing the rest of functions 
-     */
-    boolean f(Object ...objects);
-  }
-  
-  /**
-   * Interface representing the options of a Callbacks collection.
-   * 
-   * To create an implementation of this interface just call: Callbacks.createOptions()
-   */
-  public static interface CallbackOptions extends JsonBuilder {
-    boolean getMemory();
-    boolean getOnce();
-    boolean getStopOnFalse();
-    boolean getUnique();
-    CallbackOptions setMemory();
-    CallbackOptions setOnce();
-    CallbackOptions setStopOnFalse();
-    CallbackOptions setUnique();
-  }
-  
-  public static CallbackOptions createOptions() {
-    return GWT.create(CallbackOptions.class);
-  }
-  
-  private JsObjectArray<Object> stack = JsObjectArray.create();
-  
-  private boolean done = false;
-    
-  private JsObjectArray<Object> memory = null;
-  
-  public final CallbackOptions opts;
-  
-  /**
-   * Create a new Callbacks object with default options
-   */
-  public Callbacks() {
-    opts = createOptions();
-  }
-
-  /**
-   * Create a new Callbacks object with given options
-   */
-  public Callbacks(CallbackOptions options) {
-    opts = options;
-  }
-
-  /**
-   * Create a new Callbacks object with options given as a space delimited string.
-   * 
-   * Valid options are:
-   * 
-   * once, memory, unique, stopOnFalse
-   */
-  public Callbacks(String options) {
-    this();
-    opts.load(Properties.create(options.replaceAll("[^\\S]+|$", ":true,")));
-  }
-  
-  /**
-   * Add a Callback or a collection of callbacks to a callback list.
-   * 
-   */
-  public Callbacks add(Callback... c) {
-    addAll((Object[])c);
-    return this;
-  }
-  
-  /**
-   * Add a Callback or a collection of callbacks to a callback list.
-   */
-  public Callbacks add(com.google.gwt.core.client.Callback<?, ?>... c) {
-    addAll((Object[])c);
-    return this;
-  }
-
-  /**
-   * Add a Function or a collection of Function to a callback list.
-   */
-  public Callbacks add(Function... f) {
-    addAll((Object[])f);
-    return this;
-  }
-  
-  /**
-   * Disable a callback list from doing anything more.
-   */
-  public Callbacks disable() {
-    stack = memory = null;
-    done = true;
-    return this;
-  }
-  
-  /**
-   * lock
-   */
-  public Callbacks lock() {
-    if (!opts.getMemory()) {
-      disable();
-    }
-    stack = null;
-    return this;
-  }
-
-  /**
-   * Call all of the callbacks with the given arguments.
-   */
-  public Callbacks fire(Object... o) {
-    if (!done) {
-      done = opts.getOnce();
-      if (stack != null) for (Object c : stack.elements()) {
-        if (!run(c, o) && opts.getStopOnFalse()) {
-          break;
-        }
-      }
-      if (opts.getMemory()) {
-        memory = JsObjectArray.create().add(o);
-      }
-    }
-    return this;
-  }
-  
-  /**
-   * Remove a callback or a collection of callbacks from a callback list.
-   */
-  public Callbacks remove(Object... o) {
-    stack.remove(o);
-    return this;
-  }
-  
-  private void addAll(Object...o) {
-    for (Object c : o) {
-      if (!done && c != null && (!opts.getUnique() || !stack.contains(c))) {
-        stack.add(c);
-      }
-      // In jQuery add always is run when memory is true even when unique is set
-      if (opts.getMemory() && memory != null) {
-        run(c, memory.elements());
-      }
-    }
-  }  
-
-  @SuppressWarnings({"unchecked", "rawtypes"})
-  private boolean run(Object c, Object...o) {
-    if (c instanceof Callback) {
-      return ((Callback)c).f(o);
-    } else if (c instanceof Function) {
-      Object r = ((Function)c).f(o);
-      return (r instanceof Boolean) ? (Boolean)r : true;
-    } else if (c instanceof com.google.gwt.core.client.Callback) {
-      ((com.google.gwt.core.client.Callback)c).onSuccess(o);
-    }
-    return true;
-  }
-}
diff --git a/gwtquery-core/src/main/java/com/google/gwt/query/client/plugins/deferred/Callbacks.java b/gwtquery-core/src/main/java/com/google/gwt/query/client/plugins/deferred/Callbacks.java
new file mode 100644 (file)
index 0000000..5471ed2
--- /dev/null
@@ -0,0 +1,188 @@
+/*
+ * Copyright 2013, The gwtquery team.
+ *
+ * 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.query.client.plugins.deferred;
+
+import com.google.gwt.core.shared.GWT;
+import com.google.gwt.query.client.Function;
+import com.google.gwt.query.client.Properties;
+import com.google.gwt.query.client.builders.JsonBuilder;
+import com.google.gwt.query.client.js.JsObjectArray;
+
+/**
+ * Implementation of jQuery.Callbacks for gwtquery.
+ */
+public class Callbacks {
+  
+  /**
+   * Iterface used for callbacks which could cancel the execution 
+   * when returning false;
+   *
+   */
+  public static interface Callback {
+    /**
+     * Return false to avoid executing the rest of functions 
+     */
+    boolean f(Object ...objects);
+  }
+  
+  /**
+   * Interface representing the options of a Callbacks collection.
+   * 
+   * To create an implementation of this interface just call: Callbacks.createOptions()
+   */
+  public static interface CallbackOptions extends JsonBuilder {
+    boolean getMemory();
+    boolean getOnce();
+    boolean getStopOnFalse();
+    boolean getUnique();
+    CallbackOptions setMemory();
+    CallbackOptions setOnce();
+    CallbackOptions setStopOnFalse();
+    CallbackOptions setUnique();
+  }
+  
+  public static CallbackOptions createOptions() {
+    return GWT.create(CallbackOptions.class);
+  }
+  
+  private JsObjectArray<Object> stack = JsObjectArray.create();
+  
+  private boolean done = false;
+    
+  private JsObjectArray<Object> memory = null;
+  
+  public final CallbackOptions opts;
+  
+  /**
+   * Create a new Callbacks object with default options
+   */
+  public Callbacks() {
+    opts = createOptions();
+  }
+
+  /**
+   * Create a new Callbacks object with given options
+   */
+  public Callbacks(CallbackOptions options) {
+    opts = options;
+  }
+
+  /**
+   * Create a new Callbacks object with options given as a space delimited string.
+   * 
+   * Valid options are:
+   * 
+   * once, memory, unique, stopOnFalse
+   */
+  public Callbacks(String options) {
+    this();
+    opts.load(Properties.create(options.replaceAll("[^\\S]+|$", ":true,")));
+  }
+  
+  /**
+   * Add a Callback or a collection of callbacks to a callback list.
+   * 
+   */
+  public Callbacks add(Callback... c) {
+    addAll((Object[])c);
+    return this;
+  }
+  
+  /**
+   * Add a Callback or a collection of callbacks to a callback list.
+   */
+  public Callbacks add(com.google.gwt.core.client.Callback<?, ?>... c) {
+    addAll((Object[])c);
+    return this;
+  }
+
+  /**
+   * Add a Function or a collection of Function to a callback list.
+   */
+  public Callbacks add(Function... f) {
+    addAll((Object[])f);
+    return this;
+  }
+  
+  /**
+   * Disable a callback list from doing anything more.
+   */
+  public Callbacks disable() {
+    stack = memory = null;
+    done = true;
+    return this;
+  }
+  
+  /**
+   * lock
+   */
+  public Callbacks lock() {
+    if (!opts.getMemory()) {
+      disable();
+    }
+    stack = null;
+    return this;
+  }
+
+  /**
+   * Call all of the callbacks with the given arguments.
+   */
+  public Callbacks fire(Object... o) {
+    if (!done) {
+      done = opts.getOnce();
+      if (stack != null) for (Object c : stack.elements()) {
+        if (!run(c, o) && opts.getStopOnFalse()) {
+          break;
+        }
+      }
+      if (opts.getMemory()) {
+        memory = JsObjectArray.create().add(o);
+      }
+    }
+    return this;
+  }
+  
+  /**
+   * Remove a callback or a collection of callbacks from a callback list.
+   */
+  public Callbacks remove(Object... o) {
+    stack.remove(o);
+    return this;
+  }
+  
+  private void addAll(Object...o) {
+    for (Object c : o) {
+      if (!done && c != null && (!opts.getUnique() || !stack.contains(c))) {
+        stack.add(c);
+      }
+      // In jQuery add always is run when memory is true even when unique is set
+      if (opts.getMemory() && memory != null) {
+        run(c, memory.elements());
+      }
+    }
+  }  
+
+  @SuppressWarnings({"unchecked", "rawtypes"})
+  private boolean run(Object c, Object...o) {
+    if (c instanceof Callback) {
+      return ((Callback)c).f(o);
+    } else if (c instanceof Function) {
+      Object r = ((Function)c).f(o);
+      return (r instanceof Boolean) ? (Boolean)r : true;
+    } else if (c instanceof com.google.gwt.core.client.Callback) {
+      ((com.google.gwt.core.client.Callback)c).onSuccess(o);
+    }
+    return true;
+  }
+}
diff --git a/gwtquery-core/src/main/java/com/google/gwt/query/client/plugins/deferred/Deferred.java b/gwtquery-core/src/main/java/com/google/gwt/query/client/plugins/deferred/Deferred.java
new file mode 100644 (file)
index 0000000..017c6aa
--- /dev/null
@@ -0,0 +1,233 @@
+/*
+ * Copyright 2013, The gwtquery team.
+ *
+ * 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.query.client.plugins.deferred;
+
+import static com.google.gwt.query.client.Promise.PENDING;
+import static com.google.gwt.query.client.Promise.REJECTED;
+import static com.google.gwt.query.client.Promise.RESOLVED;
+
+import com.google.gwt.query.client.Function;
+import com.google.gwt.query.client.GQuery;
+import com.google.gwt.query.client.Promise;
+import com.google.gwt.query.client.plugins.Plugin;
+
+/**
+ * Implementation of jQuery.Deferred for gwtquery.
+ */
+public class Deferred extends GQuery implements Promise.Deferred {
+  
+  /**
+   * Implementation of the Promise interface which is used internally by Deferred.
+   */
+  public static class DeferredPromiseImpl implements Promise {
+    protected com.google.gwt.query.client.plugins.deferred.Deferred dfd;
+    
+    protected DeferredPromiseImpl() {
+      dfd = new com.google.gwt.query.client.plugins.deferred.Deferred();
+    }
+
+    protected DeferredPromiseImpl(com.google.gwt.query.client.plugins.deferred.Deferred o) {
+      dfd = o;
+    }
+    
+    public Promise always(Function... f) {
+      return done(f).fail(f);
+    }
+
+    public Promise done(Function... f) {
+      dfd.resolve.add(f);
+      return this;
+    }
+    
+    public Promise fail(Function... f) {
+      dfd.reject.add(f);
+      return this;
+    }
+
+    public Promise pipe(Function... f) {
+      return then(f);
+    }
+    
+    public Promise progress(Function... f) {
+      dfd.notify.add(f);
+      return this;
+    }
+    
+    public String state() {
+      return dfd.state;
+    }
+    
+    public Promise then(Function... f) {
+      assert f.length < 4 : "Promise.then: Too much arguments";
+      switch (f.length) {
+        case 3: progress(f[2]);
+        case 2: fail(f[1]);
+        case 1: done(f[0]);
+      }
+      return this;
+    }
+  }
+  
+  /**
+   * Internal Deferred class used to combine a set of subordinate promises. 
+   */
+  private static class WhenDeferredImpl extends Deferred {
+    /**
+     * Internal function used to track whether all deferred 
+     * subordinates are resolved. 
+     */
+    private class DoneFnc extends Function {
+      final int idx;
+
+      public DoneFnc(int i, Deferred d) {
+        idx = i; 
+      }
+
+      public Object f(Object... args) {
+        values[idx] = args;
+        if (--remaining == 0) {
+          WhenDeferredImpl.this.resolve(values);
+        }
+        return true;
+      }
+    }
+    
+    private Function failFnc = new Function() {
+      public Object f(Object... o) {
+        WhenDeferredImpl.this.reject(o);
+        return true;
+      }
+    };
+    
+    private Function progressFnc = new Function() {
+      public Object f(Object... o) {
+        WhenDeferredImpl.this.notify(o);
+        return true;
+      }
+    };
+    
+    // Remaining counter
+    private int remaining;
+    
+    // An indexed array with the fired values of all subordinated
+    private final Object[] values;
+    
+    public WhenDeferredImpl(Promise[] sub) {
+      int l = remaining = sub.length;
+      values = new Object[l];
+      for (int i = 0; i < l; i++) {
+        sub[i].done(new DoneFnc(i, this)).progress(progressFnc).fail(failFnc);
+      }
+    }
+  }
+  
+  // Register Deferred as a GQuery plugin
+  public static final Class<Deferred> Deferred = GQuery.registerPlugin(
+      Deferred.class, new Plugin<Deferred>() {
+        public Deferred init(GQuery gq) {
+          return new Deferred(gq);
+        }
+      });
+  
+  public static Promise when(Promise... d) {
+    final int n = d.length;
+    switch (n) {
+      case 1:
+        return d[0];
+      case 0:
+        return new Deferred().resolve().promise();
+      default:
+        return new WhenDeferredImpl(d).promise();
+    }
+  }
+  
+  private Callbacks notify = new Callbacks("memory");
+  
+  private Promise promise = null;
+  
+  private Callbacks reject = new Callbacks("once memory");
+  
+  private Callbacks resolve = new Callbacks("once memory");
+  
+  private String state = PENDING;
+  
+  public Deferred() {
+    this(null);
+  }
+  
+  protected Deferred(GQuery gq) {
+    super(gq);
+    resolve.add(new Function() {
+      public void f() {
+        state = RESOLVED;
+        resolve.disable();
+        notify.lock();
+      }
+    });
+
+    reject.add(new Function() {
+      public void f() {
+        state = REJECTED;
+        reject.disable();
+        notify.lock();
+      }
+    });
+  }
+  
+  /**
+   * Call the progressCallbacks on a Deferred object with the given args.
+   */
+  public Deferred notify(Object... o) {
+    notify.fire(o);
+    return this;
+  }
+
+  /**
+   * Return a Deferred’s Promise object.
+   */
+  public Promise promise() {
+    if (promise == null) {
+      promise = new DeferredPromiseImpl(this);
+    }
+    return promise;
+  }
+  
+  /**
+   * Reject a Deferred object and call any failCallbacks with the given args.
+   */
+  public Deferred reject(Object... o) {
+    reject.fire(o);
+    return this;
+  }
+  
+  /**
+   * Resolve a Deferred object and call any doneCallbacks with the given args.
+   */
+  public Deferred resolve(Object... o) {
+    resolve.fire(o);
+    return this;
+  }
+
+  // private, used from jsni because it does not handles variable arguments
+  @SuppressWarnings("unused")
+  private void err(Object o) {
+    reject(o);
+  }
+  
+  // private, used from jsni because it does not handles variable arguments
+  @SuppressWarnings("unused")
+  private void ok(Object o) {
+    resolve(o);
+  }
+}
diff --git a/gwtquery-core/src/main/java/com/google/gwt/query/client/plugins/deferred/PromiseFunction.java b/gwtquery-core/src/main/java/com/google/gwt/query/client/plugins/deferred/PromiseFunction.java
new file mode 100644 (file)
index 0000000..72f19ff
--- /dev/null
@@ -0,0 +1,38 @@
+package com.google.gwt.query.client.plugins.deferred;
+
+import com.google.gwt.query.client.plugins.deferred.Deferred.DeferredPromiseImpl;
+
+/**
+ * Utility class used to create customized promises which can manipulate
+ * the associated deferred object.
+ * <pre>
+ *    Promise doSomething = new PromiseFunction() {
+ *      @Override
+ *      public void f(Deferred dfd) {
+ *        dfd.notify("hi");
+ *        dfd.resolve("done");
+ *      }
+ *    };
+ *    
+ *    doSomething.progress(new Function() {
+ *      public void f() {
+ *        String hi = arguments(0);
+ *      }
+ *    }).done(new Function() {
+ *      public void f() {
+ *        String done = arguments(0);
+ *      }
+ *    });
+ * </pre>
+ */
+public abstract class PromiseFunction extends DeferredPromiseImpl {
+  public PromiseFunction() {
+    f(dfd);
+  }
+  
+  /**
+   * This function is called once when the promise is created and the
+   * new deferred is available.
+   */
+  public abstract void f(Deferred dfd);
+}
\ No newline at end of file
diff --git a/gwtquery-core/src/main/java/com/google/gwt/query/client/plugins/deferred/PromiseJsonpReqBuilder.java b/gwtquery-core/src/main/java/com/google/gwt/query/client/plugins/deferred/PromiseJsonpReqBuilder.java
new file mode 100644 (file)
index 0000000..80f0082
--- /dev/null
@@ -0,0 +1,68 @@
+package com.google.gwt.query.client.plugins.deferred;
+
+import com.google.gwt.jsonp.client.JsonpRequestBuilder;
+import com.google.gwt.query.client.js.JsObjectArray;
+import com.google.gwt.query.client.js.JsRegexp;
+import com.google.gwt.query.client.plugins.deferred.Deferred.DeferredPromiseImpl;
+import com.google.gwt.user.client.rpc.AsyncCallback;
+
+/**
+ * Utility class used to create promises for JsonpRequestBuilder.
+ * <pre>
+ *    Promise p = new PromiseJsonpReqBuilder(url, 4000);
+ *    
+ *    p.done(new Function() {
+ *      public void f() {
+ *        Properties p = arguments(0);
+ *      }
+ *    }).fail(new Function() {
+ *      public void f() {
+ *        Throwable error = arguments(0);
+ *      }
+ *    });
+ * </pre>
+ */
+public class PromiseJsonpReqBuilder extends DeferredPromiseImpl {
+  
+  private static final JsRegexp callbackRegex = new JsRegexp("^(.+[\\?&])([^=]+)=\\?(.*)$");
+  
+  public PromiseJsonpReqBuilder(String url) {
+    this(url, null, 0);
+  }
+
+  public PromiseJsonpReqBuilder(String url, int timeout) {
+    this(url, null, timeout);
+  }
+
+  public PromiseJsonpReqBuilder(String url, String callbackParam, int timeout) {
+    JsonpRequestBuilder builder = new JsonpRequestBuilder();
+    if (timeout > 0) {
+      builder.setTimeout(timeout);
+    }
+    // jQuery allows a parameter callback=? to figure out the callback parameter
+    if (callbackParam == null) {
+      JsObjectArray<String> tmp = callbackRegex.exec(url);
+      if  (tmp.length() == 4) {
+        callbackParam = tmp.get(2);
+        url = tmp.get(1) + tmp.get(3);
+      }
+    }
+    if (callbackParam != null) {
+      builder.setCallbackParam(callbackParam);
+    }
+    send(builder, url, new AsyncCallback<Object>() {
+      public void onFailure(Throwable caught) {
+        dfd.reject(caught);
+      }
+
+      public void onSuccess(Object result) {
+        dfd.resolve(result);
+      }
+    });
+  }
+
+  // Using jsni because method send in JsonpRequestBuilder is private
+  private final native void send(JsonpRequestBuilder bld, String url, AsyncCallback<?> cb) /*-{
+    bld.@com.google.gwt.jsonp.client.JsonpRequestBuilder::send(Ljava/lang/String;Lcom/google/gwt/user/client/rpc/AsyncCallback;Z)(url,cb,false);
+  }-*/;
+}
\ No newline at end of file
diff --git a/gwtquery-core/src/main/java/com/google/gwt/query/client/plugins/deferred/PromiseRF.java b/gwtquery-core/src/main/java/com/google/gwt/query/client/plugins/deferred/PromiseRF.java
new file mode 100644 (file)
index 0000000..737c7e8
--- /dev/null
@@ -0,0 +1,48 @@
+package com.google.gwt.query.client.plugins.deferred;
+
+import java.util.Set;
+
+import javax.validation.ConstraintViolation;
+
+import com.google.gwt.query.client.plugins.deferred.Deferred.DeferredPromiseImpl;
+import com.google.web.bindery.requestfactory.shared.Receiver;
+import com.google.web.bindery.requestfactory.shared.ServerFailure;
+
+/**
+ * Utility class used to create promises for RequestFactory services.
+ * <pre>
+ *    Request<SessionProxy> req1 = loginFact.api().login(null, null);
+ *    Request<UserProxy> req2 = srvFact.api().getCurrentUser();
+ *    
+ *    Promise requestingAll = Deferred.when(new PromiseRF(req1), new PromiseRF(req2);
+ *    
+ *    requestingAll.done(new Function() {
+ *        public void f() {
+ *          SessionProxy session = arguments(0, 0);
+ *          UserProxy user = arguments(1, 0);
+ *        }
+ *      })
+ *      .fail(new Function() {
+ *        public void f() {
+ *          ServerFailure failure = arguments(0);
+ *        }
+ *      }); 
+ * </pre>
+ */
+public class PromiseRF extends DeferredPromiseImpl {
+  public <T> PromiseRF(com.google.web.bindery.requestfactory.shared.Request<T> request) {
+    request.fire(new Receiver<T>() {
+      public void onConstraintViolation(Set<ConstraintViolation<?>> violations) {
+        dfd.reject(new ServerFailure("ConstraintViolation"), violations);
+      }
+
+      public void onFailure(ServerFailure error) {
+        dfd.reject(error);
+      }
+
+      public void onSuccess(T response) {
+        dfd.resolve(response);
+      }
+    });
+  }
+}
\ No newline at end of file
diff --git a/gwtquery-core/src/main/java/com/google/gwt/query/client/plugins/deferred/PromiseRPC.java b/gwtquery-core/src/main/java/com/google/gwt/query/client/plugins/deferred/PromiseRPC.java
new file mode 100644 (file)
index 0000000..41e88cf
--- /dev/null
@@ -0,0 +1,33 @@
+package com.google.gwt.query.client.plugins.deferred;
+
+import com.google.gwt.query.client.plugins.deferred.Deferred.DeferredPromiseImpl;
+import com.google.gwt.user.client.rpc.AsyncCallback;
+
+/**
+ * Utility class used to create promises for RPC services.
+ * <pre>
+ *        PromiseRPC<String> greeting = new PromiseRPC<String>();
+ *        
+ *        GreetingServiceAsync greetingService = GWT.create(GreetingService.class);
+ *        greetingService.greetServer("hi", greeting);
+ *        
+ *        greeting.fail(new Function(){
+ *          public void f() {
+ *            Throwable error = arguments(0);
+ *          }
+ *        }).done(new Function(){
+ *          public void f() {
+ *            String response = arguments(0);
+ *          }
+ *        });
+ * </pre>
+ */
+public class PromiseRPC<T> extends DeferredPromiseImpl implements AsyncCallback<T> {
+  public void onFailure(Throwable caught) {
+    dfd.reject(caught);
+  }
+
+  public void onSuccess(T result) {
+    dfd.resolve(result);
+  }
+}
\ No newline at end of file
diff --git a/gwtquery-core/src/main/java/com/google/gwt/query/client/plugins/deferred/PromiseReqBuilder.java b/gwtquery-core/src/main/java/com/google/gwt/query/client/plugins/deferred/PromiseReqBuilder.java
new file mode 100644 (file)
index 0000000..26ecefd
--- /dev/null
@@ -0,0 +1,50 @@
+package com.google.gwt.query.client.plugins.deferred;
+
+import com.google.gwt.http.client.Request;
+import com.google.gwt.http.client.RequestBuilder;
+import com.google.gwt.http.client.RequestCallback;
+import com.google.gwt.http.client.RequestException;
+import com.google.gwt.http.client.Response;
+import com.google.gwt.query.client.plugins.deferred.Deferred.DeferredPromiseImpl;
+
+/**
+ * Utility class used to create promises for RequestBuilder.
+ * <pre>
+ *        RequestBuilder builder = new RequestBuilder(RequestBuilder.GET, "http://127.0.0.1:8888/whatever");
+ *        PromiseRequest gettingResponse = new PromiseReqBuilder(builder);
+ *        
+ *        gettingResponse.fail(new Function() {
+ *          public void f() {
+ *            Throwable exception = arguments(0);
+ *          }
+ *        }).done(new Function() {
+ *          public void f() {
+ *            Response response = arguments(0);
+ *          }
+ *        });
+ * </pre>
+ */
+public class PromiseReqBuilder extends DeferredPromiseImpl implements RequestCallback {
+  public PromiseReqBuilder(RequestBuilder builder) {
+    builder.setCallback(this);
+    try {
+      builder.send();
+    } catch (RequestException e) {
+      onError(null, e);
+    }
+  }
+
+  public void onError(Request request, Throwable exception) {
+    dfd.reject(exception, request);
+  }
+
+  public void onResponseReceived(Request request, Response response) {
+    int status = response.getStatusCode();
+    if (status <= 0 || status >= 400) {
+      String statusText = status <= 0 ? "Bad CORS" : response.getStatusText();
+      onError(request, new RequestException("HTTP ERROR: " + status + " " + statusText + "\n" + response.getText()));
+    } else {
+      dfd.resolve(response, request);
+    }
+  }
+}
\ No newline at end of file
index dcd6e20b2c196364d46ac7f6b78a78e69d567e2b..8c011a247e8ed6c447bba2cb9b730d7c698658df 100644 (file)
@@ -17,10 +17,10 @@ package com.google.gwt.query.client;
 
 
 import com.google.gwt.junit.client.GWTTestCase;
-import com.google.gwt.query.client.plugins.Deferred.PromiseFunction;
 import com.google.gwt.query.client.plugins.ajax.Ajax;
-import com.google.gwt.query.client.plugins.callbacks.Callbacks;
-import com.google.gwt.query.client.plugins.callbacks.Callbacks.Callback;
+import com.google.gwt.query.client.plugins.deferred.Callbacks;
+import com.google.gwt.query.client.plugins.deferred.PromiseFunction;
+import com.google.gwt.query.client.plugins.deferred.Callbacks.Callback;
 import com.google.gwt.user.client.Timer;
 
 /**