Remove version from the public api of EntityProxy. Encodes the version value into a !version field on the client side.

Patch by: amitmanjhi
Review by: rjrjr (desk review)

Review at http://gwt-code-reviews.appspot.com/878802


git-svn-id: https://google-web-toolkit.googlecode.com/svn/trunk@8851 8db76d5a-ed1c-0410-87a9-c151d255dfc7
diff --git a/user/src/com/google/gwt/requestfactory/client/impl/ProxyImpl.java b/user/src/com/google/gwt/requestfactory/client/impl/ProxyImpl.java
index c11a88c..ccb5bf9 100644
--- a/user/src/com/google/gwt/requestfactory/client/impl/ProxyImpl.java
+++ b/user/src/com/google/gwt/requestfactory/client/impl/ProxyImpl.java
@@ -36,8 +36,6 @@
  */
 public class ProxyImpl implements EntityProxy {
 
-  static final Property<Integer> version = new Property<Integer>("version", Integer.class);
-
   protected static String getWireFormatId(String id, boolean isFuture,
       ProxySchema<?> schema) {
     return id + "@" + (isFuture ? "IS" : "NO") + "@" + schema.getToken();
@@ -106,10 +104,6 @@
     return jso.getSchema();
   }
 
-  public Integer getVersion() {
-    return jso.getVersion();
-  }
-
   public String getWireFormatId() {
     return getWireFormatId(jso.encodedId(), isFuture, jso.getSchema());
   }
@@ -146,10 +140,14 @@
     return new EntityProxyIdImpl(encodedId(), getSchema(), isFuture, null);
   }
 
+  public Integer version() {
+    return jso.version();
+  }
+
   protected ValueStoreJsonImpl getValueStore() {
     return jso.getRequestFactory().getValueStore();
   }
-
+  
   void setDeltaValueStore(DeltaValueStoreJsonImpl deltaValueStore) {
     this.deltaValueStore = deltaValueStore;
   }
diff --git a/user/src/com/google/gwt/requestfactory/client/impl/ProxyJsoImpl.java b/user/src/com/google/gwt/requestfactory/client/impl/ProxyJsoImpl.java
index 8a4a91c..e80f3f1 100644
--- a/user/src/com/google/gwt/requestfactory/client/impl/ProxyJsoImpl.java
+++ b/user/src/com/google/gwt/requestfactory/client/impl/ProxyJsoImpl.java
@@ -25,6 +25,7 @@
 import com.google.gwt.requestfactory.shared.EntityProxyId;
 import com.google.gwt.requestfactory.shared.impl.CollectionProperty;
 import com.google.gwt.requestfactory.shared.impl.Property;
+import com.google.gwt.requestfactory.shared.impl.RequestData;
 
 import java.math.BigDecimal;
 import java.math.BigInteger;
@@ -74,7 +75,7 @@
 
   public static ProxyJsoImpl emptyCopy(ProxyJsoImpl jso) {
     ProxySchema<?> schema = jso.getSchema();
-    return create(jso.encodedId(), jso.getVersion(), schema,
+    return create(jso.encodedId(), jso.version(), schema,
         jso.getRequestFactory());
   }
 
@@ -103,7 +104,7 @@
    }-*/; 
 
    static native void splice(JavaScriptObject array, int index, int deleteCount,
-       Object value) /*-{
+       boolean value) /*-{
      array.splice(index, deleteCount, value);
    }-*/;
 
@@ -113,7 +114,7 @@
    }-*/;
 
   static native void splice(JavaScriptObject array, int index, int deleteCount,
-       boolean value) /*-{
+       Object value) /*-{
      array.splice(index, deleteCount, value);
    }-*/;
 
@@ -134,7 +135,7 @@
   public final void assertValid() {
     assert encodedId() != null : "encodedId required";
     assert getRequestFactory() != null : "requestFactory required";
-    assert getVersion() != null : "version required";
+    assert version() != null : "version required";
     assert getSchema() != null : "schema required";
   }
 
@@ -273,17 +274,13 @@
     return this['__key'];
   }-*/;
 
-  public final Integer getVersion() {
-    return this.get(ProxyImpl.version);
-  }
-
   public final native boolean isDefined(String name)/*-{
     return this[name] !== undefined;
   }-*/;
 
   public final boolean isEmpty() {
     for (Property<?> property : getSchema().allProperties()) {
-      if ((property != ProxyImpl.version) && (isDefined(property.getName()))) {
+      if (isDefined(property.getName())) {
         return false;
       }
     }
@@ -418,6 +415,10 @@
     return rtn;
   }-*/;
 
+  public final Integer version() {
+    return Integer.valueOf(getInt(RequestData.ENCODED_VERSION_PROPERTY));
+  }
+
   final boolean hasChanged(ProxyJsoImpl newJso) {
     assert getSchema() == newJso.getSchema();
     for (Property<?> property : getSchema().allProperties()) {
@@ -438,6 +439,10 @@
     this[@com.google.gwt.requestfactory.shared.impl.RequestData::ENCODED_ID_PROPERTY] = id;
   }-*/;
 
+  final void putVersion(Integer version) {
+    setInt(RequestData.ENCODED_VERSION_PROPERTY, version);
+  }
+
   private native boolean copyPropertyIfDifferent(String name, ProxyJsoImpl from) /*-{
     if (this[name] == from[name]) {
       return false;
@@ -465,13 +470,6 @@
     return true;
   }-*/;
 
-  /**
-   * @param version
-   */
-  private void putVersion(Integer version) {
-    set(ProxyImpl.version, version);
-  }
-
   private native void setBoolean(String name, boolean value) /*-{
     this[name] = value;
   }-*/;
diff --git a/user/src/com/google/gwt/requestfactory/client/impl/ProxySchema.java b/user/src/com/google/gwt/requestfactory/client/impl/ProxySchema.java
index ee5db74..d65933e 100644
--- a/user/src/com/google/gwt/requestfactory/client/impl/ProxySchema.java
+++ b/user/src/com/google/gwt/requestfactory/client/impl/ProxySchema.java
@@ -47,7 +47,6 @@
   
   {
     Set<Property<?>> set = new HashSet<Property<?>>();
-    set.add(ProxyImpl.version);
     allProperties = Collections.unmodifiableSet(set);
   }
   
diff --git a/user/src/com/google/gwt/requestfactory/server/JsonRequestProcessor.java b/user/src/com/google/gwt/requestfactory/server/JsonRequestProcessor.java
index 7fdc50b..7ec8010 100644
--- a/user/src/com/google/gwt/requestfactory/server/JsonRequestProcessor.java
+++ b/user/src/com/google/gwt/requestfactory/server/JsonRequestProcessor.java
@@ -612,10 +612,13 @@
       RequestProperty propertyContext) throws JSONException,
       NoSuchMethodException, IllegalAccessException, InvocationTargetException {
     JSONObject jsonObject = new JSONObject();
+    if (entityElement == null || !EntityProxy.class.isAssignableFrom(entityKeyClass)) {
+      return jsonObject;
+    }
 
-    jsonObject.put(ENCODED_ID_PROPERTY, isEntityReference(entityElement,
-        entityKeyClass));
-
+    jsonObject.put(ENCODED_ID_PROPERTY, isEntityReference(entityElement, entityKeyClass));
+    jsonObject.put(ENCODED_VERSION_PROPERTY, encodePropertyValueFromDataStore(entityElement,
+          ENTITY_VERSION_PROPERTY, ENTITY_VERSION_PROPERTY.getName(), propertyContext));
     for (Property<?> p : allProperties(entityKeyClass)) {
       if (requestedProperty(p, propertyContext)) {
         String propertyName = p.getName();
@@ -888,7 +891,7 @@
       } else {
         returnType = (Class<? extends EntityProxy>) operation.getReturnType();
       }
-      JSONObject jsonObject = toJsonObject(returnType, result);
+      JSONObject jsonObject = getJsonObject(result, returnType, propertyRefs);
       envelop.put(RESULT_TOKEN, jsonObject);
     }
     envelop.put(SIDE_EFFECTS_TOKEN, sideEffects);
@@ -911,6 +914,7 @@
      * gums up the works.
      */
     recordObject.remove(ENCODED_ID_PROPERTY);
+    recordObject.remove(ENCODED_VERSION_PROPERTY);
 
     Iterator<?> keys = recordObject.keys();
     while (keys.hasNext()) {
@@ -1214,9 +1218,9 @@
 
     newId = encodeId(newId);
     returnObject.put("id", getSchemaAndId(originalEntityKey.proxyType, newId));
-    returnObject.put("version", encodePropertyValueFromDataStore(
-        entityInstance, new Property<Integer>("version", Integer.class),
-        "version", propertyRefs));
+    returnObject.put(ENCODED_VERSION_PROPERTY, encodePropertyValueFromDataStore(
+        entityInstance, ENTITY_VERSION_PROPERTY,
+        ENTITY_VERSION_PROPERTY.getName(), propertyRefs));
     return returnObject;
   }
 
@@ -1487,13 +1491,6 @@
     return jsonArray;
   }
 
-  private JSONObject toJsonObject(Class<? extends EntityProxy> returnType,
-      Object result) throws JSONException, NoSuchMethodException,
-      IllegalAccessException, InvocationTargetException {
-    JSONObject jsonObject = getJsonObject(result, returnType, propertyRefs);
-    return jsonObject;
-  }
-
   /**
    * Update propertiesInRecord based on the types of entity type.
    */
diff --git a/user/src/com/google/gwt/requestfactory/shared/EntityProxy.java b/user/src/com/google/gwt/requestfactory/shared/EntityProxy.java
index 7d9a824..1ccc8ac 100644
--- a/user/src/com/google/gwt/requestfactory/shared/EntityProxy.java
+++ b/user/src/com/google/gwt/requestfactory/shared/EntityProxy.java
@@ -24,12 +24,6 @@
  * A proxy for a server-side domain object.
  */
 public interface EntityProxy {
-
-  /**
-   * @return the version of this Proxy.
-   */
-  Integer getVersion();
-
   /**
    * Subtypes should override to declare they return a stable id of their own
    * type, to allow type safe use of the request objects returned by
diff --git a/user/src/com/google/gwt/requestfactory/shared/impl/RequestData.java b/user/src/com/google/gwt/requestfactory/shared/impl/RequestData.java
index 7ebf74e..f54c9e0 100644
--- a/user/src/com/google/gwt/requestfactory/shared/impl/RequestData.java
+++ b/user/src/com/google/gwt/requestfactory/shared/impl/RequestData.java
@@ -50,11 +50,21 @@
   public static final String ENCODED_ID_PROPERTY = "!id";
   
   /**
+   * Property on a proxy JSO that holds its server side version data.
+   */
+  public static final String ENCODED_VERSION_PROPERTY = "!version";
+  
+  /**
    * Id property that server entity objects are required to define.
    */
   public static final String ENTITY_ID_PROPERTY = "id";
 
-  // TODO: non-final is a hack for now.
+  /**
+   * Version property that server entity objects are required to define.
+   */
+  public static final Property<Integer> ENTITY_VERSION_PROPERTY = new Property<Integer>(
+      "version", Integer.class);
+
   private final String operation;
   private final Object[] parameters;
 
diff --git a/user/test/com/google/gwt/requestfactory/client/impl/DeltaValueStoreJsonImplTest.java b/user/test/com/google/gwt/requestfactory/client/impl/DeltaValueStoreJsonImplTest.java
index 8ec80b5..cfb75ae 100644
--- a/user/test/com/google/gwt/requestfactory/client/impl/DeltaValueStoreJsonImplTest.java
+++ b/user/test/com/google/gwt/requestfactory/client/impl/DeltaValueStoreJsonImplTest.java
@@ -78,7 +78,7 @@
   public void testCreate() {
     EntityProxy created = requestFactory.create(SimpleFooProxy.class);
     assertNotNull(((ProxyImpl) created).encodedId());
-    assertNotNull(created.getVersion());
+    assertNotNull(((ProxyImpl) created).version());
 
     DeltaValueStoreJsonImpl deltaValueStore = new DeltaValueStoreJsonImpl(
         valueStore, requestFactory);
@@ -103,7 +103,7 @@
   public void testCreateWithSet() {
     EntityProxy created = requestFactory.create(SimpleFooProxy.class);
     assertNotNull(((ProxyImpl) created).encodedId());
-    assertNotNull(created.getVersion());
+    assertNotNull(((ProxyImpl) created).version());
 
     DeltaValueStoreJsonImpl deltaValueStore = new DeltaValueStoreJsonImpl(
         valueStore, requestFactory);
@@ -211,7 +211,7 @@
 
     JSONObject proxy = proxyWithName.get(SIMPLE_FOO_CLASS_NAME).isObject();
     assertTrue(proxy.containsKey(RequestData.ENCODED_ID_PROPERTY));
-    assertTrue(proxy.containsKey("version"));
+    assertTrue(proxy.containsKey(RequestData.ENCODED_VERSION_PROPERTY));
 
     return proxy;
   }
diff --git a/user/test/com/google/gwt/requestfactory/client/impl/ProxyJsoImplTest.java b/user/test/com/google/gwt/requestfactory/client/impl/ProxyJsoImplTest.java
index 6c797c1..9492010 100644
--- a/user/test/com/google/gwt/requestfactory/client/impl/ProxyJsoImplTest.java
+++ b/user/test/com/google/gwt/requestfactory/client/impl/ProxyJsoImplTest.java
@@ -41,9 +41,9 @@
         "123456789012345678901234567890", "created", "400", RequestData.ENCODED_ID_PROPERTY, "42L"};
 
     String[] literalBits = new String[]{
-        "version", "1", "intId", "4", "shortField", "5", "byteField", "6",
-        "floatField", "12.3456789", "doubleField", "12345.6789", "boolField",
-        "false", "otherBoolField", "true"};
+        RequestData.ENCODED_VERSION_PROPERTY, "1", "intId", "4", "shortField",
+        "5", "byteField", "6", "floatField", "12.3456789", "doubleField",
+        "12345.6789", "boolField", "false", "otherBoolField", "true"};
 
     boolean isFirst = true;
     boolean isLabel = true;
@@ -78,9 +78,11 @@
   }
 
   private static final String ID_VERSION_JSON = "{\""
-      + RequestData.ENCODED_ID_PROPERTY + "\":\"42L\",\"version\":1}";
+      + RequestData.ENCODED_ID_PROPERTY + "\":\"42L\",\""
+      + RequestData.ENCODED_VERSION_PROPERTY + "\":1}";
   private static final String ID_VERSION_JSON2 = "{\""
-      + RequestData.ENCODED_ID_PROPERTY + "\":\"43L\",\"version\":1}";
+      + RequestData.ENCODED_ID_PROPERTY + "\":\"43L\",\""
+      + RequestData.ENCODED_VERSION_PROPERTY + "\":1}";
 
   static ProxyJsoImpl getMinimalJso() {
     return ProxyJsoImpl.create("42L", 1, SimpleRequestFactoryInstance.schema(),
@@ -187,8 +189,10 @@
   }
 
   private void testMinimalJso(ProxyJsoImpl jso) {
-    for (String property : new String[]{RequestData.ENCODED_ID_PROPERTY, "version"}) {
-      assertTrue("expect " + property + " to be defined", jso.isDefined(property));
+    for (String property : new String[]{
+        RequestData.ENCODED_ID_PROPERTY, RequestData.ENCODED_VERSION_PROPERTY}) {
+      assertTrue("expect " + property + " to be defined",
+          jso.isDefined(property));
     }
     for (String property : new String[]{
         "created", "intId", "userName", "password"}) {
@@ -196,7 +200,7 @@
       assertNull(jso.get(property));
     }
     assertEquals("42L", jso.encodedId());
-    assertEquals(new Integer(1), jso.getVersion());
+    assertEquals(new Integer(1), jso.version());
     assertEquals(null, jso.get(SimpleFooProxyProperties.longField));
     assertEquals(null, jso.get(SimpleFooProxyProperties.enumField));
     testSchema(jso);
@@ -207,7 +211,7 @@
         "userName", "password", "charField", "longField", "bigDecimalField",
         "bigIntField", "intId", "shortField", "byteField", "created",
         "doubleField", "floatField", "boolField", "otherBoolField", 
-        "version", RequestData.ENCODED_ID_PROPERTY}) {
+        RequestData.ENCODED_VERSION_PROPERTY, RequestData.ENCODED_ID_PROPERTY}) {
       assertTrue("Expect " + property + " to be defined",
           jso.isDefined(property));
     }
@@ -238,7 +242,7 @@
     assertTrue(jso.get(SimpleFooProxyProperties.otherBoolField));
 
     assertEquals("42L", jso.encodedId());
-    assertEquals(new Integer(1), jso.getVersion());
+    assertEquals(new Integer(1), jso.version());
 
     testSchema(jso);
   }
diff --git a/user/test/com/google/gwt/requestfactory/server/JsonRequestProcessorTest.java b/user/test/com/google/gwt/requestfactory/server/JsonRequestProcessorTest.java
index e8bfc88..639233f 100644
--- a/user/test/com/google/gwt/requestfactory/server/JsonRequestProcessorTest.java
+++ b/user/test/com/google/gwt/requestfactory/server/JsonRequestProcessorTest.java
@@ -268,7 +268,7 @@
     assertEquals(foo.getString("userName"), "GWT");
     assertEquals(foo.getLong("longField"), 8L);
     assertEquals(foo.getInt("enumField"), 0);
-    assertEquals(foo.getInt("version"), 1);
+    assertEquals(foo.getInt(RequestData.ENCODED_VERSION_PROPERTY), 1);
     assertEquals(foo.getBoolean("boolField"), true);
     assertNotNull(foo.getString("!id"));
     assertTrue(foo.has("created"));