Public (konstantin.scheglov@gmail.com):
We need to provide at least some support for @UiField(provided) and
@UiFactory in GWT Designer. At design time we pass "null" as "owner", so
we need to use special design time hooks to create instances of widgets.

Review by rjrjr@google.com
http://gwt-code-reviews.appspot.com/1077802

Review by: sbrubaker@google.com

git-svn-id: https://google-web-toolkit.googlecode.com/svn/trunk@9204 8db76d5a-ed1c-0410-87a9-c151d255dfc7
diff --git a/user/src/com/google/gwt/uibinder/elementparsers/BeanParser.java b/user/src/com/google/gwt/uibinder/elementparsers/BeanParser.java
index 3beb83d..fe2c261 100644
--- a/user/src/com/google/gwt/uibinder/elementparsers/BeanParser.java
+++ b/user/src/com/google/gwt/uibinder/elementparsers/BeanParser.java
@@ -176,9 +176,18 @@
     if (creator != null) {
       String[] args = makeArgsList(requiredValues, creator);
       if (creator instanceof JMethod) { // Factory method
-        String factoryMethod = String.format("owner.%s(%s)", creator.getName(),
-            UiBinderWriter.asCommaSeparatedList(args));
-        writer.setFieldInitializer(fieldName, factoryMethod);
+        JMethod factoryMethod = (JMethod) creator;
+        String initializer;
+        if (writer.getDesignTime().isDesignTime()) {
+          String typeName = factoryMethod.getReturnType().getQualifiedSourceName();
+          initializer = writer.getDesignTime().getProvidedFactory(typeName,
+              factoryMethod.getName(),
+              UiBinderWriter.asCommaSeparatedList(args));
+        } else {
+          initializer = String.format("owner.%s(%s)", factoryMethod.getName(),
+              UiBinderWriter.asCommaSeparatedList(args));
+        }
+        writer.setFieldInitializer(fieldName, initializer);
       } else { // Annotated Constructor
         writer.setFieldInitializerAsConstructor(fieldName, type, args);
       }
diff --git a/user/src/com/google/gwt/uibinder/rebind/DesignTimeUtils.java b/user/src/com/google/gwt/uibinder/rebind/DesignTimeUtils.java
index 5d194c3..1bf98c4 100644
--- a/user/src/com/google/gwt/uibinder/rebind/DesignTimeUtils.java
+++ b/user/src/com/google/gwt/uibinder/rebind/DesignTimeUtils.java
@@ -1,12 +1,12 @@
 /*
  * 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
@@ -39,6 +39,16 @@
   String getPath(Element element);
 
   /**
+   * Returns the source to access "@UiFactory" method.
+   */
+  String getProvidedFactory(String typeName, String methodName, String args);
+
+  /**
+   * Returns the source to access "@UiField(provided)" instance of some object.
+   */
+  String getProvidedField(String typeName, String fieldName);
+
+  /**
    * Returns the design time content of <code>*.ui.xml</code> template to parse,
    * or <code>null</code> if not design time, or this template is not under
    * design.
diff --git a/user/src/com/google/gwt/uibinder/rebind/DesignTimeUtilsImpl.java b/user/src/com/google/gwt/uibinder/rebind/DesignTimeUtilsImpl.java
index 9acd169..85f1db6 100644
--- a/user/src/com/google/gwt/uibinder/rebind/DesignTimeUtilsImpl.java
+++ b/user/src/com/google/gwt/uibinder/rebind/DesignTimeUtilsImpl.java
@@ -1,12 +1,12 @@
 /*
  * 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
@@ -48,17 +48,35 @@
   public void addDeclarations(IndentedWriter w) {
     // handler
     w.write("public static interface DTObjectHandler {");
-    w.write("  void handle(String path, Object object);");
+    {
+      w.indent();
+      w.write("void handle(String path, Object object);");
+      w.write("Object provideFactory(Class rawType, String methodName, Object[] args);");
+      w.write("Object provideField(Class rawType, String fieldName);");
+      w.outdent();
+    }
     w.write("}");
     w.write("public DTObjectHandler dtObjectHandler;");
     // attributes
     w.write("public final java.util.Map dtAttributes = new java.util.HashMap();");
     w.write("private void dtPutAttribute(String key, Object...values) {");
-    w.write("  if (values.length == 1) {");
-    w.write("    dtAttributes.put(key, values[0]);");
-    w.write("  } else {");
-    w.write("    dtAttributes.put(key, java.util.Arrays.asList(values));");
-    w.write("  }");
+    {
+      w.indent();
+      w.write("if (values.length == 1) {");
+      {
+        w.indent();
+        w.write("dtAttributes.put(key, values[0]);");
+        w.outdent();
+      }
+      w.write("} else {");
+      {
+        w.indent();
+        w.write("dtAttributes.put(key, java.util.Arrays.asList(values));");
+        w.outdent();
+      }
+      w.write("}");
+      w.outdent();
+    }
     w.write("}");
   }
 
@@ -70,6 +88,19 @@
     return elementPaths.get(element);
   }
 
+  public String getProvidedFactory(String typeName, String methodName,
+      String args) {
+    return String.format(
+        "(%1$s) dtObjectHandler.provideFactory(%1$s.class, \"%2$s\", new Object[] {%3$s})",
+        typeName, methodName, args);
+  }
+
+  public String getProvidedField(String typeName, String fieldName) {
+    return String.format(
+        "(%1$s) dtObjectHandler.provideField(%1s.class, \"%2$s\")", typeName,
+        fieldName);
+  }
+
   public String getTemplateContent(String path) {
     return System.getProperty("gwt.UiBinder.designTime " + path);
   }
diff --git a/user/src/com/google/gwt/uibinder/rebind/DesignTimeUtilsStub.java b/user/src/com/google/gwt/uibinder/rebind/DesignTimeUtilsStub.java
index 6459e4e..072ccea 100644
--- a/user/src/com/google/gwt/uibinder/rebind/DesignTimeUtilsStub.java
+++ b/user/src/com/google/gwt/uibinder/rebind/DesignTimeUtilsStub.java
@@ -35,6 +35,15 @@
     return null;
   }
 
+  public String getProvidedFactory(String typeName, String methodName,
+      String args) {
+    return null;
+  }
+
+  public String getProvidedField(String typeName, String fieldName) {
+    return null;
+  }
+
   public String getTemplateContent(String path) {
     return null;
   }
diff --git a/user/src/com/google/gwt/uibinder/rebind/UiBinderParser.java b/user/src/com/google/gwt/uibinder/rebind/UiBinderParser.java
index b950a24..bc5c3a3 100644
--- a/user/src/com/google/gwt/uibinder/rebind/UiBinderParser.java
+++ b/user/src/com/google/gwt/uibinder/rebind/UiBinderParser.java
@@ -269,7 +269,15 @@
       }
 
       if (ownerField.isProvided()) {
-        fieldWriter.setInitializer("owner." + ownerField.getName());
+        String initializer;
+        if (writer.getDesignTime().isDesignTime()) {
+          String typeName = ownerField.getType().getRawType().getQualifiedSourceName();
+          initializer = writer.getDesignTime().getProvidedField(typeName,
+              ownerField.getName());
+        } else {
+          initializer = "owner." + ownerField.getName();
+        }
+        fieldWriter.setInitializer(initializer);
         return;
       }
     }
@@ -279,8 +287,15 @@
     JMethod factoryMethod = writer.getOwnerClass().getUiFactoryMethod(
         resourceType);
     if (factoryMethod != null) {
-      fieldWriter.setInitializer(String.format("owner.%s()",
-          factoryMethod.getName()));
+      String initializer;
+      if (writer.getDesignTime().isDesignTime()) {
+        String typeName = factoryMethod.getReturnType().getQualifiedSourceName();
+        initializer = writer.getDesignTime().getProvidedFactory(typeName,
+            factoryMethod.getName(), "");
+      } else {
+        initializer = String.format("owner.%s()", factoryMethod.getName());
+      }
+      fieldWriter.setInitializer(initializer);
     }
 
     /*
diff --git a/user/src/com/google/gwt/uibinder/rebind/UiBinderWriter.java b/user/src/com/google/gwt/uibinder/rebind/UiBinderWriter.java
index 5d9def6..2ae08f1 100644
--- a/user/src/com/google/gwt/uibinder/rebind/UiBinderWriter.java
+++ b/user/src/com/google/gwt/uibinder/rebind/UiBinderWriter.java
@@ -1092,8 +1092,15 @@
 
         // TODO why can this be null?
         if (fieldWriter != null) {
-          fieldManager.lookup(fieldName).setInitializer(
-              formatCode("owner.%1$s", fieldName));
+          String initializer;
+          if (designTime.isDesignTime()) {
+            String typeName = ownerField.getType().getRawType().getQualifiedSourceName();
+            initializer = designTime.getProvidedField(typeName,
+                ownerField.getName());
+          } else {
+            initializer = formatCode("owner.%1$s", fieldName);
+          }
+          fieldManager.lookup(fieldName).setInitializer(initializer);
         }
       }
     }
diff --git a/user/test/com/google/gwt/uibinder/rebind/DesignTimeUtilsTest.java b/user/test/com/google/gwt/uibinder/rebind/DesignTimeUtilsTest.java
index f4d45d2..68200eb 100644
--- a/user/test/com/google/gwt/uibinder/rebind/DesignTimeUtilsTest.java
+++ b/user/test/com/google/gwt/uibinder/rebind/DesignTimeUtilsTest.java
@@ -1,12 +1,12 @@
 /*
  * 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
@@ -153,6 +153,45 @@
   }
 
   /**
+   * Test for {@link DesignTimeUtils#getProvidedField(String, String)}.
+   */
+  public void test_getProvidedField_default() throws Exception {
+    String source = stub.getProvidedField("java.lang.String", "fieldName");
+    assertEquals(null, source);
+  }
+
+  /**
+   * Test for {@link DesignTimeUtils#getProvidedField(String, String)}.
+   */
+  public void test_getProvidedField_designTime() throws Exception {
+    String source = impl.getProvidedField("java.lang.String", "fieldName");
+    assertEquals("(java.lang.String) dtObjectHandler.provideField("
+        + "java.lang.String.class, \"fieldName\")", source);
+  }
+
+  /**
+   * Test for {@link DesignTimeUtils#getProvidedFactory(String, String, String)}
+   * .
+   */
+  public void test_getProvidedFactory_default() throws Exception {
+    String source = stub.getProvidedFactory("java.lang.String", "methodName",
+        "false, 1");
+    assertEquals(null, source);
+  }
+
+  /**
+   * Test for {@link DesignTimeUtils#getProvidedFactory(String, String, String)}
+   * .
+   */
+  public void test_getProvidedFactory_designTime() throws Exception {
+    String source = impl.getProvidedFactory("java.lang.String", "methodName",
+        "false, 1");
+    assertEquals("(java.lang.String) dtObjectHandler.provideFactory("
+        + "java.lang.String.class, \"methodName\", new Object[] {false, 1})",
+        source);
+  }
+
+  /**
    * Test for {@link DesignTimeUtils#getTemplateContent(String)}.
    */
   public void test_getTemplateContent_default() throws Exception {