Revision: 8384
Author: rj...@google.com
Date: Thu Jul 15 04:01:13 2010
Log: Adds design time hooks to UiBinder for GWT Designer, or any other tool
that can find a use for them. See discussion in
http://groups.google.com/group/google-web-toolkit-contributors/browse_thread/thread/3e9b2193531fb0b4/69829d19f0573be1

Patch by konstantin.scheg...@gmail.com
Review by rj...@google.com
http://gwt-code-reviews.appspot.com/693801/show

Review by: robertvaw...@google.com
http://code.google.com/p/google-web-toolkit/source/detail?r=8384

Added:
 /trunk/user/src/com/google/gwt/uibinder/rebind/DesignTimeUtils.java
 /trunk/user/src/com/google/gwt/uibinder/rebind/Statements.java
 /trunk/user/test/com/google/gwt/uibinder/rebind/DesignTimeUtilsTest.java
Modified:
 /trunk/user/src/com/google/gwt/uibinder/elementparsers/BeanParser.java
 /trunk/user/src/com/google/gwt/uibinder/elementparsers/CellPanelParser.java
 /trunk/user/src/com/google/gwt/uibinder/elementparsers/UIObjectParser.java
 /trunk/user/src/com/google/gwt/uibinder/rebind/UiBinderGenerator.java
 /trunk/user/src/com/google/gwt/uibinder/rebind/UiBinderWriter.java
 /trunk/user/src/com/google/gwt/uibinder/rebind/XMLElement.java
 /trunk/user/test/com/google/gwt/uibinder/UiBinderJreSuite.java

=======================================
--- /dev/null
+++ /trunk/user/src/com/google/gwt/uibinder/rebind/DesignTimeUtils.java Thu Jul 15 04:01:13 2010
@@ -0,0 +1,133 @@
+/*
+ * 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.uibinder.rebind;
+
+import org.w3c.dom.Document;
+import org.w3c.dom.Element;
+import org.w3c.dom.Node;
+import org.w3c.dom.NodeList;
+
+import java.beans.Beans;
+import java.util.WeakHashMap;
+
+/**
+ * Utilities used for implementing design time support of UiBinder.
+ */
+public class DesignTimeUtils {
+ private static final WeakHashMap<Element, String> elementPaths = new WeakHashMap<Element, String>();
+
+  /**
+   * Adds declarations for design time artifacts.
+   */
+  public static void addDeclarations(IndentedWriter w) {
+    if (!isDesignTime()) {
+      return;
+    }
+ w.write("public static interface DTObjectHandler {void handle(String path, Object object);}");
+    w.write("public DTObjectHandler dtObjectHandler;");
+ w.write("public final java.util.Map dtAttributes = new java.util.HashMap();");
+  }
+
+  /**
+   * @return the name of "Impl", unique each time if it is design time.
+   */
+  public static String getImplName(String implName) {
+    if (isDesignTime()) {
+      implName += "_designTime" + System.currentTimeMillis();
+    }
+    return implName;
+  }
+
+  /**
+   * @return the path of given {...@link Element}.
+   */
+  public static String getPath(Element element) {
+    return elementPaths.get(element);
+  }
+
+  /**
+ * @return 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.
+   */
+  public static String getTemplateContent(String path) {
+    if (DesignTimeUtils.isDesignTime()) {
+      return System.getProperty("gwt.UiBinder.designTime " + path);
+    }
+    return null;
+  }
+
+  /**
+   * Notifies tool about <code>UIObject</code> creation.
+   */
+  public static void handleUIObject(Statements writer,
+      XMLElement elem, String fieldName) {
+    if (!isDesignTime()) {
+      return;
+    }
+    writer.addStatement(
+        "if (dtObjectHandler != null) dtObjectHandler.handle(\"%s\", %s);",
+        elem.getDesignTimePath(), fieldName);
+  }
+
+  /**
+   * @return <code>true</code> if UiBinder works now in design time, so
+ * additional information should be provided in generated classes.
+   */
+  public static boolean isDesignTime() {
+    return Beans.isDesignTime();
+  }
+
+  /**
+   * Remembers value of attribute, for given {...@link XMLElement}.
+   */
+  public static void putAttribute(Statements writer,
+      XMLElement elem, String name, String value) {
+    if (!isDesignTime()) {
+      return;
+    }
+    String path = elem.getDesignTimePath();
+    String key = path + " " + name;
+    writer.addStatement("dtAttributes.put(\"%s\", %s);", key, value);
+  }
+
+  /**
+ * Fills {...@value #elementPaths} with paths for given and child {...@link Element}
+   * s.
+   */
+  public static void rememberPathForElements(Document doc) {
+    if (!isDesignTime()) {
+      return;
+    }
+    rememberPathForElements(doc.getDocumentElement(), "0");
+  }
+
+  /**
+ * Recursive implementation of {...@link #rememberPathForElements(Document)}.
+   */
+ private static void rememberPathForElements(Element element, String path) {
+    elementPaths.put(element, path);
+    NodeList childNodes = element.getChildNodes();
+    int elementIndex = 0;
+    for (int i = 0; i < childNodes.getLength(); ++i) {
+      Node childNode = childNodes.item(i);
+      if (childNode.getNodeType() == Node.ELEMENT_NODE) {
+        Element childElement = (Element) childNode;
+        rememberPathForElements(childElement, path + "/" + elementIndex++);
+      }
+    }
+  }
+}
=======================================
--- /dev/null
+++ /trunk/user/src/com/google/gwt/uibinder/rebind/Statements.java Thu Jul 15 04:01:13 2010
@@ -0,0 +1,57 @@
+/*
+ * 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.uibinder.rebind;
+
+/**
+ * Accepts Java statements to be included in generated UiBinder implementations.
+ */
+public interface Statements {
+
+  Statements EMPTY = new Statements() {
+
+    public void addDetachStatement(String format, Object... args) {
+    }
+
+    public void addInitStatement(String format, Object... params) {
+    }
+
+    public void addStatement(String format, Object... args) {
+    }
+  };
+
+  /**
+ * Add a statement to be executed right after the current attached element is + * detached. This is useful for doing things that might be expensive while the
+   * element is attached to the DOM.
+   *
+   * @param format
+   * @param args
+   * @see #beginAttachedSection(String)
+   */
+  void addDetachStatement(String format, Object... args);
+
+  /**
+ * Add a statement to be run after everything has been instantiated, in the
+   * style of {...@link String#format}.
+   */
+  void addInitStatement(String format, Object... params);
+
+  /**
+ * Adds a statement to the block run after fields are declared, in the style
+   * of {...@link String#format}.
+   */
+  void addStatement(String format, Object... args);
+}
=======================================
--- /dev/null
+++ /trunk/user/test/com/google/gwt/uibinder/rebind/DesignTimeUtilsTest.java Thu Jul 15 04:01:13 2010
@@ -0,0 +1,326 @@
+/*
+ * 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.uibinder.rebind;
+
+import com.google.gwt.core.ext.TreeLogger;
+import com.google.gwt.dev.javac.impl.MockResourceOracle;
+
+import junit.framework.TestCase;
+
+import org.w3c.dom.Document;
+import org.w3c.dom.Element;
+import org.w3c.dom.NodeList;
+import org.xml.sax.SAXParseException;
+
+import java.beans.Beans;
+import java.io.PrintWriter;
+import java.io.StringWriter;
+import java.util.ArrayList;
+import java.util.List;
+
+/**
+ * Tests for {...@link DesignTimeUtils}.
+ */
+public class DesignTimeUtilsTest extends TestCase {
+  private static final W3cDomHelper docHelper = new W3cDomHelper(
+      TreeLogger.NULL, new MockResourceOracle());
+
+ ////////////////////////////////////////////////////////////////////////////
+  //
+  // Life cycle
+  //
+ ////////////////////////////////////////////////////////////////////////////
+  @Override
+  protected void tearDown() throws Exception {
+    Beans.setDesignTime(false);
+    super.tearDown();
+  }
+
+ ////////////////////////////////////////////////////////////////////////////
+  //
+  // isDesignTime()
+  //
+ ///////////////////////////////////////////////////////////////////////////
+  /**
+   * Test for {...@link DesignTimeUtils#isDesignTime()}.
+   */
+  public void test_isDesignTime_default() {
+    assertFalse(DesignTimeUtils.isDesignTime());
+  }
+
+  /**
+   * Test for {...@link DesignTimeUtils#isDesignTime()}.
+   */
+  public void test_isDesignTime_designTime() {
+    Beans.setDesignTime(true);
+    assertTrue(DesignTimeUtils.isDesignTime());
+  }
+
+ ////////////////////////////////////////////////////////////////////////////
+  //
+  // addDeclarations()
+  //
+ ///////////////////////////////////////////////////////////////////////////
+  /**
+   * Test for {...@link DesignTimeUtils#addDeclarations(IndentedWriter)}.
+   */
+  public void test_addDeclarations_default() {
+    String result = call_addDeclarations();
+    assertEquals("", result);
+  }
+
+  /**
+   * Test for {...@link DesignTimeUtils#addDeclarations(IndentedWriter)}.
+   */
+  public void test_addDeclarations_designTime() {
+    Beans.setDesignTime(true);
+    String result = call_addDeclarations();
+    String lineSeparator = System.getProperty("line.separator");
+    assertEquals(
+ "public static interface DTObjectHandler {void handle(String path, Object object);}"
+            + lineSeparator
+            + "public DTObjectHandler dtObjectHandler;"
+            + lineSeparator
+ + "public final java.util.Map dtAttributes = new java.util.HashMap();"
+            + lineSeparator, result);
+  }
+
+  private static String call_addDeclarations() {
+    StringWriter sw = new StringWriter();
+ IndentedWriter indentedWriter = new IndentedWriter(new PrintWriter(sw));
+    DesignTimeUtils.addDeclarations(indentedWriter);
+    return sw.toString();
+  }
+
+ ////////////////////////////////////////////////////////////////////////////
+  //
+  // getImplName()
+  //
+ ///////////////////////////////////////////////////////////////////////////
+  /**
+   * Test for {...@link DesignTimeUtils#getImplName(String)}.
+   */
+  public void test_getImplName_default() {
+    String basicName = "MyBinderImpl";
+    String result = DesignTimeUtils.getImplName(basicName);
+    assertEquals(basicName, result);
+  }
+
+  /**
+   * Test for {...@link DesignTimeUtils#getImplName(String)}.
+   */
+  public void test_getImplName_designTime() {
+    Beans.setDesignTime(true);
+    String basicName = "MyBinderImpl";
+    String result = DesignTimeUtils.getImplName(basicName);
+    // has "_designTime" substring
+    String prefix = basicName + "_designTime";
+    assertTrue(result.startsWith(prefix));
+    // suffix is current time plus/minus 1 hour, so generates unique names
+    long suffix = Long.parseLong(result.substring(prefix.length()));
+    long delta = System.currentTimeMillis() - suffix;
+    assertTrue(Math.abs(delta) < 1000 * 3600);
+  }
+
+ ////////////////////////////////////////////////////////////////////////////
+  //
+  // Path
+  //
+ ///////////////////////////////////////////////////////////////////////////
+  /**
+   * Test for {...@link DesignTimeUtils#getPath(Element)} and related methods.
+   */
+  public void test_path_default() throws SAXParseException {
+ Document doc = docHelper.documentFor("<root><first/><second/></root>", null);
+    DesignTimeUtils.rememberPathForElements(doc);
+    Element first = getChildElement(doc.getDocumentElement(), "first");
+    Element second = getChildElement(doc.getDocumentElement(), "second");
+    assertEquals(null, DesignTimeUtils.getPath(first));
+    assertEquals(null, DesignTimeUtils.getPath(second));
+  }
+
+  /**
+   * Test for {...@link DesignTimeUtils#getPath(Element)} and related methods.
+   */
+  public void test_path_designTime() throws SAXParseException {
+    Beans.setDesignTime(true);
+    Document doc = docHelper.documentFor(
+        "<root><first/><second><subSecond/></second></root>", null);
+    DesignTimeUtils.rememberPathForElements(doc);
+    Element first = getChildElement(doc.getDocumentElement(), "first");
+    Element second = getChildElement(doc.getDocumentElement(), "second");
+    Element subSecond = getChildElement(second, "subSecond");
+    assertEquals("0/0", DesignTimeUtils.getPath(first));
+    assertEquals("0/1", DesignTimeUtils.getPath(second));
+    assertEquals("0/1/0", DesignTimeUtils.getPath(subSecond));
+  }
+
+ ////////////////////////////////////////////////////////////////////////////
+  //
+  // getTemplateContent()
+  //
+ ///////////////////////////////////////////////////////////////////////////
+  /**
+   * Test for {...@link DesignTimeUtils#getTemplateContent(String)}.
+   */
+  public void test_getTemplateContent_default() {
+    String path = "the/path";
+    assertEquals(null, DesignTimeUtils.getTemplateContent(path));
+  }
+
+  /**
+   * Test for {...@link DesignTimeUtils#getTemplateContent(String)}.
+   */
+  public void test_getTemplateContent_designTime() {
+    Beans.setDesignTime(true);
+    String path = "the/path";
+    String key = "gwt.UiBinder.designTime " + path;
+    try {
+      String content = "myContent";
+      System.setProperty(key, content);
+      assertEquals(content, DesignTimeUtils.getTemplateContent(path));
+    } finally {
+      System.clearProperty(key);
+    }
+  }
+
+ ////////////////////////////////////////////////////////////////////////////
+  //
+  // handleUIObject()
+  //
+ ///////////////////////////////////////////////////////////////////////////
+  /**
+   * Test for
+   * {...@link DesignTimeUtils#handleUIObject(Statements, XMLElement, String)}
+   * .
+   */
+  public void test_handleUIObject_default() {
+    WriterStatements writer = new WriterStatements();
+    DesignTimeUtils.handleUIObject(writer, null, "myField");
+    assertEquals(0, writer.statements.size());
+  }
+
+  /**
+   * Test for
+   * {...@link DesignTimeUtils#handleUIObject(Statements, XMLElement, String)}
+   * .
+   */
+  public void test_handleUIObject_designTime() throws SAXParseException {
+    Beans.setDesignTime(true);
+    // prepare XMLElement
+    XMLElement element;
+    {
+      Document doc = docHelper.documentFor("<root><first/></root>", null);
+      DesignTimeUtils.rememberPathForElements(doc);
+      Element first = getChildElement(doc.getDocumentElement(), "first");
+      element = createXMLElement(first);
+    }
+    // prepare statements
+    List<String> statements;
+    {
+      WriterStatements writer = new WriterStatements();
+      DesignTimeUtils.handleUIObject(writer, element, "myField");
+      statements = writer.statements;
+    }
+    // validate
+    assertEquals(1, statements.size());
+    assertEquals(
+ "if (dtObjectHandler != null) dtObjectHandler.handle(\"0/0\", myField);",
+        statements.get(0));
+  }
+
+ ////////////////////////////////////////////////////////////////////////////
+  //
+  // putAttribute()
+  //
+ ///////////////////////////////////////////////////////////////////////////
+  /**
+   * Test for
+ * {...@link DesignTimeUtils#putAttribute(Statements, XMLElement, String, String)}
+   * .
+   */
+  public void test_putAttribute_default() {
+    WriterStatements writer = new WriterStatements();
+    DesignTimeUtils.putAttribute(writer, null, "name", "value");
+    assertEquals(0, writer.statements.size());
+  }
+
+  /**
+   * Test for
+ * {...@link DesignTimeUtils#putAttribute(Statements, XMLElement, String, String)}
+   * .
+   */
+  public void test_putAttribute_designTime() throws SAXParseException {
+    Beans.setDesignTime(true);
+    // prepare XMLElement
+    XMLElement element;
+    {
+      Document doc = docHelper.documentFor("<root><first/></root>", null);
+      DesignTimeUtils.rememberPathForElements(doc);
+      Element first = getChildElement(doc.getDocumentElement(), "first");
+      element = createXMLElement(first);
+    }
+    // prepare statements
+    List<String> statements;
+    {
+      WriterStatements writer = new WriterStatements();
+      DesignTimeUtils.putAttribute(writer, element, "name", "value");
+      statements = writer.statements;
+    }
+    // validate
+    assertEquals(1, statements.size());
+ assertEquals("dtAttributes.put(\"0/0 name\", value);", statements.get(0));
+  }
+
+ ////////////////////////////////////////////////////////////////////////////
+  //
+  // Utilities
+  //
+ ///////////////////////////////////////////////////////////////////////////
+
+  /**
+   * @return the only child {...@link Element} with given tag name.
+   */
+  private static Element getChildElement(Element parent, String name) {
+    NodeList elements = parent.getElementsByTagName(name);
+    assertEquals(1, elements.getLength());
+    return (Element) elements.item(0);
+  }
+
+  /**
+   * @return the {...@link XMLElement} wrapper for given {...@link Element}.
+   */
+  private static XMLElement createXMLElement(Element elem) {
+    return new XMLElement(elem, null, null, null, null, null);
+  }
+
+  /**
+   * Implementation of {...@link Statements} for simple statements.
+   */
+  private static class WriterStatements implements Statements {
+    List<String> statements = new ArrayList<String>();
+
+    public void addDetachStatement(String format, Object... args) {
+    }
+
+    public void addInitStatement(String format, Object... params) {
+    }
+
+    public void addStatement(String format, Object... args) {
+      statements.add(String.format(format, args));
+    }
+  };
+}
=======================================
--- /trunk/user/src/com/google/gwt/uibinder/elementparsers/BeanParser.java Wed Jul 14 07:07:23 2010 +++ /trunk/user/src/com/google/gwt/uibinder/elementparsers/BeanParser.java Thu Jul 15 04:01:13 2010
@@ -21,6 +21,7 @@
 import com.google.gwt.core.ext.typeinfo.JMethod;
 import com.google.gwt.core.ext.typeinfo.JParameter;
 import com.google.gwt.core.ext.typeinfo.JType;
+import com.google.gwt.uibinder.rebind.DesignTimeUtils;
 import com.google.gwt.uibinder.rebind.UiBinderWriter;
 import com.google.gwt.uibinder.rebind.XMLAttribute;
 import com.google.gwt.uibinder.rebind.XMLElement;
@@ -105,8 +106,7 @@

         if (setter == null || !(params.length == 1)
             || !isString(writer, params[0].getType())) {
-          writer.die(elem, "No method found to apply message attribute %s",
-              key);
+ writer.die(elem, "No method found to apply message attribute %s", key);
         } else {
           setterValues.put(key, value);
         }
@@ -178,9 +178,12 @@
       }
     }

-    for (String propertyName : setterValues.keySet()) {
+    for (Map.Entry<String, String> entry : setterValues.entrySet()) {
+      String propertyName = entry.getKey();
+      String value = entry.getValue();
writer.addStatement("%s.set%s(%s);", fieldName, initialCap(propertyName),
-          setterValues.get(propertyName));
+          value);
+      DesignTimeUtils.putAttribute(writer, elem, propertyName, value);
     }
   }

=======================================
--- /trunk/user/src/com/google/gwt/uibinder/elementparsers/CellPanelParser.java Mon Jun 7 12:20:31 2010 +++ /trunk/user/src/com/google/gwt/uibinder/elementparsers/CellPanelParser.java Thu Jul 15 04:01:13 2010
@@ -17,6 +17,7 @@

 import com.google.gwt.core.ext.UnableToCompleteException;
 import com.google.gwt.core.ext.typeinfo.JClassType;
+import com.google.gwt.uibinder.rebind.DesignTimeUtils;
 import com.google.gwt.uibinder.rebind.UiBinderWriter;
 import com.google.gwt.uibinder.rebind.XMLElement;
import com.google.gwt.user.client.ui.HasHorizontalAlignment.HorizontalAlignmentConstant;
@@ -54,12 +55,16 @@
String value = cellElem.consumeAttribute(HALIGN_ATTR, hAlignConstantType);
       writer.addStatement("%1$s.setCellHorizontalAlignment(%2$s, %3$s);",
           fieldName, childFieldName, value);
+ DesignTimeUtils.putAttribute(writer, cellElem, "*Cell." + HALIGN_ATTR,
+          value);
     }

     if (cellElem.hasAttribute(VALIGN_ATTR)) {
String value = cellElem.consumeAttribute(VALIGN_ATTR, vAlignConstantType);
       writer.addStatement("%1$s.setCellVerticalAlignment(%2$s, %3$s);",
           fieldName, childFieldName, value);
+ DesignTimeUtils.putAttribute(writer, cellElem, "*Cell." + VALIGN_ATTR,
+          value);
     }

     // Parse width and height attributes.
@@ -67,12 +72,16 @@
       String value = cellElem.consumeStringAttribute(WIDTH_ATTR);
       writer.addStatement("%1$s.setCellWidth(%2$s, %3$s);", fieldName,
           childFieldName, value);
+      DesignTimeUtils.putAttribute(writer, cellElem, "*Cell." + WIDTH_ATTR,
+          value);
     }

     if (cellElem.hasAttribute(HEIGHT_ATTR)) {
       String value = cellElem.consumeStringAttribute(HEIGHT_ATTR);
       writer.addStatement("%1$s.setCellHeight(%2$s, %3$s);", fieldName,
           childFieldName, value);
+ DesignTimeUtils.putAttribute(writer, cellElem, "*Cell." + HEIGHT_ATTR,
+          value);
     }
   }

=======================================
--- /trunk/user/src/com/google/gwt/uibinder/elementparsers/UIObjectParser.java Mon Jun 7 12:20:31 2010 +++ /trunk/user/src/com/google/gwt/uibinder/elementparsers/UIObjectParser.java Thu Jul 15 04:01:13 2010
@@ -17,38 +17,42 @@

 import com.google.gwt.core.ext.UnableToCompleteException;
 import com.google.gwt.core.ext.typeinfo.JClassType;
+import com.google.gwt.uibinder.rebind.DesignTimeUtils;
 import com.google.gwt.uibinder.rebind.UiBinderWriter;
 import com.google.gwt.uibinder.rebind.XMLElement;

 /**
- * Parser of all UIObject types. Provides parsing of debugId,
- * addStyleNames, addStyleDependentNames. Also handles
- * other setStyle* calls to ensure they happen before the addStyle*
- * calls.
+ * Parser of all UIObject types. Provides parsing of debugId, addStyleNames, + * addStyleDependentNames. Also handles other setStyle* calls to ensure they
+ * happen before the addStyle* calls.
  */
 public class UIObjectParser implements ElementParser {

   public void parse(XMLElement elem, String fieldName, JClassType type,
       UiBinderWriter writer) throws UnableToCompleteException {

+    DesignTimeUtils.handleUIObject(writer, elem, fieldName);
+
     String debugId = elem.consumeStringAttribute("debugId", null);
     if (null != debugId) {
       writer.addStatement("%s.ensureDebugId(%s);", fieldName, debugId);
     }
-
+
     String styleName = elem.consumeStringAttribute("styleName", null);
- String stylePrimaryName = elem.consumeStringAttribute("stylePrimaryName", null); + String stylePrimaryName = elem.consumeStringAttribute("stylePrimaryName",
+        null);

     if (null != styleName && null != stylePrimaryName) {
       writer.die(elem, "Cannot set both \"styleName\" "
           + "and \"stylePrimaryName\"");
     }
-
+
     if (null != styleName) {
       writer.addStatement("%s.setStyleName(%s);", fieldName, styleName);
     }
     if (null != stylePrimaryName) {
- writer.addStatement("%s.setStylePrimaryName(%s);", fieldName, stylePrimaryName);
+      writer.addStatement("%s.setStylePrimaryName(%s);", fieldName,
+          stylePrimaryName);
     }

String[] extraStyleNames = elem.consumeStringArrayAttribute("addStyleNames");
=======================================
--- /trunk/user/src/com/google/gwt/uibinder/rebind/UiBinderGenerator.java Mon Jun 14 13:37:36 2010 +++ /trunk/user/src/com/google/gwt/uibinder/rebind/UiBinderGenerator.java Thu Jul 15 04:01:13 2010
@@ -99,6 +99,8 @@
     }

     String implName = interfaceType.getName().replace('.', '_') + "Impl";
+    implName = DesignTimeUtils.getImplName(implName);
+
     String packageName = interfaceType.getPackage().getName();
     PrintWriterManager writers = new PrintWriterManager(genCtx, logger,
         packageName);
@@ -126,6 +128,7 @@
         messages);

     Document doc = getW3cDoc(logger, resourceOracle, templatePath);
+    DesignTimeUtils.rememberPathForElements(doc);

     uiBinderWriter.parseDocument(doc, binderPrintWriter);

@@ -144,19 +147,22 @@
       throws UnableToCompleteException {

     Resource resource = resourceOracle.getResourceMap().get(templatePath);
-
     if (null == resource) {
       logger.die("Unable to find resource: " + templatePath);
     }

     Document doc = null;
     try {
-      String content = Util.readStreamAsString(resource.openContents());
- doc = new W3cDomHelper(logger.getTreeLogger(), resourceOracle).documentFor(content,
-          resource.getPath());
+      String content = DesignTimeUtils.getTemplateContent(templatePath);
+      if (content == null) {
+        content = Util.readStreamAsString(resource.openContents());
+      }
+ doc = new W3cDomHelper(logger.getTreeLogger(), resourceOracle).documentFor(
+          content, resource.getPath());
     } catch (SAXParseException e) {
-      logger.die("Error parsing XML (line " + e.getLineNumber() + "): "
-          + e.getMessage(), e);
+      logger.die(
+          "Error parsing XML (line " + e.getLineNumber() + "): "
+              + e.getMessage(), e);
     }
     return doc;
   }
=======================================
--- /trunk/user/src/com/google/gwt/uibinder/rebind/UiBinderWriter.java Fri Jul 2 08:22:57 2010 +++ /trunk/user/src/com/google/gwt/uibinder/rebind/UiBinderWriter.java Thu Jul 15 04:01:13 2010
@@ -58,7 +58,7 @@
  * TODO(rjrjr): Line numbers in error messages.
  */
 @SuppressWarnings("deprecation")
-public class UiBinderWriter {
+public class UiBinderWriter implements Statements {
   private static final String PACKAGE_URI_SCHEME = "urn:import:";

   // TODO(rjrjr) Another place that we need a general anonymous field
@@ -1180,5 +1180,6 @@
   private void writeStatics(IndentedWriter w) {
     writeStaticMessagesInstance(w);
     writeStaticBundleInstances(w);
+    DesignTimeUtils.addDeclarations(w);
   }
 }
=======================================
--- /trunk/user/src/com/google/gwt/uibinder/rebind/XMLElement.java Mon Jun 7 12:20:31 2010 +++ /trunk/user/src/com/google/gwt/uibinder/rebind/XMLElement.java Thu Jul 15 04:01:13 2010
@@ -115,7 +115,7 @@

   private static final Set<String> NO_END_TAG = new HashSet<String>();

-  private static final String[] EMPTY = new String[] {};
+  private static final String[] EMPTY = new String[]{};

   private static void clearChildren(Element elem) {
     // TODO(rjrjr) I'm nearly positive that anywhere this is called
@@ -257,7 +257,7 @@
    */
public String consumeAttributeWithDefault(String name, String defaultValue,
       JType type) throws UnableToCompleteException {
- return consumeAttributeWithDefault(name, defaultValue, new JType[] {type}); + return consumeAttributeWithDefault(name, defaultValue, new JType[]{type});
   }

   /**
@@ -494,7 +494,7 @@
    */
   public String consumeLengthAttribute(String name)
       throws UnableToCompleteException {
-    return consumeAttributeWithDefault(name, null, new JType[] {
+    return consumeAttributeWithDefault(name, null, new JType[]{
         getDoubleType(), getUnitType()});
   }

@@ -753,6 +753,14 @@
     }
     return String.format("</%s>", elem.getTagName());
   }
+
+  /**
+ * @return the design time path of this element, in form of indexes from root,
+   *         such as "0/0/1/0".
+   */
+  public String getDesignTimePath() {
+    return DesignTimeUtils.getPath(elem);
+  }

   /**
    * Gets this element's local name (sans namespace prefix).
=======================================
--- /trunk/user/test/com/google/gwt/uibinder/UiBinderJreSuite.java Fri Jul 2 04:56:18 2010 +++ /trunk/user/test/com/google/gwt/uibinder/UiBinderJreSuite.java Thu Jul 15 04:01:13 2010
@@ -34,6 +34,7 @@
 import com.google.gwt.uibinder.elementparsers.StackLayoutPanelParserTest;
 import com.google.gwt.uibinder.elementparsers.TabLayoutPanelParserTest;
 import com.google.gwt.uibinder.elementparsers.UIObjectParserTest;
+import com.google.gwt.uibinder.rebind.DesignTimeUtilsTest;
import com.google.gwt.uibinder.rebind.FieldWriterOfGeneratedCssResourceTest;
 import com.google.gwt.uibinder.rebind.GwtResourceEntityResolverTest;
 import com.google.gwt.uibinder.rebind.HandlerEvaluatorTest;
@@ -59,6 +60,7 @@
     suite.addTestSuite(HandlerEvaluatorTest.class);
     suite.addTestSuite(TokenatorTest.class);
     suite.addTestSuite(XMLElementTest.class);
+    suite.addTestSuite(DesignTimeUtilsTest.class);

     // model
     suite.addTestSuite(OwnerClassTest.class);

--
http://groups.google.com/group/Google-Web-Toolkit-Contributors

Reply via email to