Revision: 8755
Author: [email protected]
Date: Fri Sep 10 13:31:52 2010
Log: Fixed the firing of events on changes to EntityProxy. Added an ACQUIRE
event and implemented the copy-on-write semantics.
Patch by: amitmanjhi
Review by: rjrjr (desk review)
Review at http://gwt-code-reviews.appspot.com/860801
http://code.google.com/p/google-web-toolkit/source/detail?r=8755
Added:
/trunk/user/test/com/google/gwt/requestfactory/client/impl/ValueStoreJsonImplTest.java
Modified:
/trunk/user/src/com/google/gwt/requestfactory/client/impl/AbstractJsonObjectRequest.java
/trunk/user/src/com/google/gwt/requestfactory/client/impl/AbstractRequest.java
/trunk/user/src/com/google/gwt/requestfactory/client/impl/DeltaValueStoreJsonImpl.java
/trunk/user/src/com/google/gwt/requestfactory/client/impl/ProxyJsoImpl.java
/trunk/user/src/com/google/gwt/requestfactory/client/impl/ValueStoreJsonImpl.java
/trunk/user/src/com/google/gwt/requestfactory/shared/Receiver.java
/trunk/user/src/com/google/gwt/requestfactory/shared/WriteOperation.java
/trunk/user/test/com/google/gwt/requestfactory/RequestFactorySuite.java
/trunk/user/test/com/google/gwt/requestfactory/client/impl/DeltaValueStoreJsonImplTest.java
/trunk/user/test/com/google/gwt/requestfactory/client/impl/ProxyJsoImplTest.java
=======================================
--- /dev/null
+++
/trunk/user/test/com/google/gwt/requestfactory/client/impl/ValueStoreJsonImplTest.java
Fri Sep 10 13:31:52 2010
@@ -0,0 +1,45 @@
+/*
+ * Copyright 2010 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.requestfactory.client.impl;
+
+import com.google.gwt.event.shared.HandlerManager;
+import com.google.gwt.junit.client.GWTTestCase;
+
+/**
+ * Tests for {...@link ValueStoreJsonImpl}.
+ */
+public class ValueStoreJsonImplTest extends GWTTestCase {
+
+ @Override
+ public String getModuleName() {
+ return "com.google.gwt.requestfactory.RequestFactorySuite";
+ }
+
+ public void testPutInValueStore() {
+ ValueStoreJsonImpl valueStore = new ValueStoreJsonImpl();
+ ProxyJsoImpl minimalJso = ProxyJsoImplTest.getMinimalJso();
+ ProxyJsoImpl populatedJso = ProxyJsoImplTest.getPopulatedJso();
+ ProxyJsoImpl copyPopulatedJso = ProxyJsoImplTest.getPopulatedJso();
+ HandlerManager eventBus = new HandlerManager(null);
+ minimalJso.getRequestFactory().init(eventBus);
+
+ assertNull(valueStore.putInValueStore(minimalJso));
+ assertNull(valueStore.putInValueStore(populatedJso));
+ assertSame(populatedJso, valueStore.putInValueStore(copyPopulatedJso));
+ assertSame(populatedJso, valueStore.putInValueStore(minimalJso));
+ }
+
+}
=======================================
---
/trunk/user/src/com/google/gwt/requestfactory/client/impl/AbstractJsonObjectRequest.java
Tue Sep 7 10:09:37 2010
+++
/trunk/user/src/com/google/gwt/requestfactory/client/impl/AbstractJsonObjectRequest.java
Fri Sep 10 13:31:52 2010
@@ -49,7 +49,10 @@
JavaScriptObject rawJso = (JavaScriptObject) result;
ProxyJsoImpl jso = ProxyJsoImpl.create(rawJso, schema, requestFactory);
- requestFactory.getValueStore().setProxy(jso);
+ ProxyJsoImpl oldJso =
requestFactory.getValueStore().putInValueStore(jso);
+ if (oldJso != null) {
+ jso = oldJso;
+ }
/*
* schema really should be ProxySchema<? extends T>, and then this cast
=======================================
---
/trunk/user/src/com/google/gwt/requestfactory/client/impl/AbstractRequest.java
Tue Sep 7 10:09:37 2010
+++
/trunk/user/src/com/google/gwt/requestfactory/client/impl/AbstractRequest.java
Fri Sep 10 13:31:52 2010
@@ -104,9 +104,12 @@
public boolean isChanged() {
return deltaValueStore.isChanged();
}
-
+
+ /*
+ * used from the JSNI method processRelated.
+ */
public void pushToValueStore(String schemaToken, JavaScriptObject jso) {
- requestFactory.getValueStore().setProxy(
+ requestFactory.getValueStore().putInValueStore(
ProxyJsoImpl.create(jso, requestFactory.getSchema(schemaToken),
requestFactory));
}
=======================================
---
/trunk/user/src/com/google/gwt/requestfactory/client/impl/DeltaValueStoreJsonImpl.java
Fri Sep 10 09:06:14 2010
+++
/trunk/user/src/com/google/gwt/requestfactory/client/impl/DeltaValueStoreJsonImpl.java
Fri Sep 10 13:31:52 2010
@@ -228,13 +228,17 @@
ProxyJsoImpl masterRecord = master.records.get(key);
ProxyJsoImpl value = updates.get(key);
if (masterRecord != null && value != null) {
- // no support for partial updates.
- // TODO(amitmanjhi): instead of merging, get updates from
server.
- masterRecord.merge(value);
+ /*
+ * Currently, no support for partial updates. When the updates
+ * return all fields that have changed (the version number can
be
+ * used to optimize the payload), it will fix partial updates.
+ */
+ copy.merge(masterRecord);
+ copy.merge(value);
toRemove.add(key);
}
if (masterRecord != null) {
- syncResults.add(makeSyncResult(masterRecord, null, null));
+ syncResults.add(makeSyncResult(copy, null, null));
} else {
// do not change the masterRecord or fire event
syncResults.add(makeSyncResult(copy, null, null));
=======================================
---
/trunk/user/src/com/google/gwt/requestfactory/client/impl/ProxyJsoImpl.java
Fri Sep 10 09:06:14 2010
+++
/trunk/user/src/com/google/gwt/requestfactory/client/impl/ProxyJsoImpl.java
Fri Sep 10 13:31:52 2010
@@ -334,6 +334,22 @@
return rtn;
}-*/;
+ final boolean hasChanged(ProxyJsoImpl newJso) {
+ assert getSchema() == newJso.getSchema();
+ for (Property<?> property : getSchema().allProperties()) {
+ if (newJso.isDefined(property.getName())) {
+ if (isDefined(property.getName())) {
+ if (hasValueChanged(property.getName(), newJso)) {
+ return true;
+ }
+ } else {
+ return true;
+ }
+ }
+ }
+ return false;
+ }
+
private native boolean copyPropertyIfDifferent(String name, ProxyJsoImpl
from) /*-{
if (this[name] == from[name]) {
return false;
@@ -358,6 +374,13 @@
return this[name];
}-*/;
+ private native boolean hasValueChanged(String name, ProxyJsoImpl from)
/*-{
+ if (this[name] == from[name]) {
+ return false;
+ }
+ return true;
+ }-*/;
+
private native void setBoolean(String name, boolean value) /*-{
this[name] = value;
}-*/;
@@ -374,12 +397,12 @@
this[name] = null;
}-*/;
- private final native void setRequestFactory(
+ private native void setRequestFactory(
RequestFactoryJsonImpl requestFactory) /*-{
this['__rf'] = requestFactory;
}-*/;
- private final native void setSchema(ProxySchema<?> schema) /*-{
+ private native void setSchema(ProxySchema<?> schema) /*-{
this['__key'] = schema;
}-*/;
=======================================
---
/trunk/user/src/com/google/gwt/requestfactory/client/impl/ValueStoreJsonImpl.java
Wed Sep 8 11:08:25 2010
+++
/trunk/user/src/com/google/gwt/requestfactory/client/impl/ValueStoreJsonImpl.java
Fri Sep 10 13:31:52 2010
@@ -45,19 +45,15 @@
return schema.create(records.get(key));
}
- void setProxy(ProxyJsoImpl newRecord) {
- setRecordInList(newRecord, 0, null);
- }
-
- void setRecords(JsArray<ProxyJsoImpl> newRecords) {
- for (int i = 0, l = newRecords.length(); i < l; i++) {
- ProxyJsoImpl newRecord = newRecords.get(i);
- setRecordInList(newRecord, i, newRecords);
- }
- }
-
- private void setRecordInList(ProxyJsoImpl newJsoRecord, int i,
- JsArray<ProxyJsoImpl> array) {
+ /**
+ * Puts a {...@link ProxyJsoImpl} newJsoRecord in the valueStore following a
+ * copy-on-write scheme, and sends appropriate events. If the valuestore
had a
+ * Jso that was the same or a superset of newJsoRecord, returns the
valuestore
+ * jso. Otherwise, puts newJsoRecord in the valuestore and returns null.
+ * <p>
+ * package-protected for testing purposes.
+ */
+ ProxyJsoImpl putInValueStore(ProxyJsoImpl newJsoRecord) {
EntityProxyIdImpl recordKey = new
EntityProxyIdImpl(newJsoRecord.getId(),
newJsoRecord.getSchema(), RequestFactoryJsonImpl.NOT_FUTURE,
newJsoRecord.getRequestFactory().datastoreToFutureMap.get(
@@ -66,19 +62,24 @@
ProxyJsoImpl oldRecord = records.get(recordKey);
if (oldRecord == null) {
records.put(recordKey, newJsoRecord);
- // TODO: need to fire a create event.
- } else {
- // TODO: Merging is not the correct thing to do but it works as long
as we
- // don't have filtering by properties. Need to revisit this once
response
- // only has a subset of all properties.
- boolean changed = oldRecord.merge(newJsoRecord);
- newJsoRecord = oldRecord.cast();
- if (array != null) {
- array.set(i, newJsoRecord);
- }
- if (changed) {
- newJsoRecord.getRequestFactory().postChangeEvent(newJsoRecord,
- WriteOperation.UPDATE);
+ newJsoRecord.getRequestFactory().postChangeEvent(newJsoRecord,
+ WriteOperation.ACQUIRE);
+ return null;
+ }
+ if (oldRecord.hasChanged(newJsoRecord)) {
+ records.put(recordKey, newJsoRecord);
+ newJsoRecord.getRequestFactory().postChangeEvent(newJsoRecord,
+ WriteOperation.UPDATE);
+ return null;
+ }
+ return oldRecord;
+ }
+
+ void setRecords(JsArray<ProxyJsoImpl> newRecords) {
+ for (int i = 0, l = newRecords.length(); i < l; i++) {
+ ProxyJsoImpl oldRecord = putInValueStore(newRecords.get(i));
+ if (oldRecord != null) {
+ newRecords.set(i, oldRecord);
}
}
}
=======================================
--- /trunk/user/src/com/google/gwt/requestfactory/shared/Receiver.java Wed
Aug 25 17:41:41 2010
+++ /trunk/user/src/com/google/gwt/requestfactory/shared/Receiver.java Fri
Sep 10 13:31:52 2010
@@ -15,7 +15,6 @@
*/
package com.google.gwt.requestfactory.shared;
-
import java.util.Set;
/**
=======================================
---
/trunk/user/src/com/google/gwt/requestfactory/shared/WriteOperation.java
Fri Sep 10 06:27:47 2010
+++
/trunk/user/src/com/google/gwt/requestfactory/shared/WriteOperation.java
Fri Sep 10 13:31:52 2010
@@ -21,9 +21,10 @@
* development, and is very likely to be deleted. Use it at your own risk.
* </span>
* </p>
- * The write operation enum used in DeltaValueStore.
+ * The write operation enum used in {...@link EntityProxyChangedEvent}.
*/
public enum WriteOperation {
+ ACQUIRE("ACQUIRE"),
CREATE("CREATE"),
UPDATE("UPDATE"),
DELETE("DELETE");
=======================================
--- /trunk/user/test/com/google/gwt/requestfactory/RequestFactorySuite.java
Thu Sep 2 20:54:55 2010
+++ /trunk/user/test/com/google/gwt/requestfactory/RequestFactorySuite.java
Fri Sep 10 13:31:52 2010
@@ -20,6 +20,7 @@
import com.google.gwt.requestfactory.client.RequestFactoryTest;
import
com.google.gwt.requestfactory.client.impl.DeltaValueStoreJsonImplTest;
import com.google.gwt.requestfactory.client.impl.ProxyJsoImplTest;
+import com.google.gwt.requestfactory.client.impl.ValueStoreJsonImplTest;
import junit.framework.Test;
@@ -32,6 +33,7 @@
"Test suite for requestfactory gwt code.");
suite.addTestSuite(EditorTest.class);
suite.addTestSuite(ProxyJsoImplTest.class);
+ suite.addTestSuite(ValueStoreJsonImplTest.class);
suite.addTestSuite(DeltaValueStoreJsonImplTest.class);
suite.addTestSuite(RequestFactoryTest.class);
return suite;
=======================================
---
/trunk/user/test/com/google/gwt/requestfactory/client/impl/DeltaValueStoreJsonImplTest.java
Fri Sep 10 06:27:47 2010
+++
/trunk/user/test/com/google/gwt/requestfactory/client/impl/DeltaValueStoreJsonImplTest.java
Fri Sep 10 13:31:52 2010
@@ -15,6 +15,7 @@
*/
package com.google.gwt.requestfactory.client.impl;
+import com.google.gwt.event.shared.HandlerManager;
import com.google.gwt.json.client.JSONArray;
import com.google.gwt.json.client.JSONObject;
import com.google.gwt.json.client.JSONParser;
@@ -58,11 +59,12 @@
public void gwtSetUp() {
valueStore = new ValueStoreJsonImpl();
requestFactory = (RequestFactoryJsonImpl)
SimpleRequestFactoryInstance.factory();
+ HandlerManager eventBus = new HandlerManager(null);
+ requestFactory.init(eventBus);
// add a proxy
jso = ProxyJsoImpl.create(42L, 1,
SimpleRequestFactoryInstance.schema(),
SimpleRequestFactoryInstance.impl());
-
jso.set(SimpleFooProxy.userName, "bovik");
jso.set(SimpleFooProxy.password, "bovik");
jso.set(SimpleFooProxy.intId, 4);
@@ -70,7 +72,7 @@
jso.set(SimpleFooProxy.boolField, false);
jso.set(SimpleFooProxy.otherBoolField, true);
- valueStore.setProxy(jso);
+ valueStore.putInValueStore(jso);
}
public void testCreate() {
@@ -143,7 +145,7 @@
ProxyImpl mockProxy = new ProxyImpl(ProxyJsoImpl.create(futureId, 1,
SimpleRequestFactoryInstance.schema(),
SimpleRequestFactoryInstance.impl()), RequestFactoryJsonImpl.NOT_FUTURE);
- valueStore.setProxy(mockProxy.asJso()); // marked as non-future..
+ valueStore.putInValueStore(mockProxy.asJso()); // marked as
non-future..
DeltaValueStoreJsonImpl deltaValueStore = new DeltaValueStoreJsonImpl(
valueStore, requestFactory);
=======================================
---
/trunk/user/test/com/google/gwt/requestfactory/client/impl/ProxyJsoImplTest.java
Tue Sep 7 10:09:37 2010
+++
/trunk/user/test/com/google/gwt/requestfactory/client/impl/ProxyJsoImplTest.java
Fri Sep 10 13:31:52 2010
@@ -80,6 +80,20 @@
private static final String ID_VERSION_JSON
= "{\"id\":\"42\",\"version\":1}";
private static final String ID_VERSION_JSON2
= "{\"id\":\"43\",\"version\":1}";
+ static ProxyJsoImpl getMinimalJso() {
+ return ProxyJsoImpl.create(42L, 1,
SimpleRequestFactoryInstance.schema(),
+ SimpleRequestFactoryInstance.impl());
+ }
+
+ static ProxyJsoImpl getPopulatedJso() {
+ ProxyJsoImpl jso = getMinimalJso();
+ jso.set(SimpleFooProxy.userName, "bovik");
+ jso.set(SimpleFooProxy.password, "bovik");
+ jso.set(SimpleFooProxy.intId, 4);
+ jso.set(SimpleFooProxy.created, new Date(400));
+ return jso;
+ }
+
@Override
public String getModuleName() {
return "com.google.gwt.requestfactory.RequestFactorySuite";
@@ -89,22 +103,29 @@
ProxyJsoImpl emptyCopy = ProxyJsoImpl.emptyCopy(getPopulatedJso());
testMinimalJso(emptyCopy);
}
-
- private native JavaScriptObject jsEval(String json) /*-{
- eval("xyz=" + json);
- return xyz;
- }-*/;
-
- private ProxyJsoImpl eval(String json) {
- JavaScriptObject rawJso = jsEval(json);
- return ProxyJsoImpl.create(rawJso,
SimpleRequestFactoryInstance.schema(),
- SimpleRequestFactoryInstance.impl());
- }
public void testFromJson() {
testMinimalJso(eval(ID_VERSION_JSON));
testPopulatedJso(eval(ALL_PROPERTIES_JSON));
}
+
+ /*
+ * TODO(amitmanjhi): test null values.
+ */
+ public void testHasChanged() {
+ ProxyJsoImpl minimalJso = getMinimalJso();
+ ProxyJsoImpl populatedJso = getPopulatedJso();
+ assertFalse(minimalJso.hasChanged(minimalJso));
+ assertFalse(populatedJso.hasChanged(populatedJso));
+
+ assertTrue(minimalJso.hasChanged(populatedJso));
+ assertFalse(populatedJso.hasChanged(minimalJso));
+
+ ProxyJsoImpl minimalJsoCopy = getMinimalJso();
+ assertFalse(minimalJso.hasChanged(minimalJsoCopy));
+ minimalJsoCopy.set(SimpleFooProxy.id, minimalJso.getId() + 42);
+ assertTrue(minimalJso.hasChanged(minimalJsoCopy));
+ }
public void testIsEmpty() {
assertTrue(getMinimalJso().isEmpty());
@@ -144,19 +165,16 @@
assertEquals(ID_VERSION_JSON, getMinimalJso().toJson());
}
- private ProxyJsoImpl getMinimalJso() {
- return ProxyJsoImpl.create(42L, 1,
SimpleRequestFactoryInstance.schema(),
+ private ProxyJsoImpl eval(String json) {
+ JavaScriptObject rawJso = jsEval(json);
+ return ProxyJsoImpl.create(rawJso,
SimpleRequestFactoryInstance.schema(),
SimpleRequestFactoryInstance.impl());
}
- private ProxyJsoImpl getPopulatedJso() {
- ProxyJsoImpl jso = getMinimalJso();
- jso.set(SimpleFooProxy.userName, "bovik");
- jso.set(SimpleFooProxy.password, "bovik");
- jso.set(SimpleFooProxy.intId, 4);
- jso.set(SimpleFooProxy.created, new Date(400));
- return jso;
- }
+ private native JavaScriptObject jsEval(String json) /*-{
+ eval("xyz=" + json);
+ return xyz;
+ }-*/;
private void testEmptyJso(JavaScriptObject rawJso) {
ProxyJsoImpl jso = ProxyJsoImpl.create(rawJso, null, null);
--
http://groups.google.com/group/Google-Web-Toolkit-Contributors