Tagging 2.1.0-ms3 candidate 2



git-svn-id: https://google-web-toolkit.googlecode.com/svn/tags/2.1.0-ms3@8640 8db76d5a-ed1c-0410-87a9-c151d255dfc7
diff --git a/bikeshed/src/com/google/gwt/sample/expenses/gwt/ui/employee/EmployeeEditActivity.java b/bikeshed/src/com/google/gwt/sample/expenses/gwt/ui/employee/EmployeeEditActivity.java
index 75b9e96..7769099 100644
--- a/bikeshed/src/com/google/gwt/sample/expenses/gwt/ui/employee/EmployeeEditActivity.java
+++ b/bikeshed/src/com/google/gwt/sample/expenses/gwt/ui/employee/EmployeeEditActivity.java
@@ -20,6 +20,7 @@
 import com.google.gwt.app.place.RecordEditView;
 import com.google.gwt.event.shared.EventBus;
 import com.google.gwt.requestfactory.shared.Receiver;
+import com.google.gwt.requestfactory.shared.RecordRequest;
 import com.google.gwt.requestfactory.shared.RequestObject;
 import com.google.gwt.sample.expenses.gwt.request.EmployeeRecord;
 import com.google.gwt.sample.expenses.gwt.request.ExpensesRequestFactory;
@@ -89,9 +90,8 @@
   }
 
   @Override
-  protected void fireFindRequest(Value<Long> id,
-      Receiver<EmployeeRecord> callback) {
-    requests.employeeRequest().findEmployee(id).fire(callback);
+  protected RecordRequest<EmployeeRecord> getFindRequest(Value<Long> id) {
+    return requests.employeeRequest().findEmployee(id);
   }
 
   protected RequestObject<Void> getPersistRequest(EmployeeRecord record) {
diff --git a/bikeshed/src/com/google/gwt/sample/expenses/gwt/ui/report/ReportEditActivity.java b/bikeshed/src/com/google/gwt/sample/expenses/gwt/ui/report/ReportEditActivity.java
index 91586c6..f4b02be 100644
--- a/bikeshed/src/com/google/gwt/sample/expenses/gwt/ui/report/ReportEditActivity.java
+++ b/bikeshed/src/com/google/gwt/sample/expenses/gwt/ui/report/ReportEditActivity.java
@@ -20,6 +20,7 @@
 import com.google.gwt.app.place.RecordEditView;
 import com.google.gwt.event.shared.EventBus;
 import com.google.gwt.requestfactory.shared.Receiver;
+import com.google.gwt.requestfactory.shared.RecordRequest;
 import com.google.gwt.requestfactory.shared.RequestObject;
 import com.google.gwt.sample.expenses.gwt.request.EmployeeRecord;
 import com.google.gwt.sample.expenses.gwt.request.ExpensesRequestFactory;
@@ -89,8 +90,8 @@
   }
   
   @Override
-  protected void fireFindRequest(Value<Long> id, Receiver<ReportRecord> callback) {
-    requests.reportRequest().findReport(id).fire(callback);
+  protected RecordRequest<ReportRecord> getFindRequest(Value<Long> id) {
+    return requests.reportRequest().findReport(id);
   }
 
   protected RequestObject<Void> getPersistRequest(ReportRecord record) {
diff --git a/branch-info.txt b/branch-info.txt
index 2d80365..67d3506 100644
--- a/branch-info.txt
+++ b/branch-info.txt
@@ -16,5 +16,9 @@
 commited as r8611  
   r8619 svn merge https://google-web-toolkit.googlecode.com/svn/trunk -r8618:8619 .
 commited as r8620
+  r8600 svn merge https://google-web-toolkit.googlecode.com/svn/trunk -r8599:8600 .
+commited as r8626
+  r8630, 8631, 8632, 8633 svn merge https://google-web-toolkit.googlecode.com/svn/trunk -r8629:8633 .
+commited as r8634
 r8613: Removed the expenses sample from samples
 
diff --git a/user/build.xml b/user/build.xml
index b9ab352..ef30cdd 100755
--- a/user/build.xml
+++ b/user/build.xml
@@ -59,6 +59,9 @@
     <pathelement location="${gwt.tools.lib}/easymock/easymock.jar"/>
     <pathelement location="${gwt.tools.lib}/easymock/easymockclassextension.jar"/>
     <pathelement location="${gwt.tools.lib}/objectweb/asm-3.1.jar"/>
+    <pathelement location="${gwt.tools.lib}/javax/validation/validation-api-1.0.0.GA.jar" />
+    <pathelement location="${gwt.tools.lib}/javax/validation/validation-api-1.0.0.GA-sources.jar" />
+    <pathelement location="${gwt.tools}/redist/json/r2_20080312/json-1.5.jar" />
     <pathelement location="${gwt.dev.jar}" />
   </path>
 
@@ -108,8 +111,6 @@
         <pathelement location="${javac.out}" />
         <pathelement location="${gwt.tools.lib}/junit/junit-3.8.1.jar" />
         <pathelement location="${gwt.tools.lib}/selenium/selenium-java-client-driver.jar" />
-        <pathelement location="${gwt.tools}/redist/json/r2_20080312/json-1.5.jar" />
-        <pathelement location="${gwt.tools.lib}/javax/validation/validation-api-1.0.0.GA.jar" />
         <path refid="test.extraclasspath" />
       </classpath>
     </gwt.javac>
diff --git a/user/src/com/google/gwt/app/place/AbstractRecordEditActivity.java b/user/src/com/google/gwt/app/place/AbstractRecordEditActivity.java
index 13e918f..d27a8c6 100644
--- a/user/src/com/google/gwt/app/place/AbstractRecordEditActivity.java
+++ b/user/src/com/google/gwt/app/place/AbstractRecordEditActivity.java
@@ -18,6 +18,7 @@
 import com.google.gwt.app.place.ProxyPlace.Operation;
 import com.google.gwt.event.shared.EventBus;
 import com.google.gwt.requestfactory.shared.Receiver;
+import com.google.gwt.requestfactory.shared.RecordRequest;
 import com.google.gwt.requestfactory.shared.RequestFactory;
 import com.google.gwt.requestfactory.shared.RequestObject;
 import com.google.gwt.user.client.Window;
@@ -146,7 +147,6 @@
     toCommit.fire(receiver);
   }
 
-  @SuppressWarnings("unchecked")
   public void start(Display display, EventBus eventBus) {
     this.display = display;
 
@@ -154,11 +154,12 @@
     view.setCreating(creating);
 
     if (creating) {
-      R tempRecord = (R) requests.create(proxyType);
+      R tempRecord = requests.create(proxyType);
       futureId = tempRecord.getId();
       doStart(display, tempRecord);
     } else {
-      fireFindRequest(Value.of(getRecord().getId()), new Receiver<R>() {
+      RecordRequest<R> findRequest = getFindRequest(Value.of(getRecord().getId()));
+      findRequest.with(getView().getPaths()).fire(new Receiver<R>() {
         public void onSuccess(R record, Set<SyncResult> syncResults) {
           if (AbstractRecordEditActivity.this.display != null) {
             doStart(AbstractRecordEditActivity.this.display, record);
@@ -189,7 +190,7 @@
   /**
    * Called to fetch the details of the edited record.
    */
-  protected abstract void fireFindRequest(Value<Long> id, Receiver<R> callback);
+  protected abstract RecordRequest<R> getFindRequest(Value<Long> id);
 
   protected abstract RequestObject<Void> getPersistRequest(R record);
 
diff --git a/user/src/com/google/gwt/requestfactory/client/impl/ClientRequestHelper.java b/user/src/com/google/gwt/requestfactory/client/impl/ClientRequestHelper.java
index 0ee5ffc..49c1823 100644
--- a/user/src/com/google/gwt/requestfactory/client/impl/ClientRequestHelper.java
+++ b/user/src/com/google/gwt/requestfactory/client/impl/ClientRequestHelper.java
@@ -47,7 +47,11 @@
     }-*/;
 
     private native String toJsonString()/*-{
-      return $wnd.JSON.stringify(this);
+      var gwt = this.__gwt_ObjectId;
+      delete this.__gwt_ObjectId;
+      var rtn = $wnd.JSON.stringify(this);
+      this.__gwt_ObjectId = gwt;
+      return rtn;
     }-*/;
   }
 
diff --git a/user/src/com/google/gwt/requestfactory/client/impl/DeltaValueStoreJsonImpl.java b/user/src/com/google/gwt/requestfactory/client/impl/DeltaValueStoreJsonImpl.java
index c27f61a..c3a81f8 100644
--- a/user/src/com/google/gwt/requestfactory/client/impl/DeltaValueStoreJsonImpl.java
+++ b/user/src/com/google/gwt/requestfactory/client/impl/DeltaValueStoreJsonImpl.java
@@ -273,11 +273,8 @@
     RecordJsoImpl rawMasterRecord = master.records.get(recordKey);
     WriteOperation priorOperation = operations.get(recordKey);
     if (rawMasterRecord == null && priorOperation == null) {
-      // it was a create on RF that has not been pulled in to the DVS.
-      RecordJsoImpl oldRecord = requestFactory.creates.remove(recordKey);
-      assert oldRecord != null;
       operations.put(recordKey, WriteOperation.CREATE);
-      creates.put(recordKey, oldRecord);
+      creates.put(recordKey, recordImpl.asJso());
       priorOperation = WriteOperation.CREATE;
     }
     if (priorOperation == null) {
@@ -322,16 +319,6 @@
   String toJson() {
     used = true;
 
-    /*
-     * pull the creates that only the requestFactory knows about.
-     */
-    for (RecordKey recordKey : requestFactory.creates.keySet()) {
-      RecordJsoImpl oldRecord = requestFactory.creates.remove(recordKey);
-      assert oldRecord != null;
-      operations.put(recordKey, WriteOperation.CREATE);
-      creates.put(recordKey, oldRecord);
-    }
-
     StringBuffer jsonData = new StringBuffer("{");
     for (WriteOperation writeOperation : new WriteOperation[] {
         WriteOperation.CREATE, WriteOperation.UPDATE}) {
diff --git a/user/src/com/google/gwt/requestfactory/client/impl/RecordJsoImpl.java b/user/src/com/google/gwt/requestfactory/client/impl/RecordJsoImpl.java
index 4209d0a..a41f5c0 100644
--- a/user/src/com/google/gwt/requestfactory/client/impl/RecordJsoImpl.java
+++ b/user/src/com/google/gwt/requestfactory/client/impl/RecordJsoImpl.java
@@ -359,11 +359,14 @@
     delete this.__rf;
     var vs = this.__vs;
     delete this.__vs;
+    var gwt = this.__gwt_ObjectId;
+    delete this.__gwt_ObjectId;
     // TODO verify that the stringify() from json2.js works on IE
     var rtn = $wnd.JSON.stringify(this);
     this.__key = key;
     this.__rf = rf;
     this.__vs = vs;
+    this.__gwt_ObjectId = gwt;
     return rtn;
   }-*/;
 
diff --git a/user/src/com/google/gwt/requestfactory/client/impl/RequestFactoryJsonImpl.java b/user/src/com/google/gwt/requestfactory/client/impl/RequestFactoryJsonImpl.java
index 5b4af09..3228494 100644
--- a/user/src/com/google/gwt/requestfactory/client/impl/RequestFactoryJsonImpl.java
+++ b/user/src/com/google/gwt/requestfactory/client/impl/RequestFactoryJsonImpl.java
@@ -31,8 +31,6 @@
 import com.google.gwt.valuestore.shared.Record;
 import com.google.gwt.valuestore.shared.WriteOperation;
 
-import java.util.HashMap;
-import java.util.Map;
 import java.util.logging.Level;
 import java.util.logging.Logger;
 
@@ -62,8 +60,6 @@
 
   private long currentFutureId = 0;
 
-  final Map<RecordKey, RecordJsoImpl> creates = new HashMap<RecordKey, RecordJsoImpl>();
-
   private ValueStoreJsonImpl valueStore;
 
   private EventBus eventBus;
@@ -204,8 +200,6 @@
     Long futureId = ++currentFutureId;
     RecordJsoImpl newRecord = RecordJsoImpl.create(futureId, INITIAL_VERSION,
         schema);
-    RecordKey recordKey = new RecordKey(newRecord, IS_FUTURE);
-    creates.put(recordKey, newRecord);
     return schema.create(newRecord, IS_FUTURE);
   }
 
diff --git a/user/src/com/google/gwt/requestfactory/server/JsonRequestProcessor.java b/user/src/com/google/gwt/requestfactory/server/JsonRequestProcessor.java
index a0974cf..1f0d454 100644
--- a/user/src/com/google/gwt/requestfactory/server/JsonRequestProcessor.java
+++ b/user/src/com/google/gwt/requestfactory/server/JsonRequestProcessor.java
@@ -149,6 +149,7 @@
    * 
    * <li>Find the changes that need to be sent back.
    */
+  private Map<EntityKey, Object> cachedEntityLookup = new HashMap<EntityKey, Object>();
   private Set<EntityKey> involvedKeys = new HashSet<EntityKey>();
   private Map<EntityKey, DvsData> dvsDataMap = new HashMap<EntityKey, DvsData>();
   private Map<EntityKey, SerializedEntity> beforeDataMap = new HashMap<EntityKey, SerializedEntity>();
@@ -287,6 +288,7 @@
       if (service != null) {
         Class<?> sClass = service.value();
         EntityKey entityKey = getEntityKey(parameterValue.toString());
+
         DvsData dvsData = dvsDataMap.get(entityKey);
         try {
           if (dvsData != null) {
@@ -294,7 +296,9 @@
                 dvsData.jsonObject, dvsData.writeOperation);
             return entityData.entityInstance;
           } else {
-            Method findMeth = sClass.getMethod(getMethodNameFromPropertyName(sClass.getSimpleName(), "find"), Long.class);
+            Method findMeth = sClass.getMethod(
+                getMethodNameFromPropertyName(sClass.getSimpleName(), "find"),
+                Long.class);
             return findMeth.invoke(null, entityKey.id);
           }
         } catch (NoSuchMethodException e) {
@@ -396,11 +400,14 @@
       Object entityInstance = getEntityInstance(writeOperation, entity,
           recordObject.get("id"), propertiesInRecord.get("id"));
 
+      cachedEntityLookup.put(entityKey, entityInstance);
+
       Set<ConstraintViolation<Object>> violations = Collections.emptySet();
       Iterator<?> keys = recordObject.keys();
       while (keys.hasNext()) {
         String key = (String) keys.next();
         Class<?> propertyType = propertiesInRecord.get(key);
+        Class<?> dtoType = propertiesToDTO.get(key);
         if (writeOperation == WriteOperation.CREATE && ("id".equals(key))) {
           Long id = generateIdForCreate(key);
           if (id != null) {
@@ -408,8 +415,20 @@
                 propertyType).invoke(entityInstance, id);
           }
         } else {
-          Object propertyValue = getPropertyValueFromRequest(recordObject, key,
-              propertiesToDTO.get(key));
+          Object propertyValue = null;
+          if (Record.class.isAssignableFrom(dtoType)) {
+            EntityKey propKey = getEntityKey(recordObject.getString(key));
+            Object cacheValue = cachedEntityLookup.get(propKey);
+            if (cachedEntityLookup.containsKey(propKey)) {
+              propertyValue = cacheValue;
+            } else {
+              propertyValue = getPropertyValueFromRequest(recordObject, key,
+               propertiesToDTO.get(key));
+            }
+          } else {
+             propertyValue = getPropertyValueFromRequest(recordObject, key,
+               propertiesToDTO.get(key));
+          }
           entity.getMethod(getMethodNameFromPropertyName(key, "set"),
               propertyType).invoke(entityInstance, propertyValue);
         }
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 0921b4d..c4a458a 100644
--- a/user/test/com/google/gwt/requestfactory/client/impl/DeltaValueStoreJsonImplTest.java
+++ b/user/test/com/google/gwt/requestfactory/client/impl/DeltaValueStoreJsonImplTest.java
@@ -137,7 +137,8 @@
     DeltaValueStoreJsonImpl deltaValueStore = new DeltaValueStoreJsonImpl(
         valueStore, requestFactory);
     String json = deltaValueStore.toJson();
-    testAndGetChangeRecord(json, WriteOperation.CREATE);
+    JSONObject jsonObject = (JSONObject) JSONParser.parseLenient(json);
+    assertFalse(jsonObject.containsKey(WriteOperation.CREATE.name()));
   }
 
   public void testCreateWithSet() {
diff --git a/user/test/com/google/gwt/requestfactory/client/impl/SimpleFooRecordImpl.java b/user/test/com/google/gwt/requestfactory/client/impl/SimpleFooRecordImpl.java
index 301bb8d..63a8e32 100644
--- a/user/test/com/google/gwt/requestfactory/client/impl/SimpleFooRecordImpl.java
+++ b/user/test/com/google/gwt/requestfactory/client/impl/SimpleFooRecordImpl.java
@@ -103,6 +103,10 @@
     return get(enumField);
   }
 
+  public SimpleFooRecord getFooField() {
+    return (SimpleFooRecord) getValueStore().getRecordBySchemaAndId(SCHEMA, (Long) (Object) get(fooField));
+  }
+
   public java.lang.Integer getIntId() {
     return get(intId);
   }
@@ -131,6 +135,10 @@
     // ignore
   }
 
+  public void setFooField(SimpleFooRecord fooField) {
+    // ignore
+  }
+
   public void setIntId(Integer intId) {
     // ignore
   }
diff --git a/user/test/com/google/gwt/valuestore/client/RequestFactoryTest.java b/user/test/com/google/gwt/valuestore/client/RequestFactoryTest.java
index 3ac6136..02733ec 100644
--- a/user/test/com/google/gwt/valuestore/client/RequestFactoryTest.java
+++ b/user/test/com/google/gwt/valuestore/client/RequestFactoryTest.java
@@ -204,6 +204,26 @@
     });
   }
 
+   public void testPersistRecursiveRelation() {
+    final SimpleRequestFactory req = GWT.create(SimpleRequestFactory.class);
+    HandlerManager hm = new HandlerManager(null);
+    req.init(hm);
+    delayTestFinish(5000);
+
+    SimpleFooRecord rayFoo = req.create(SimpleFooRecord.class);
+    final RequestObject<SimpleFooRecord> persistRay = req.simpleFooRequest().persistAndReturnSelf(
+        rayFoo);
+    rayFoo = persistRay.edit(rayFoo);
+    rayFoo.setUserName("Ray");
+    rayFoo.setFooField(rayFoo);
+    persistRay.fire(new Receiver<SimpleFooRecord>() {
+      public void onSuccess(final SimpleFooRecord persistedRay,
+          Set<SyncResult> ignored) {
+        finishTest();
+      }
+    });
+  }
+
   public void testPersistRelation() {
     final SimpleRequestFactory req = GWT.create(SimpleRequestFactory.class);
     HandlerManager hm = new HandlerManager(null);
diff --git a/user/test/com/google/gwt/valuestore/server/SimpleFoo.java b/user/test/com/google/gwt/valuestore/server/SimpleFoo.java
index 27a967f..aa7be4c 100644
--- a/user/test/com/google/gwt/valuestore/server/SimpleFoo.java
+++ b/user/test/com/google/gwt/valuestore/server/SimpleFoo.java
@@ -88,6 +88,8 @@
 
   private SimpleBar barField;
 
+  private SimpleFoo fooField;
+
   public SimpleFoo() {
     intId = 42;
     version = 1;
@@ -115,6 +117,10 @@
     return enumField;
   }
 
+  public SimpleFoo getFooField() {
+    return fooField;
+  }
+
   public Long getId() {
     return id;
   }
@@ -164,6 +170,10 @@
     this.enumField = enumField;
   }
 
+  public void setFooField(SimpleFoo fooField) {
+    this.fooField = fooField;
+  }
+
   public void setId(Long id) {
     this.id = id;
   }
diff --git a/user/test/com/google/gwt/valuestore/shared/SimpleFooRecord.java b/user/test/com/google/gwt/valuestore/shared/SimpleFooRecord.java
index b0cf7a2..a161c2b 100644
--- a/user/test/com/google/gwt/valuestore/shared/SimpleFooRecord.java
+++ b/user/test/com/google/gwt/valuestore/shared/SimpleFooRecord.java
@@ -42,6 +42,9 @@
   Property<SimpleBarRecord> barField = new Property<SimpleBarRecord>("barField",
       SimpleBarRecord.class);
 
+  Property<SimpleFooRecord> fooField = new Property<SimpleFooRecord>("fooField",
+      SimpleFooRecord.class);
+
   SimpleBarRecord getBarField();
 
   Boolean getBoolField();
@@ -50,6 +53,8 @@
 
   SimpleEnum getEnumField();
 
+  SimpleFooRecord getFooField();
+
   Integer getIntId();
 
   Long getLongField();
@@ -64,6 +69,8 @@
 
   void setCreated(Date created);
 
+  void setFooField(SimpleFooRecord fooField);
+
   void setIntId(Integer intId);
 
   void setLongField(Long longField);