aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorManuel Carrasco Moñino <manuel.carrasco.m@gmail.com>2013-11-30 12:57:24 +0100
committerManuel Carrasco Moñino <manuel.carrasco.m@gmail.com>2013-11-30 12:57:24 +0100
commitf7119204c7717ec7f396079df182f111f7f35b2b (patch)
treeae0d7d460f8b30376184039b5a3143630b1aa075
parent9df2f18c2b655db88abc31787ae7903f01f71060 (diff)
downloadgwtquery-f7119204c7717ec7f396079df182f111f7f35b2b.tar.gz
gwtquery-f7119204c7717ec7f396079df182f111f7f35b2b.zip
Adding ability to cache promises.
-rw-r--r--gwtquery-core/src/main/java/com/google/gwt/query/client/plugins/deferred/FunctionDeferred.java73
-rw-r--r--gwtquery-core/src/test/java/com/google/gwt/query/client/deferred/DeferredTest.java43
2 files changed, 96 insertions, 20 deletions
diff --git a/gwtquery-core/src/main/java/com/google/gwt/query/client/plugins/deferred/FunctionDeferred.java b/gwtquery-core/src/main/java/com/google/gwt/query/client/plugins/deferred/FunctionDeferred.java
index 3b40fdce..771749f8 100644
--- a/gwtquery-core/src/main/java/com/google/gwt/query/client/plugins/deferred/FunctionDeferred.java
+++ b/gwtquery-core/src/main/java/com/google/gwt/query/client/plugins/deferred/FunctionDeferred.java
@@ -21,29 +21,36 @@ import com.google.gwt.query.client.Promise.Deferred;
* execution in pipelined processes.
*
* They have access to the associated deferred object via a method which
- * will be called only in the case the previous promise is resolved
+ * will be called only in the case the previous promise is resolved.
+ *
+ * We can reuse the function and it will create new promises or will return
+ * the last one depending on the value of cache. It is very useful for caching
+ * server calls which we just want execute once like login, etc.
*
* <pre>
- * Promise doSomething = new PromiseFunction() {
+ * Function login = new FunctionDeferred() {
* @Override
* public void f(Deferred dfd) {
- * dfd.notify("hi");
- * dfd.resolve("done");
+ * dfd.resolve("logged in as james-bond at " + new Date());
* }
- * };
- *
- * doSomething.then(new FunctionDeferred() {
- * public void f(Deferred dfd) {
- * dfd.resolve("deferred " + arguments(0));
+ * }.withCache(RESOLVED);
+ *
+ * when(login)
+ * .then(new Function() {
+ * public void f() {
+ * String loginMessage = arguments(0);
* }
* });
* </pre>
*/
public abstract class FunctionDeferred extends Function {
-
+
+ public static enum CacheType {NONE, ALL, RESOLVED, REJECTED};
+
protected Deferred dfd;
public Function resolve, reject;
-
+ private CacheType cache = CacheType.NONE;
+
/**
* This function is called once the the previous promise in the
* pipe is resolved, and the new created deferred is available.
@@ -51,20 +58,46 @@ public abstract class FunctionDeferred extends Function {
* You have to override it, and resolve the new promise
*/
protected abstract void f(Deferred dfd);
-
+
/**
* This function is called when the previous promise in the pipe
* is resolved.
*/
public final Object f(Object... args) {
- return new PromiseFunction() {
- public void f(Deferred dfd) {
- FunctionDeferred.this.resolve = resolve;
- FunctionDeferred.this.reject = reject;
- FunctionDeferred.this.dfd = dfd;
- FunctionDeferred.this.f(dfd);
- }
- };
+ return dfd != null &&
+ (cache == CacheType.ALL ||
+ cache == CacheType.RESOLVED && dfd.promise().isResolved() ||
+ cache == CacheType.REJECTED && dfd.promise().isRejected())
+ ? dfd.promise()
+ : new PromiseFunction() {
+ public void f(Deferred dfd) {
+ FunctionDeferred.this.resolve = resolve;
+ FunctionDeferred.this.reject = reject;
+ FunctionDeferred.this.dfd = dfd;
+ FunctionDeferred.this.f(dfd);
+ }
+ };
}
+ /**
+ * Configure whether cache the promise the first time it is resolved
+ * or create new promises each time the function is executed.
+ *
+ * By default cache is disabled.
+ */
+ public FunctionDeferred withCache(CacheType type) {
+ cache = type;
+ return this;
+ }
+
+ /**
+ * Reset the cache so as a new invocation to this function will
+ * execute it instead of restoring old values from cache.
+ */
+ public FunctionDeferred resetCache() {
+ if (dfd != null && !dfd.promise().isPending()) {
+ dfd = null;
+ }
+ return this;
+ }
}
diff --git a/gwtquery-core/src/test/java/com/google/gwt/query/client/deferred/DeferredTest.java b/gwtquery-core/src/test/java/com/google/gwt/query/client/deferred/DeferredTest.java
index 45eb6064..9c7f16ef 100644
--- a/gwtquery-core/src/test/java/com/google/gwt/query/client/deferred/DeferredTest.java
+++ b/gwtquery-core/src/test/java/com/google/gwt/query/client/deferred/DeferredTest.java
@@ -24,6 +24,7 @@ import com.google.gwt.query.client.GQuery;
import com.google.gwt.query.client.Promise.Deferred;
import com.google.gwt.query.client.plugins.deferred.Callbacks;
import com.google.gwt.query.client.plugins.deferred.Callbacks.Callback;
+import com.google.gwt.query.client.plugins.deferred.FunctionDeferred.CacheType;
import com.google.gwt.query.client.plugins.deferred.FunctionDeferred;
import com.google.gwt.query.client.plugins.deferred.PromiseFunction;
@@ -371,4 +372,46 @@ public class DeferredTest extends GWTTestCase {
});
}
+ private Boolean deferredData;
+
+ public void testFunctionDeferredCache() {
+
+ FunctionDeferred cachedFunction = new FunctionDeferred() {protected void f(Deferred dfd) {
+ dfd.resolve(deferredData);
+ }};
+
+ Function setDeferredDataToTrue = new Function(){public void f() {
+ deferredData = true;
+ }};
+
+ Function setDeferredDataToFalse = new Function(){public void f() {
+ deferredData = false;
+ }};
+
+ Function assertDeferredDataIsFalse = new Function(){public void f() {
+ Boolean data = arguments(0);
+ assertFalse(data);
+ }};
+
+ Function assertDeferredDataIsTrue = new Function(){public void f() {
+ Boolean data = arguments(0);
+ assertTrue(data);
+ }};
+
+ when(setDeferredDataToTrue, cachedFunction.withCache(CacheType.ALL))
+ .always(setDeferredDataToFalse)
+ .done(assertDeferredDataIsTrue)
+ .then(cachedFunction)
+ .done(assertDeferredDataIsTrue)
+ .then(cachedFunction.withCache(CacheType.REJECTED))
+ .done(assertDeferredDataIsFalse)
+ .always(setDeferredDataToTrue)
+ .then(cachedFunction.withCache(CacheType.RESOLVED))
+ .done(assertDeferredDataIsFalse)
+ .then(cachedFunction.resetCache())
+ .done(assertDeferredDataIsTrue)
+ .then(cachedFunction)
+ .done(assertDeferredDataIsTrue)
+ ;
+ }
}